Redis Sentinel和Raft协议
Sentinel(哨兵)为redis提供高可用性(HA),官方文档 https://redis.io/topics/sentinel
用于监视主从服务器,主节点下线时进行选主。本质上是一个运行在特殊模式下的redis服务器,只是端口、命令集等有所不同,维护主从服务器、其他sentinel的状态,一般通过配置文件(主节点IP,下线时间阈值等)来初始化。
哨兵和master一般是多对多的,多个哨兵监视多个master。哨兵连接主从服务器时,除了命令连接,还会创建订阅连接,订阅的频道是master维度的,这样监视同一个master的哨兵,可以通过该频道来共享信息。哨兵可以通过频道知晓其他哨兵的存在,可以自动发现,不需要额外的配置。
哨兵心跳默认1 s,向主从服务器、其他哨兵发送PING命令,当在down-after-milliseconds内均返回无效回复,那么该实例(主从服务器或者哨兵)进入主观下线状态。
主观下线状态是单个哨兵自己的判断,因为每个哨兵的ping响应时间、down-after-milliseconds等参数不一样,需要询问其他哨兵,如果一个实例被足够多的哨兵判断为主观下线状态,则进入客观下线状态,执行故障转移,先选举leader哨兵,leader哨兵再将优先级最高、偏移量最大的从服务器选为主服务器。
领头Sentinel选举和Raft协议:
1、每次选举之后,不论成功与否,所有哨兵的配置纪元(configuration epoch)加一;
2、每个epoch里,每个哨兵只有一次机会将某个哨兵选举为leader;
3、每个发现主服务器客观下线的哨兵,都会向其他哨兵发送命令,要求将自己设置为leader,每个哨兵将最先收到的请求中的节点设为leader(请求的纪元要大于等于自身的纪元);
4、如果某个哨兵被半数以上哨兵选举为leader,则成为leader;
5、给定时间内未选出leader,一段时间后重新选举;
2、4决定了一个纪元里只有一个哨兵成为leader,如果选出了更高纪元的leader以更高的为准,简单来说就是每个哨兵选自己,并且根据先到先得的规则,接受/拒绝其他哨兵成为leader的请求,超过半数的哨兵成为leader,否则重新选举。
这种选举是Raft协议的实现,Raft协议有leader选举和日志复制两个子问题,Raft协议参考