**redis数据库基础**
1、redis简介
2、redis数据操作
3、redis持久化
4、redis其他知识
**redis简介**
**1.1、简介**
Redis是C语言开发的一个开源高性能键值对的内存数据库,可以用来做数据库、缓存、消息中间件等场景,是一种NoSQL(not-only sql,非关系型数据库)的数据库。
**1.2、特点**
* 优秀的性能,数据是存储在内存中,读写速度非常快,可支持并发10W QPS
* 单线程单进程,
使用非阻塞I/O,
多路复用I/O模型
* 可作为分布式锁
* 支持五种数据类型
* 支持数据持久化到磁盘
* 可以作为消息中间件使用,支持消息发布及订阅
* 默认端口6379,16个数据库,默认0库开始
* **1.3、服务端和客户端**
**服务端:**
* 服务器端的命令为redis-server
可以使用help查看帮助文档
~~~
redis-server --help
~~~
* 推荐使用服务的方式管理redis服务
启动
~~~
sudo service redis start
~~~
停止
~~~
sudo service redis stop
~~~
重启
~~~
sudo service redis restart
~~~
**客户端:**
* 客户端的命令为redis-cli
可以使用help查看帮助文档
~~~
redis-cli --help
~~~
运行测试命令
~~~
ping
~~~
切换数据库(数据库没有名称,默认有16个,通过0-15来标识)
~~~
select 1
~~~
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt57yEhJUaico4pHJDicfGlRxFbnwzbklVI3hL7j3DYnaVYrIROiaibMLzNIazwUTnL0UaTBrkO8yjjU91g/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
**redis数据操作**
PART 02
redis是key-value的数据结构,每条数据都是一个键值对,键的类型是字符串(键不能重复),值的类型分为五种:
* 字符串string
* 哈希hash
* 列表list
* 集合set
* 有序集合zset
**2.1、字符串string**
* string是redis最基本的类型
* 最大能存储512MB数据
* string类型是二进制安全的,可以存储任何数据,比如数字、图片等
**增加、修改**
~~~
# 如果设置的键不存在则为添加,如果设置的键已经存在则修改
~~~
**获取**
~~~
根据键获取值,如果不存在此键则返回nil
~~~
**键命令(查找、删除)**
~~~
查找键,参数通配符查找
~~~
**2.2、哈希hash**
* hash用于存储对象,对象的结构为属性、值
* 值的类型为string
**增加、修改**
~~~
设置单个属性
~~~
**获取**
~~~
获取指定键所有的属性
~~~
**删除**
~~~
删除整个hash键及值,使用del命令
~~~
**2.3、列表list**
* 列表的元素类型为string
* 按照插入顺序排序
**增加**
~~~
在左侧插入数据
~~~
**修改
**
~~~
设置指定索引位置的元素值
~~~
**获取**
~~~
返回列表里指定范围内的元素
~~~
**删除**
~~~
删除指定元素
~~~
**2.4、集合set**
* 无序集合
* 元素为string类型
* 元素具有唯一性,不重复
* 对于集合没有修改操作
**增加**
~~~
#添加元素
~~~
**获取**
~~~
返回所有的元素
~~~
**删除**
~~~
删除指定元素
~~~
**2.5、有序集合zset**
* sorted set,有序集合
* 元素为string类型
* 元素具有唯一性,不重复
* 每个元素都会关联一个double类型的score,表示权重,通过权重将元素从小到大排序
* 没有修改操作
**增加**
~~~
添加
~~~
**获取**
~~~
返回指定范围内的元素
~~~
**删除**
~~~
删除指定元素
~~~
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt57yEhJUaico4pHJDicfGlRxFbnwzbklVI3hL7j3DYnaVYrIROiaibMLzNIazwUTnL0UaTBrkO8yjjU91g/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
**redis持久化**
PART 03
**3.1、redis持久化方式**
redis是一个内存数据库,一旦断电或服务器进程退出,内存数据库中的数据将全部丢失,所以需要redis持久化。
redis持久化就是把数据保存在磁盘上,利用永久性存储介质将数据保存,在特定的时间将保存的数据进行恢复的工作机制。
redis提供两种持久化机制:
* RDB:存储数据结果,关注点在数据
* AOF:存储操作过程,关注点在数据的操作过
程
**3.2、RDB**
* 原理:将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化,直接把内存中的数据保存到一个 dump 的文件中。
* 开启RDB持久化方式:
客户端可以通过向Redis服务器发送save或bgsave命令让服务器生成rdb文件,或者通过服务器配置文件指定触发RDB条件。
~~~
# 同步数据到磁盘上命令
~~~
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt55tsX8Hvj2TZLxFmUInKUcjzmjV6icc4ria2R2Lfp5Z27Slal3eEQylvUOhWCtI3FYS68hGlTJ0gCmQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
由于redis的单进程单线程特性,当客户端向服务器发送save命令请求进行持久化时,服务器会阻塞save命令之后的其他客户端的请求,直到数据同步完成。如果数据量太大,同步数据会执行很久,而这期间redis服务器也无法接收其他请求,所以,最好不要在生产环境使用save命令。
~~~
# 异步保存数据集到磁盘上
~~~
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt55tsX8Hvj2TZLxFmUInKUcjQfVwGs5nEtcia6eeb2K2SHcR5ZnwQPQKViahsk1o8fM2NDOcb2JJ6kKg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
当客户端发服务发出bgsave命令时,redis服务器主进程会forks一个子进程来数据同步问题,在将数据保存到rdb文件之后,子进程会退出。所以,与save命令相比,redis服务器在处理bgsave采用子线程进行IO写入,而主进程仍然可以接收其他请求,但forks子进程是同步的,所以forks子进程时,一样不能接收其他请求,这意味着,如果forks子进程花费的时间太久(一般是很快的),bgsave命令仍然有阻塞其他客户的请求的情况发生。
~~~
# 服务器配置自动触发
~~~
这种通过服务器配置文件触发RDB的方式,与bgsave命令类似,达到触发条件时,会forks一个子进程进行数据同步,不过最好不要通过这种方式来触发RDB持久化,因为设置触发的时间太短,则容易频繁写入rdb文件,影响服务器性能,时间设置太长则会造成数据丢失。
* RDB文件:
执行同步数据到磁盘操作后,生成临时rdb文件,并写入数据;完成数据写入,用临时文代替代正式rdb文件,删除原来的rdb文件。RDB默认生成的文件名为dump.rdb(可通过配置文件修改RDB默认文件名)。
**3.3、AOF**
* 原理:将Reids的操作日志以追加的方式写入文件,把所有的对 Redis的服务器进行修改的命令都存到一个文件里,保存的是命令的集合。
* 开启AOF持久化方式:
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt55tsX8Hvj2TZLxFmUInKUcjN5d26tgFDVMqTicXbfWeiclibY8M84icSBiaesAkRIPZK8tNVsnZl6doia9Q/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
与RDB存储某个时刻的快照不同,AOF持久化方式会记录客户端对服务器的每一次写操作命令,并将这些写操作以Redis命令追加保存到以后缀为aof文件的末尾,在Redis
服务器重启时,会加载并运行aof文件的命令,以达到恢复数据的目的。
Redis默认不开启AOF持久化方式,需要在配置文件中开启并进行更加详细的配置,如下面的redis.conf文件:
~~~
# 开启aof机制
~~~
* 三种写入策略:
1. always
:
客户端的每一个写操作都保存到aof文件,这种策略很安全,但是每个写请注都有IO操作,所以也很慢。
2. everysec
:
appendfsync的默认写入策略,每秒写入一次aof文件,因此,最多可能会丢失1s的数据。
3. no:Redis服务器不负责写入aof,而是交由操作系统来处理什么时候写入aof文件。更快,但也是最不安全的选择,不推荐使用。
**3.4、两者区别&优劣势**
区别:
* RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
* AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
优劣势:
* 如果非常关心你的数据,但仍然可以承受数分钟内的数据丢失,那么可以额只使用 RDB持久化。
* AOF将Redis 执行的每一条命令追加到磁盘中,处理巨大的写入会降低Redis的
性能。
* 数据库备份和灾难恢复:定时生成 RDB 快照非常便于进行数据库备份,并且 R
DB恢复数据集的速度也要比 AOF 恢复的速度快。
(Redis 支持同时开启 RDB 和 AOF,系统重启后,Redis 会优先使用 AOF 来恢复数据,这样丢失的数据会最少。)
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt57yEhJUaico4pHJDicfGlRxFbnwzbklVI3hL7j3DYnaVYrIROiaibMLzNIazwUTnL0UaTBrkO8yjjU91g/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
**redis其他知识**
PART 04
**4.1、主从模式**
* 原理:
将一台redis服务器的数据,复制到其他的redis服务器,前者称为主节点(master/leader,主节点不用配置,redis默认单机就是主节点),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。master以写为主,slave以读为主。主从复制,读写分离。
* 作用:
数据冗余(实现数据的热备份)、故障恢复、负载均衡(读写分离等操作,可以减缓服务器压力,架构中经常使用)、高可用基石(它是哨兵与集群能够实施的基础)、集群模式的最低配置应该是一主二从,三台服务器。
* 主从复制步骤
当slave启动成功连接到master后会发送一个sync同步命令,master接到命令,启动后台的存盘进程,同时收集所有用于修改数据集命令,在后台进程执行完毕后,master将传送整个数据文件(RDB文件)到slave,并且完成一次完全同步(全量复制);只要是重新连接master,全量复制将会被自动执行,数据一定可以在从机中看到。
全量复制 —— slave服务在接收到数据库文件数据后,将其存盘并加载到内存中;
增量复制 —— master继续将新的所有收集到的修改命令依次传给slave,完成同步;
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt55tsX8Hvj2TZLxFmUInKUcjXWWF5wDuRsp2hNQvialvwYZZicHAibxn9yFf15mia08BDVRH419ZZtOgJQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
~~~
# 主从复制只需要在从机中配置,命令如下:
~~~
**4.2、哨兵模式**
* 原理:
哨兵模式就是自动选取主机的方法,哨兵模式是一种特殊的模式,redis提供了哨兵的命令,它是一个独立的进程,原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个redis实例。
* 哨兵模式的由来:
主从复制会存在如下问题:一旦主节点宕机,从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预。
* 哨兵模式的作用:
1. 通过发送命令,令redis服务器返回运行状态,包括主服务器与从服务器;
2. 当哨兵检测到master宕机,会自动将slave切换到master,然后通过发布订阅模式通知其他从服务器,修改配置文件,切换主机。
* 哨兵的架构模式如下:
![图片](https://mmbiz.qpic.cn/mmbiz_jpg/EuxggHvdt55tsX8Hvj2TZLxFmUInKUcjbyuDY8YLN2ibMz5KiaVw5D7iaG1LLTOqkibQEh8vvGUnwgQQPb3Tp9Mefg/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1)
可以执行以下四个任务:
* 监控:不断检查主服务器和从服务器是否正常运行。
* 通知:当被监控的某个 Redis 服务器出现问题,Sentinel 通过 API 脚本向管理员或者其他应用程序发出通知。
* 自动故障转移:当主节点不能正常工作时,Sentinel 会开始一次自动的故障转移操作,它会将与失效主节点是主从关系的其中一个从节点升级为新的主节点,并且将其他的从节点指向新的主节点,这样人工干预就可以免了。
* 配置提供者:在 Redis Sentinel 模式下,客户端应用在初始化时连接的是 Sentinel 节点集合,从中获取主节点的信息。
**4.3、集群模式**
* 原理:
哨兵模式虽然基本已经可以实现高可用、读写分离;但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的内容。
* 集群的配置:
集群部署至少需要3台以上的master节点,最好使用3主3从6个节点的模式;这里的 6 台 redis 两两之间并不是独立的,每个节点都会通过集群总线(cluster bus),与其他的节点进行通信。所有的redis节点彼此互联,内部使用二进制协议优化传输速度和带宽;节点的 fail 是通过集群中超过半数的节点检测失效时才生效;客户端与 Redis 节点直连,不需要中间代理层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt55yicuye5Sk83UZtJQPvzwLrvrMnV60V9FcYncnwibouwNTdsdcE8BUmqm1q28DtAHMVOWicDlic7BQibg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
* 工作方式:
在 Redis 的每一个节点上,都有两个东西,一个是插槽(slot),它的取值范围是:0-16384。还有一个就是cluster,可以理解为是一个集群管理的插件。当我们的存取的 Key到达的时候,Redis 会根据crc16的算法得出一个结果,然后把结果对16384求余数,这样每个 key 都会对应一个编号在0-16384 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
**4.4、reids的雪崩&穿透&击穿**
**缓存雪崩**
* 定义:
redis缓存中大量的key同时失效,此时又刚好有大量的请求打进来,直接打到数据库层,造成数据库阻塞甚至宕机。
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt55yicuye5Sk83UZtJQPvzwLrVfZTIiaPb2trvfu34JCFiczLNz5VGuCyIdwdXQ6jRP9libqZJczd24jKA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
* 解决办法:
1. 让redis数据永不过期,这种方式最可靠的,最安全的但是占空间,内存消耗大,并且不能保持数据最新,所以需要根据具体的业务逻辑来做
2. 将缓存失效时间分散开,比如每个key的过期时间都是随机的,防止同一时间大量数据过期的现象发生,就不会出现同一时间全部请求都落在数据库。
3. 因为redis宕机导致缓存雪崩的问题,可以启动服务熔断机制,暂停业务应用对缓存服务的访问,直接返回错误,但是暂停了业务应用访问缓存系统,全部业务都无法正常的工作
4. 创造redis集群,对数据库进行读写分离
**缓存穿透**
* 定义:
指查询一个缓存和数据库都不存在的数据,导致尽管数据不存在但是每次都会到数据库查询。在访问量大时可能DB就会挂掉。如果有人利用不存在的key频繁攻击,则这就形成了漏洞。
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt55yicuye5Sk83UZtJQPvzwLrhXP2zS4iaOiciaF1vVI8zcHZyuE1W7KsjX643MqutRibFvrTfx1aC9w38g/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
* 解决办法:
1. 如果一个查询返回的数据为空,我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
2. 接口层增加校验,用户鉴权,id做基础校验。
3. 采用布隆过滤器,将所有可能存在的数据hash到一个足够大的bitmap中。
布隆过滤器:类似于HashSet,可以快速判断一个元素在集合中是否存在,应用场景:快速判断一个元素是否在某容器内,不存在直接返回。(关键点在于hash算法和容器大小。)
**缓存击穿**
* 定义:
击穿与雪崩的不同在于缓存key失效的量级上。击穿是对于单个key值(热点数据)的缓存失效过期,雪崩则是大面积key同时失效。
![图片](https://mmbiz.qpic.cn/mmbiz_png/EuxggHvdt55yicuye5Sk83UZtJQPvzwLr8Tu8Tsj3nYN4bfoONVUCIFMu1yXUn6X8VLnzxPlkuAJYD4RiczeZDHA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
* 解决办法:
1. 若缓存数据基本不会发生更新,则可尝试将热点数据设置为永不过期。
2. 若缓存的数据更新不频繁,且缓存刷新的整个流程耗时较少的情况下,则可以采用基于Redis、zookeeper 等分布式中间件的分布式互斥锁,或者本地互斥锁以保证仅少量的请求能请求数据库并重新构建缓存,其余线程则在锁释放后能访问到新缓存。
3. 若缓存的数据更新频繁或者在缓存刷新的流程耗时较长的情况下,可以利用定时线程在缓存过期前主动地重新构建缓存或者延后缓存的过期时间,以保证所有的请求能一直访问到对应的缓存。
- 后端
- composer
- composer配置国内镜像
- composer安装及设置2
- PHP
- 贝塔SG11加密
- 申请KEY
- 开始加密
- php 中连接tcp服务的三种方式
- php websocket 教程
- editor内容转换数组
- 使用正则判断中文维吾尔文
- PHP常用函数总结
- 常用助手函数
- 通过Imagick把pdf转换图片
- 维吾尔语基本区转换扩展区
- php GD库生成一个由文字和图片生成新的图片
- aes加密
- php数组函数 -- array_column,array_multisort 实现二维数组排序
- PHP操作Excel
- php更新内容
- 辅助查询(*)
- 【时间】操作
- 时间函数例子
- Date/Time 函数(不包含别名函数)
- php网络相关
- HTTP请求的返回值含义说明
- 使用php语言开发一个类似数据库操作的文件表类
- pinyin
- 维吾尔语基本区转换扩展区(2)
- php获取当前环境的信息
- laravel
- laravel 队列的使用
- laravel 自定义助手函数
- laravel seeder的使用
- laravel项目从git下载命令
- laravel 多个数据库配置
- laravel 填充假数据
- laravel 动态路由
- laravel 自定义 validate 响应
- laravel 创建追加字段的模拟访问器
- laravel 线上环境的数据库更改或添加字段
- laravel 模型查询按照whereIn排序
- laravel 使用 workerman 通过TCP 文件传输功能
- laravel api Header添加Accept头
- Laraval IDE 自动补全插件 laravel-ide-helper
- laravel 网站后台
- laravel 设置路由
- laravel-第三方composer包
- laravel 开发技巧
- laravel 昨天,今天时间
- 使用宝塔计划任务启动laravel调度器
- laravel结合workerman第二节
- Laravel - 上传多个文件
- 查询聊天好友列表
- 事件系统 event, listener
- laravel 安装 laravel-modules
- 自定义求看守器-toekn
- laravel限流
- 使用 Laravel api Resource 类时自定义分页信息
- Laravel php artisan命令大全
- 验证器
- workerman 创建wss服务
- 架构师必须知道的26项PHP安全实践
- python
- Python读取文件代码块已经备好,用的时候光拿(建议收藏)
- Python常用库大全
- api 签名验证
- git
- git命令
- 十分钟学会git基础
- Git代码同时上传到GitHub和Gitee(码云)
- Git - 多人协同开发利器,团队协作流程规范与注意事项
- 删除远程仓库的文件
- github查询方法
- 错误
- 解除项目git版本控制
- linux
- sentos安装supervisor
- PHP怎么守护进程运行php脚本
- 600条最强Linux命令总结
- centos开启防火墙、开放指定端口
- 前端
- vue
- vue2发布之前的config简单配置
- vue2安装scss命令
- vue2父子组件之间双向数据绑定
- 国际化双语--安装VueI18n
- vue3-setup 组件传参(defineProps、defineEmits、defineExpose
- Vue3 新写法速览:十分钟内轻松get
- 关于vue的外连接
- watch讲解
- computed
- webpack 打包后生成很多小文件怎么优化?
- vue2 vue.config.js常见配置和打包部署测试
- 小程序
- 小程序长期订阅消息
- 小程序自定义TabBar后如何实现keep-alive
- 收藏的html和css和js
- CSS 省略号(单行省略号、多行省略号)
- UyghurInput_a.js
- font.css
- 漂亮按钮样式
- clock.html
- css
- scroll css样式
- CSS流动布局-页面自适应
- css grid布局
- 禁止wap页面调整字体大小
- CSS @media 和 min-width/max-width
- 网站变灰是怎么实现的
- 瀑布流实现方式
- javascript
- SortableJS拖动排序
- wondow scroll滚动到上边
- 原生js插入HTML元素
- Konva.js —— 像操作DOM一样操作canvas
- 通过canvas合并俩个图片
- js scroll更多加载
- js 实现复制功能
- js判断安卓和苹果或者微信
- 浏览器打开控制台禁止
- 原生js一些dom操作
- js http客户端集合
- fetch
- axios
- canvas 点钟
- layer dialog
- jquery 和 laravel ajax全局配置
- layui 获取select的自定义参数
- konva.js中文开发文档
- js 大文件分片上传
- js监听网络状态实现断网重连后自动刷新页面
- js生成video缩略图
- JS获取当前系统电量情况
- uniapp
- uni-app swiper数量过多时卡顿优化方案
- uniapp 帖子集合
- 微信wap
- wap分享朋友和朋友圈
- wap 手机页面微信支付
- JsSdk微信公众号支付
- 通用各种小知识
- 正则表达式
- JS正则匹配过滤字符串中的html标签及html标签内的内容
- 判断维吾尔文输入
- 正则表达式符号
- 正则表达式练习
- 百度网盘不限速下载助手
- 解决VSCode下载慢或下载失败的问题
- 性能测试 使用Apache的ab测试工具
- nginx从入门到精通
- nginx
- Nginx 是怎么禁止访问php的 ?
- 宝塔面板
- supervisor
- 卸载宝塔
- redis
- redis实用笔记
- redis入门到精通
- phpredis
- redis数据库基础
- PHP对Redis的基本操作
- ffmpeg
- 合并多个音视
- 获取音视时长
- FFmpeg视频处理入门教程(新手必看)
- 外连接
- 安装
- PHP基于ffmpeg实现转换视频,截图及生成缩略图的方法
- Linux安装ffmpeg
- docker
- 服务实现
- docker基本命令
- rewrite笔记
- 别人笔记链接
- 计算机常用知识
- 二进制1-10
- 斐波那契数列
- mysql
- 高性能高可用的MySQL,得从各种规范开始
- 读写分离配置
- 重要外连接,前端/ 后端/数据库等等
- 关于程序必须收藏的文章链接集合
- markdown
- 一篇文章讲清楚markdown