Redis设计与实现-12.sentinel
Sentinel(哨兵)是Redis的高可用性的解决方案,由一个或者多个Sentinel实例组成了Sentinel系统可以监视任意多个主服务器,以及这些下属的从服务器。假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程(运行在特殊模式下的Redis服务),它能监控多个master-slave集群,发现master宕机后能进行自懂切换。
它的主要功能有以下几点:
- 不时地监控redis是否按照预期良好地运行;
- 如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端);
- 能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址。
Sentinel支持集群
很显然,只使用单个sentinel进程来监控redis集群是不可靠的,当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。所以有必要将sentinel集群,这样有几个好处:
- 即使有一些sentinel进程宕掉了,依然可以进行redis集群的主备切换;
- 如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换(单点问题);
- 如果有多个sentinel,redis的客户端可以随意地连接任意一个sentinel来获得关于redis集群中的信息。
Sentinel初始化
Sentinel初始化步骤:
- Sentinel本质上只是一个运行在特殊模式下的Redis服务器,所以初始化Sentinel之前要初始化一个Redis服务器,
- Sentinel是特殊的服务器,还无法使用Redis的命令以及代码,Sentinel使用自己的专用代码,所以需要将代码换成Sentinel代码。
- 初始化sentinelState结构
- 初始化Sentinel状态下的Masters属性
- 创建连向主服务器的网络连接
服务器会初始化一个sentinel.c/sentinelState结构,这个结构保存了服务器中所有和Sentinel功能有关的状态。
struct sentinelState{ //当前纪元 unit64_t current_epoch; //保存了所有被这个sentinel监视的主服务器 //字典的键是主服务器的名字 //字典的值则是一个指向sentinelRedisInstance结构的指针 dict *masters; //是否进入了TILT模式 int tilt; //目前正在执行的脚本数量 int running_scripts; //进入TILT模式的时间 mstime_t tilt_start_time; //最后一次执行时间处理器的时间 mstime_t previous_time; //一个FIFO队列,包含了所需要执行的用户脚本 list *scripts_queue; }sentinel;
- 命令连接:这个连接专门用于向主服务器发送命令,并接收命令回复。
- 订阅连接:专门订阅主服务器的 _sentinel_:hello频道。
Sentinel的三个定时任务
1.Sentinel默认会以每10秒一次的频率,通过命令连接向被监视的主服务器和从服务器发送INFO命令,并通过分析INFO命令的回复来获取服务器的当前信息。
2.每2秒每个sentinel节点通过master节点的channel(sentinel:hello)交换信息
3.每1秒每个sentintel节点对master节点和slave节点以及其余的sentinel节点执行ping操作
Sentinel的主观客观下线
主观下线:当前Sentinel节点认为Redis节点不可用
客观下线:当前Sentinel接收到其他Sentinel消息,认定这个Redis节点不可用。(执行故障转移)
Sentinel故障转移
Sentinel的选举
1. 领导者选举
作用:选举出一个sentenel节点作为领导者去进行故障转移操作。
过程:
1). 每个做主观下线的sentinel节点向其他sentinel节点发送上面那条命令,要求将它设置为领导者。
2). 收到命令的sentinel节点如果还没有同意过其他的sentinel发送的命令(还未投过票),那么就会同意,否则拒绝。
3). 如果该sentinel节点发现自己的票数已经过半且达到了quorum的值,就会成为领导者。
4). 如果这个过程出现多个sentinel成为领导者,则会等待一段时间重新选举。
2. 选出新的master节点
redis sentinel会选一个合适的slave来升级为master,那么,如何选择一个合适的slave呢?顺序如下:
1). 选择slave-priority最高的slave节点(默认是相同)。
2). 选择复制偏移量最大的节点。
3). 如果以上两个条件都不满足,选runId最小的(启动最早的)。
3. 更改slave节点的master节点
当选举出新的master节点后,会将其余的节点变更为新的master节点的slave节点,如果原有的master节点重新上线,成为新的master节点的slave节点。
4. 通知客户端
当所有节点配置结束后,sentinel会通知客户端节点变更信息。
5. 客户端连接新的master节点
客户端收到节点信息后,会连接新的master节点。