1.基本概念
-
一旦多个实例组成了哨兵集群,即使有哨兵实例出现故障挂掉了,其他哨兵还能继续协作完成主从库切换的工作
- 包括判定主库是不是处于下线状态
- 选择新主库
- 通知从库和客户端
-
配置哨兵
-
设置主库的 IP 和端口,并没有配置其他哨兵的连接信息\
-
sentinel monitor
-
并不需要配置其他哨兵信息
-
2.基于 pub/sub 机制的哨兵集群组成
-
哨兵间相互发现,是通过Redis 提供的 pub/sub 机制,也就是发布 / 订阅机制
-
名为“sentinel:hello”的频道,不同哨兵就是通过它来相互发现,实现互相通信的\
-
哨兵只要和主库建立起了连接
- 在主库上发布消息了,比如说发布它自己的连接信息(IP 和端口)
- 可以从主库上订阅消息,获得其他哨兵发布的连接信息(前面的哨兵可以获取后面,后面的怎么获取前面的)->(前面的哨兵主动与后面的哨兵建立联系)->(成功建立了哨兵集群)\
-
为了区分不同的消息,Redis 会以频道的形式,对这些消息进行分门别类的管理(topic)
- 只有订阅了同一个频道的应用,才能通过发布的消息进行信息交换
-
当新的主库切换完成后,哨兵需要通知从库,哨兵是如何直到从库的IP地址和端口?\
- 哨兵向主库发送 INFO 命令来完成的
- 主库接受到这个命令后,就会把从库列表返回给哨兵(主库会管理所有从库 从库主动连接主库)\
-
哨兵还需要完成把新主库的信息告诉客户端这个任务\
3.基于 pub/sub 机制的客户端事件通知
-
怎么获取到哨兵集群在监控、选主、切换这个过程中发生的各种事件
-
哨兵就是一个运行在特定模式下的 Redis 实例,只不过它并不服务请求操作,只是完成监控、选主和通知的任务\
- 每个哨兵实例也提供 pub/sub 机制,客户端可以从哨兵订阅消息
- 哨兵提供的消息订阅频道有很多,不同频道包含了主从库切换过程中的不同关键事件\
-
客户端读取哨兵配置,获取哨兵地址和端口
-
客户端执行订阅命令,来获取不同的事件消息(监控实时状态)\
-
客户端执行订阅命令,来获取不同的事件消息
-
客观下线状态的事件 SUBSCRIBE +odown\
-
订阅所有的事件 PSUBSCRIBE *\
-
切换主库 switch-master
-
-
\
\
4.由哪个哨兵执行主从切换?
-
确定由哪个哨兵执行主从切换的过程
- 查一下是啥分布式算法
- 和主库“客观下线”的判断过程类似,也是一个“投票仲裁”的过程\
-
客观下线的判断流程
-
任何一个实例只要自身判断主库“主观下线”后,就会给其他实例发送 is-master-down-by-addr 命令\
-
其他实例会根据自己和主库的连接情况,做出 Y 或 N 的响应,Y 相当于赞成票,N 相当于反对票\
- 自己会给自己一张赞成票
-
一个哨兵获得了仲裁所需的赞成票数后,就可以标记主库为“客观下线”\
- 通过哨兵配置文件中的 quorum 配置项设定的\
-
Leader 选举 决定切换主从的哨兵节点\
-
这个哨兵就可以再给其他哨兵发送命令,表明希望由自己来执行主从切换,并让所有其他哨兵进行投票\
-
成为leader的条件
-
拿到半数以上的赞成票\
-
拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值
-
-
-
-
举个栗子(任何节点都有可能执行切换主库操作)
-
在 T1 时刻,S1 判断主库为“客观下线”,它想成为 Leader,就先给自己投一张赞成票,然后分别向 S2 和 S3 发送命令,表示要成为 Leader。\
-
在 T2 时刻,S3 判断主库为“客观下线”,它也想成为 Leader,所以也先给自己投一张赞成票,再分别向 S1 和 S2 发送命令,表示要成为 Leader。\
-
在 T3 时刻,S1 收到了 S3 的 Leader 投票请求。因为 S1 已经给自己投了一票 Y,所以它不能再给其他哨兵投赞成票了,所以 S1 回复 N 表示不同意。同时,S2 收到了 T2 时 S3 发送的 Leader 投票请求。因为 S2 之前没有投过票,它会给第一个向它发送投票请求的哨兵回复 Y,给后续再发送投票请求的哨兵回复 N,所以,在 T3 时,S2 回复 S3,同意 S3 成为 Leader。\
-
在 T4 时刻,S2 才收到 T1 时 S1 发送的投票命令。因为 S2 已经在 T3 时同意了 S3 的投票请求,此时,S2 给 S1 回复 N,表示不同意 S1 成为 Leader。发生这种情况,是因为 S3 和 S2 之间的网络传输正常,而 S1 和 S2 之间的网络传输可能正好拥塞了,导致投票请求传输慢了。\
-
在 T5 时刻,S1 得到的票数是来自它自己的一票 Y 和来自 S2 的一票 N。而 S3 除了自己的赞成票 Y 以外,还收到了来自 S2 的一票 Y。此时,S3 不仅获得了半数以上的 Leader 赞成票,也达到预设的 quorum 值(quorum 为 2),所以它最终成为了 Leader。接着,S3 会开始执行选主操作,而且在选定新主库后,会给其他从库和客户端通知新主库的信息。\
-
-
需要注意的
-
如果 S3 没有拿到 2 票 Y,那么这轮投票就不会产生 Leader。哨兵集群会等待一段时间(也就是哨兵故障转移超时时间的 2 倍),再重新选举\
-
如果哨兵集群只有 2 个实例,此时,一个哨兵要想成为 Leader,必须获得 2 票,而不是 1 票\
-
至少会配置 3 个哨兵实例(奇数个)\
-
\
5.总结
-
在解决一个系统问题的时候,会引入一个新机制,或者设计一层新功能\
-
为了实现主从切换,我们引入了哨兵\
-
为了避免单个哨兵故障后无法进行主从切换,以及为了减少误判率,又引入了哨兵集群\
-
哨兵集群又需要有一些机制来支撑它的正常运行\
-
-
支持哨兵集群的这些关键机制\
-
基于 pub/sub 机制的哨兵集群组成过程(订阅频道 topic)\
-
基于 INFO 命令的从库列表,这可以帮助哨兵和从库建立连接(从主库获取从库信息)\
-
基于哨兵自身的 pub/sub 功能,这实现了客户端和哨兵之间的事件通知\
-
-
要保证所有哨兵实例的配置是一致的,尤其是主观下线的判断值 down-after-milliseconds