先放上一张总结的Redis主从集群、pub/sub通信、哨兵选主机制图,可以结合图阅读后面的文字
一、 主-从-从级联模式主从备份过程
主从库建立长连接 — 从库申请备份数据 — 主库fork子进程 — 子进程将RDB文件发送给从库(主库的主进程同时将更新的数据记入replication buffer(每个从库在主库中有一个与自己对应的replication buffer),同时主库无论何时都会将自己的更新操作记入一个叫repl_backlog_buffer(所有从库共享一个repl_backlog_buffer,只不过他们各自在上面的位置不同)的环形缓冲区) — 从库清空原有数据并读取RDB快照完成复制 — 主库发送replication buffer中的指令给从库 — 从库更新replication buffer中记录的操作
如下图所示(包括了以下第二点中同样参考该图)
二、 主从库断线重连机制(原理类似游戏的断线重连机制?)
主从库网络断开 — 主库保持读写,将数据继续记入repl_backlog_buffer — 主从重新建立连接 — 从库发送断开时自己同步的数据对应在repl_backlog_buffer中的位置,主库将从该位置到目前自己所在的位置的增量信息发送给从库,即增量备份(之后与正常情况一样,将后续数据操作再记入一份到replication_buffer中,从库备份时才有这个replication_buffer) — 从库拷贝数据 — 主库发送replication_buffer增量信息 — 从库更新增量信息
注:如果断开连接时间过长,环形缓冲区会覆盖数据,导致刚断开连接时的增量信息丢失,从库只能读取RDB文件再次进行全量备份。
三、 哨兵(特殊的redis进程)三个作用:监控、选主、通知
- 监控:主观下线(单个哨兵判断主库下线),客观下线(大部分哨兵判断主库下线)
- 选主的过程:从库在线 — 之前通信网络良好 — 优先级最高的从库 — 同步进度最快的从库 ---- ID号最小(哨兵集群会票选出一个哨兵leader来执行以上操作)
- 通知:将新的主库的连接信息发送给从库和客户端
四、 主库下线后怎么处理客户端信息
可读不可写,写操作会被缓存到消息队列,主库恢复后再将新的写操作指向新主库。
down-after-milliseconds参数:可用性与可靠性之间的trade-off
- 主库下线:哨兵ping主库,在down-after-milliseconds时间内没有收到主库回复就判断主观下线,down-after-milliseconds越小越有可能发生误判进行新主库选取(过程需要较长时间),客户端写请求会经常阻塞(低可用);down-after-milliseconds越大,主机真正宕机时难以发现(低可靠),但不会经常阻塞客户端请求,且真正发生主库宕机时,其新主库可用的时间会更长。
五、 主库与客户端断线重连机制(客户端与哨兵集群间可以通信)
- 哨兵主动通知客户端:将主库地址写入哨兵自己的pubsub中,平时客户端会订阅哨兵集群的这个pubsub,会收到里面的最新通知;
- 客户端主动向哨兵集群请求主库地址;
六、 Redis的pub/sub机制(Redis可以作为注册中心)
Redis的实例(主库、从库、哨兵)中有很多处理不同类型消息的消息订阅中心(频道),不同频道分别对各自之间的连接实例进行相关类型消息的通信。
- 哨兵—主库频道—哨兵(哨兵连接哨兵);
- 哨兵—主库频道—从库(哨兵连接从库);
- 客户端—哨兵频道—新主库(哨兵连接新主库)。
七、 leader哨兵竞选机制
每个哨兵都可以向集群申请自己成为leader,在申请前会先给自己投一票,之后再向其他哨兵拉票,任何一个哨兵在收到其他哨兵的拉票请求时,会先给第一个收到的请求投赞成票(前提是他自己没有竞选leader,因为如果自己竞选了,就会先给自己投一票),每个哨兵只有一票,所以后续收到的请求就不会再投了------也就是和其他哨兵之间网络传输最快的哨兵会成为leader,该哨获取的票数必须大于哨兵实例数量的一半,并且大于DBA设置的阈值才能成为leader。
ps:如果只有两个哨兵,那么想成为leader必须获取两票,如果某个哨兵挂了,就没有leader哨兵,就不会执行选主流程—因此一般至少配置三个哨兵。