一、主从复制
Redis主从的好处
- Redis主从可以解决主节点读的压力,主库进行写,由从库进行读取。主从架构需要人为的进行故障转移
- 从库通过配置replicaof(5.0之前使用slaveof) 实现主从复制
Redis主从复制流程
- 建立连接:从节点连接主节点(TCP三次握手),发送PING命令,收到PONG的回复后说明连接正常
- 身份验证:主节点和从节点都没有设置密码验证或者主节点和从节点密码相同验证通过。身份验证后从节点会发送给主节点自己的端口、IP等信息
- 数据同步:从节点发送数据同步命令PSYNC,数据同步分为完整重同步和部分重同步
- 命令传播:当从节点同步完成,主节点会把后续执行的命令发送给从节点。从节点执行这些命令来达到和主节点数据一致
Redis数据同步
- 完整重同步:主节点会fork出一个子进程进行RDB,主进程采用写时复制。子进程将RDB保存到自己磁盘后(也可以通过RDB文件流形式发送),发送给子节点,子节点回放RDB文件进行同步,同时主节点将aof缓存区的命令发送给子节点。
- 部分重同步:部分重同步主节点会判断子节点发送的runid是否和自身相同,同步判断复制偏移量是否在复制积压缓存区,都满足则进行部分重同步,否则进行完整重同步
Redis各个版本同步指令
- 2.8之前使用SYNC命令进行完全冲同步,断线重连也需要完全重同步。
- 2.8~4.0使用PSYNC支持完全重同步和部分重同步,但是重启连和故障转移导致runid不同而进行完全重同步。
- 4.0之后引入PSYNC2,关闭服务前会记录runid和复制偏移量,同时使用两组replid,子节点也开启复制积压缓冲区。解决了重启和故障转移导致的完全重同步。
二、哨兵模式
什么是哨兵
- 哨兵是Redis集群高可用的解决方案,由一个或者多个Sentinel实例组成的系统,会监控Redis主节点,以及主节点下的从节点。当主节点发生故障时,哨兵会在从节点选举一个作为新的主节点,进行故障转移,由新的主节点继续处理命令。
- 哨兵模式很好的解决了主从复制无法故障转移的缺点。但但redis数据量大时无法进行横向扩容。
- 实际开发中通过连接Sentinel来进行redis的操作以及读写分离
哨兵如何判断主节点下线
- 主观下线:Sentinel会每一秒钟发送PING命令给主节点,如果在一定时间内,返回无需回复,则判断该主节点掉线,进入主观下线状态
- 客户下线:主节点判断为主观下线后,Sentinel会向其他监视该节点的Sentinel发起询问该节点是否下线,如果其他Sentinel返回下线的计算合超过配置的数量,则判断该节点客户下线,会进行故障转移
哨兵如何进行故障转移
- 当Sentinel判断主节点客户下线后,会向其他Sentinel拉起投票,选举自己为领头的Sentinel。
- 选取领头Sentinel后,Sentinel会从剩余的从节点中选择优质的节点使其成为主节点,将其他所有的从节点改为复制该新主节点,旧的主节点上线后最为从节点
Sentinel选举
Sentinel选举采用Raft算法
- 每个节点都有机会成为领导者,当他们发现主节点客观下线时会,向其他Sentinel发送 Sentinel is-master-down-by-addr命令来让其投票给自己
- 其他Sentinel如果没有投票给其他的Sentinel,则投票,否则拒绝
- 当Sentinel的投票大于半数,且大于quornum时则选举为领导者,否则进入下次选举
Sentinel定时任务
- 每10s向监控的主节点和从节点发送Info消息,用于获取主节点和从节点的信息以及更新节点的拓扑关系
- 每2s向其他Sentinel发送_sentinel_:hello消息,用于发现新的Sentinel和获取节点客户下线以及选择的依据
- 每1s向主节点、从节点以及其他Sentinel发送ping命令,用于判断节点是否主观下线。
三、集群模式
- 集群模式很好的解决了redis数据量大时哨兵模式无法进行横向扩容的缺点
redis集群模式的特点
- 集群分为16384个槽,每个节点负责一部分槽
- 对key进行CRC16算法处理,然后对16384取模来决定所属的槽位
- 分片采用一主多从,支持读写分离和故障转移
- 去中心化,客户端直连redis节点,不需要连接所有节点,连接一个可用节点即可
- 所有节点互相连通,使用ping-pong命令进行心跳检测
操作key不在连接的redis节点上
- 当操作的key不在连接的redis节点上负责的槽位上,redis节点会快速返回moved错误,使得再次定位到key所属槽为redis节点进行操作。下次再请求会直接定位到相应的节点。
- 当redis增加节点时,槽位进行迁移,某部分key已经被移到新的节点上,那么请求时会先在老的节点判断是否存在,不存在则返回ask错误,到新的节点进行请求
redis集群选举
- redis集群选举和哨兵一样采用Raft算法,当从节点发现主节点客观下线后,发送命令让其他节点投票给自己,只有主节点可以进行投票