1. Redis的使用场景
- 热点数据的缓存
热点数据:频繁读取的数据
限时任务的操作。比如短信验证码
完成session共享的问题。因为前后端分离
完成分布式锁
商品的销售量
2. Redis的持久化方式
2.1 什么是持久化
把内存中的数据存储到磁盘的过程。同时也可以把磁盘中的数据加载到内存中。
2.2 实现持久化的方式
Redis实现持久化的方式提供了两种:
- RDB[Redis Database]:快照模式
- AOF[append only file]:日志追加模式
2.2.1 RDB快照模式
2.2.1.1 什么是RDB
RDB快照模式:每隔一段时间对内存中的数据进行快照存储。默认启用该模式
2.2.1.2 什么时候会触发RDB模式
RDB快照模式的触发方式有两种:
- 手动触发:通过save或bgsave【redis中唯一的多线程】命令
- 自动触发:通过修改配置文件
-
手动触发:save或bgsave手动触发RDB。保存的文件名称:dump.rdb
- save命令: 接收到
save
命令的redis服务在快照创建完毕之前将不再响应其他的命令。
save:该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。
具体流程:
执行完成时,如果存在老的RDB文件,就把新的替换掉旧的。我们的客户端可能都是几万或者是几十万,这种方式不可取
-
bgsave命令:BGSAVE 命令执行之后立即返回 OK ,然后 Redis fork 出一个新子进程,原来的 Redis 进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出。
执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求
具体流程:
bgsave在执行该命令时会fork出一个新的线程,单独执行rdb持久化操作,而不影响其他客户对redis服务的操作。【唯一的多线程】
虽然 BGSAVE 子进程写入 RDB 的工作不会阻塞主线程,但是会对机器的 CPU资源和内存资源造成影响,严重的情况下甚至会导致服务器宕机。
- save命令: 接收到
-
自动触发:通过配置文件搞定
需要修改配置文件
2.2.2 AOF日志追加模式
2.2.2.1 什么是AOF日志追加模式
AOF:append only file 日志追加模式【每执行一次写操作就要追加一次】,默认redis没有开启该模式,手动开启。默认的文件名:appendonly.aof
写操作:增删改
读操作:查
2.2.2.2 开启AOF
把配置文件中的appendonly yes即可
当启动redis服务器,会把日志文件中的命令从上到下执行以下
2.2.3 RDB和AOF的区别
- RDB快照模式,数据备份和回复速度快。缺点:数据完整性差。数据可能丢失多
- AOF日志追加模式,数据完整性高。缺点:数据备份和恢复速度慢
若RDB和AOF同时开启,先执行AOF
3. Redis的集群模式
集群:将一个项目部署到多个服务器上,分摊压力
redis提供了三种集群模式
- 主从模式。版本3以下
- 哨兵模式。版本5以下
- 去中心化模式
3.1 为什么使用redis集群
提高并发量,提高可用性
3.2 主从模式
redis主从模式表示一个主节点和若干个从节点。
主节点:负责读、写操作
从节点:只负责读操作
主节点的数据会自动同步到所有的从节点上【冗余换高效】
如何搭建redis主从模式
我们为了操作方便,在一台linux三跑三个redis服务器。只要端口不同即可
修改配置文件
1.端口号 2.dump文件的名称 3.aof的名称
开启三台Redsi服务器
reids-server redisXXX.conf
配置主从关系
配从不配主原则
slaveof 主节点IP 主节点port
查看主从的状态
info replication
思考
如果某台slave宕机,如果恢复后,是否具有master新增的数据?
若子节点杀死重启,状态会为master,需重新更改为slave。但会保存死之前的数据,不会更新死之后master新增的数据
master宕机后,slave会不会自动选举成为主节点?
若主节点杀死,从节点仍可读,主节点重启,从节点中主节点状态变为up。不会推荐新的主节点,需要手动恢复主节点
发现主从模式的缺点:不会自动选举master节点。导致一旦主节点宕机,无法进行写操作
3.3 哨兵模式
为了解决主从模式的缺陷:当主节点宕机后,从节点无法直接上位
Sentinel(哨兵)进程的作用:
- 监控redis集群中Master主服务器工作的状态
- 在Master主服务器发生故障时,可以实现Master和Slave服务器的切换,保证系统的高可用(HA)
3.3.1 监控功能
- 每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。
- 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值,则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)。
- 如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态。
- 当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)。
- 在一般情况下, 每个Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令。
- 当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
- 若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。
搭建sentinel服务时,尽量搭建奇数个
3.3.2 选举机制
- 筛选条件
不仅仅要判断从库当前的状态,还要判断他之前的网络连接状态。如果之前从库跟主库断联次数超过了阈值,那么有理由确认这个从库的网络连接状态不是很好,可以把它筛选掉。虽然现在他在运行,但是万一过一会断掉了,就需要重新选主,所以需要判断她之前的状态。
具体怎么判断呢?
使用配置项down-after-milliseconds*10。其中,down-after-milliseconds是我们认定是从库断联的最大时间。如果在down-after-milliseconds毫秒内,主从节点都没有网络连接上,那么就认为从库断联了。如果断联时间超过了10次就认为,这个从库的网络转态不是很好,不适合做主库。
- 打分规则
可以分别按照三个规则进行打分:从库优先级、从库复制进度、以及从库ID号
只需要在某一轮得分最高,那么他就是新主库,选主过程到此结束,要是没有出现得分最高的,那么就进行下一轮。
第一轮:优先级slave-priority最高的从库得分高
用户可以通过slave-priority配置项,给不同的从库设置不同优先级。比如,你有两个从库,它们的内存大小不一样,你可以手动给内存大的实例设置一个高优先级。在选主时,哨兵会给优先级高的从库打高分,如果有一个从库优先级最高,那么它就是新主库了。如果从库的优先级都一样,那么哨兵开始第二轮打分。
第二轮:和旧主库同步程度最接近的从库得分高
如果选择和旧主库同步最接近的从库作为主库,新主库上边就会有最新的数据。
如何判断从库和主库的同步进度呢?(复制进度)
主从库同步的时有个命令传播的过程,在这个过程中,主库会用master-repl-offset记录,当前的最新写操作在repl-backlog-buffer的中位置,而从库会用slave-repl-offset记录复制的进度。
所以我们需要找到master-repl-offset,slave-repl-offset最接近的从库。得分就高,就会被选为新主库。如果slave-repl-offset相同,就会进行下一轮的打分。
旧主库的master_repl_offset是1000,从库1、2和3的slave_repl_offset分别是950、990和900,那么,从库2就应该被选为新主库。
第三轮:ID号小的从库得分高
每个实例都会有一个id,这个ID类似于从库的编号。Redis选主时,有一个规定:在优先级和复制进度相同的情况下,ID越小的得分越高。
- 主从切换总结
首先哨兵机制会根据在线状态,网络状态,过滤筛选掉一部分不符合要求的从库。然后按照优先级,复制进度,ID大小对从库进行打分,得分最高的选为新主库。
3.3.3 准备条件
1. 修改sentinel.conf
2. 启动哨兵服务
redis-sentinel sentinel.conf
3.4 去中心化
- redis集群中总共16384个槽,平均分配到主节点上
- 当存入一个key时,会计算key的crc16的整数值。该值对16384求余,确定该key存放在哪个槽中
- 主从之间自动同步,主从之间存在哨兵
redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个整数结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。当你往Redis Cluster中加入一个Key时,会根据crc16(key) mod 16384计算这个key应该分布到哪个hash slot中,一个hash slot中会有很多key和value。你可以理解成表的分区,使用单节点时的redis时只有一个表,所有的key都放在这个表里;改用Redis Cluster以后会自动为你生成16384个分区表,你insert数据时会根据上面的简单算法来决定你的key应该存在哪个分区,每个分区里有很多key。
准备三主三从
1. 修改端口
2. dump文件名
3. aof文件名
4. aof目录名
5. 开启集群模式cluster-enabled yes
6. cluster-config-file nodes-7001.conf
启动redis
启动所有配置文件,并查看进程状况。
redis-server redisduanXXX.conf
分配槽以及主从关系
分槽,以及设置主从关系。 副本
redis-cli --cluster create --cluster-replicas 1 192.168.111.188:7001 192.168.111.188:7002 192.168.111.188:7003 192.168.111.188:7004 192.168.111.188:7005 192.168.111.188:7006
命令行的客户端
redis-cli -c -h 192.168.111.188 -p 7006
可随意属于一个已开启的端口号,输入key之后,会根据计算的槽的位置自动跳转到对应的端口