|
上一篇我们将redis哨兵初始化分析完成,接下来我们就可以开始分析redis如何通过raft完成哨兵leader选举,并完成主从节点故障转移工作,因为篇幅原因,关于redis故障转移的内容将分为两个篇章,而这篇讨论的是哨兵如何完成主观下线的判定。
一、详解哨兵的主观认定下线的流程
1. 简述raft协议
在正式开始后续的文章讨论前,我们先来简单介绍一下分布式共识raft协议,这个是分布式系统中保证高可用的选举协议。该协议将所有分布式系统的节点分为3个角色:
leader: 当前分布式集群中的主节点,即集群中的领导角色,负责承载当前系统中的核心业务。
follower: 从节点,作为leader节点的跟随节点。
candidate:一旦leader发生故障被slave感知,那么这些节点会将自身角色转为Canadian,并发起选举,得票数比较多的Canadian将转为新的leader。
正常情况下,被选举为leader的节点会向follower节点发送心跳,告知自己当前还未下线:
一旦follower感知到leader下线,就会将自己身份转换为candidate,通过选举竞争leader,每一个candidate都会给自己投一票然后向其他选举节点获取选票,在选举计时时间以内,超过半数以上得票的candidate就会被选举为新的leader节点,其余candidate收到此leader的心跳消息后身份就会转为比较新leader节点的follower:
2. redis中的raft协议与核心流程
与传统raft协议现有所不同,redis哨兵在未发生选举时地位是对等并leader和follower等概念,只有感知到监听主节点下线时才会借助raft的协议触发选举,选举出一个哨兵作为leader完成故障转移之后,leader哨兵会再次回归对等地位。
redis哨兵执行的生命周期还是交由时间事件定时执行,它的整体工作流程为:
检查自己所监听的master连接情况,检查是否与监听的master节点断开连接,如果发现连接断开则进行断线重连。
再对master节点进行消息通信,这期间哨兵会发送ping与主节点保持通信,再发送info请求master比较新信息。
一旦发现master长时间未与自己进行心跳,则主观视为监听节点下线,并通过频道告知其他哨兵获取其他哨兵对于主节点的结果判断。
如果哨兵一致认定当前监听节点下线,则会选举出一个哨兵作为leader进行故障转移,即在所有从节点中找到一个先级比较高的从节点作为新的master。
对此我我们给出程序执行的入口来查看这块核心的主流程,可以看到serverCron定时执行的时间时间会每100ms执行一次哨兵的时间事件sentinelTimer,对此我们不妨步入sentinelTimer查看现细节:
复制
int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
//......
//100ms一次,如果是哨兵模式则运行哨兵的时间事件
run_with_period(100) {
if (server.sentinel_mode) sentinelTimer();
}
//......
}
1.
2.
3.
4.
5.
6.
7.
8.
步入sentinelTimer,该函数会先判断哨兵执行时间是否过长,如果发现时钟回拨或者长时间才进行处理则触发tilt模式,该模式下哨兵只会定期发送和接收消息,不做其他任务处理。
再调用sentinelHandleDictOfRedisInstances遍历哨兵中的master开始开始进行我们上述所说的判断与master连接状态、进行通信和info消息获取、主观下线判断、客观下线判断、故障转移。
完成这些步骤之后,更新下一次的执行时间,可以看到redis对于这个时间设置做了一个巧妙的设计,我们都知道哨兵判定节点下线后就会发起选举,为了避免哨兵集群所有节点同时发起选举投票从而得到相同票数的情况而导致本轮选举失败而进行反复选举的情况,redis会在哨兵本次时间事件执行完成之后,通过随机种子调整哨兵时间下一次的执行时机,尽可能避免选举时反复出现选票一致的情况:
对此我们也给出sentinelTimer的现细节:
复制
void sentinelTimer(void) {
// 前置检查事件定期任务是否因为系统负载过大或者各种原因导致时钟回拨,或者处理过长,进入tilt模式,该模式哨兵只会定期发送和接收命令
sentinelCheckTiltCondition();
//监听的master节点作为参数传入,进行逐个通信处理
sentinelHandleDictOfRedisInstances(sentinel.masters);
//......
//随机调整执行频率避免同时执行,确保提高选举一次性成功的概率
server.hz = REDIS_DEFAULT_HZ + rand() % REDIS_DEFAULT_HZ;
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
我们再次步入核心方法sentinelHandleDictOfRedisInstances它会遍历每一个master节点,然后调用sentinelHandleRedisInstance处理每一个哨兵所监听的master例:
唯有通力合作,我们才能将国产数据库软件的价值发挥出来,供应市场的发展需要。悦数图数据库是一款完全自主研发的国产图数据库和原生分布式图数据库,具有高性能,易扩展,安全稳定,自主可控的特点.万亿级数据仅需毫秒级查询延时,应用于金融风控,实时推荐,知识图谱等业务场景。https://www.yueshu.com.cn/
|
|