【Redis】Redis Cluster-集群故障转移

【Redis】Redis Cluster-集群故障转移,第1张

集群定时任务 clusterCron 中,会遍历集群中的节点,对每个节点进行检查,判断节点是否下线。与节点下线相关的状态有两个,分别为 CLUSTER_NODE_PFAIL 和 CLUSTER_NODE_FAIL 。

CLUSTER_NODE_PFAIL :当前节点认为某个节点下线时,会将节点状态改为 CLUSTER_NODE_PFAIL ,由于可能存在误判,所以需要根据集群中的其他节点共同决定是否真的将节点标记为下线状态, CLUSTER_NODE_PFAIL 可以理解为疑似下线,类似哨兵集群中的主观下线

CLUSTER_NODE_FAIL :集群中有过半的节点标认为节点已下线,此时将节点置为 CLUSTER_NODE_FAIL 标记节点下线, CLUSTER_NODE_FAIL 表示节点真正处于下线状态,类似哨兵集群的客观下线

在集群定时任务遍历集群中的节点进行检查时,遍历到的每个节点记为 node ,当前节点记为 myself ,检查的内容主要有以下几个方面:

一、判断孤立主节点的个数

如果当前节点 myself 是从节点,正在遍历的节点 node 是主节点,并且 node 节点不处于下线状态,会判断孤立节点的个数,满足以下三个条件时,认定 node 是孤立节点,孤立节点个数增1:

二、检查连接

这一步主要检查和节点间的连接是否正常,有可能节点处于正常状态,但是连接有问题,此时需要释放连接,在下次执行定时任务时会进行重连,释放连接需要同时满足以下几个条件:

三、疑似下线判断

ping_delay 记录了当前时间距离向 node 节点发送PING消息的时间, data_delayd 记录了 node 节点向当前节点最近一次发送消息的时间,从ping_delay和data_delay中取较大的那个作为延迟时间。

如果延迟时间大于超时时间,判断 node 是否已经处于 CLUSTER_NODE_PFAIL 或者 CLUSTER_NODE_FAIL 状态,如果都不处于,将节点状态置为 CLUSTER_NODE_PFAIL ,认为节点疑似下线。

上述检查完成之后, 会判断当前节点是否是从节点,如果不处于 CLUSTER_MODULE_FLAG_NO_FAILOVER 状态,调用 clusterHandleSlaveFailover 处理故障转移,不过需要注意此时只是将节点置为疑似下线,并不满足故障转移条件,需要等待节点被置为FAIL下线状态之后,再次执行集群定时任务进入到 clusterHandleSlaveFailover 函数中才可以开始处理故障转移。

当前节点认为某个node下线时,会将node状态置为 CLUSTER_NODE_PFAIL 疑似下线状态,在定时向集群中的节点交换信息也就是发送PING消息时,消息体中记录了node的下线状态,其他节点在处理收到的PING消息时, 会将认为node节点下线的那个节点加入到node的下线链表fail_reports中,并调用 markNodeAsFailingIfNeeded 函数判断是否有必要将节点置为下线FAIL状态

markNodeAsFailingIfNeeded

markNodeAsFailingIfNeeded用于判断是否有必要将某个节点标记为FAIL状态:

clusterHandleSlaveFailover

由上面的内容可知,节点客观下线时会被置为 CLUSTER_NODE_FAIL 状态,下次执行集群定时任务时,在故障转移处理函数 clusterHandleSlaveFailover 中,就可以根据状态来检查是否需要执行故障转移。

不过在看 clusterHandleSlaveFailover 函数之前,先看一下 clusterState 中和选举以及故障切换相关的变量定义:

clusterHandleSlaveFailover函数中的一些变量

data_age : 记录从节点最近一次与主节点进行数据同步的时间 。如果与主节点处于连接状态,用当前时间减去最近一次与master节点交互的时间,否则使用当前时间减去与master主从复制中断的时间。

auth_age : 当前时间减去发起选举的时间 ,也就是距离发起选举过去了多久,用于判断选举超时、是否重新发起选举使用。

needed_quorum : quorum的数量,为集群中节点的数量的一半再加1

auth_timeout : 等待投票超时时间。

auth_retry_time : 等待重新发起选举进行投票的时间,也就是重试时间

一、故障转移条件检查

首先进行了一些条件检查,用于判断是否有必要执行故障转移,如果 处于以下几个条件之一,将会跳出函数,结束故障转移处理

二、主从复制进度校验

cluster_slave_validity_factor 设置了故障切换最大主从复制延迟时间因子,如果不为0需要校验主从复制延迟时间是否符合要求。

如果主从复制延迟时间 data_age 大于 mater向从节点发送PING消息的周期 + 超时时间 故障切换主从复制延迟时间因子 并且不是手动执行故障切换,表示主从复制延迟过大,不能进行故障切换终止执行。

三、是否需要重新发起选举

如果距离上次发起选举的时间大于超时重试时间,表示可以重新发起投票。

四、延迟发起选举

五、发起投票

如果满足执行故障的条件,接下来需从节点想集群中的其他节点广播消息,发起投票,不过只有主节点才有投票权。 failover_auth_sent 为0表示还未发起投票,此时开始发起投票:

六、执行故障切换

当某个节点获取到了集群中大多数节点的投票,即可进行故障切换,这里先不关注,在后面的章节会讲。

clusterGetSlaveRank用于计算当前节点的等级,遍历所属主节点的所有从节点,根据主从复制进度 repl_offset 计算, repl_offset 值越大表示复制主节点的数据越多,所以等级越高,对应的 rank 值就越低。

从节点在发起选举使用了 rank 的值作为延迟时间,值越低延迟时间越小,意味着选举优先级也就越高。

当从节点认为主节点故障需要发起投票,重新选举主节点时,在集群中广播了 CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST 消息,对应的处理在 clusterProcessPacket 函数中,里面会调用 clusterSendFailoverAuthIfNeeded 函数进行投票:

clusterSendFailoverAuthIfNeeded

clusterSendFailoverAuthIfNeeded函数用于进行投票,处理逻辑如下:

以上条件校验通过, 表示当前节点可以投票给发送请求的节点,此时更新 lastVoteEpoch ,记录最近一次投票的纪元(轮次),更新投票时间 node->slaveof->voted_time ,然后向发起请求的节点回复 CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 消息。

主节点对发起投票请求节点的回复消息 CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 同样在消息处理函数 clusterProcessPacket 中,会对发送回复消息的节点进行验证:

同时满足以上三个条件时, 表示发送者对当前节点进行了投票,更新当前节点记录的收到投票的个数, failover_auth_count 加1,此时有可能获取了大多数节点的投票,先调用 clusterDoBeforeSleep 设置一个 CLUSTER_TODO_HANDLE_FAILOVER 标记,在周期执行的时间事件中会调用对状态进行判断决定是否执行故障转移。

从节点收到投票后,会添加 CLUSTER_TODO_HANDLE_FAILOVER 标记,接下来看下对 CLUSTER_TODO_HANDLE_FAILOVER 状态的处理。

在 beforeSleep 函数(serverc文件中),如果开启了集群,会调用 clusterBeforeSleep 函数,里面就包含了对 CLUSTER_TODO_HANDLE_FAILOVER 状态的处理:

beforeSleep 函数是在Redis事件循环 aeMain 方法中被调用的,详细内容可参考 事件驱动框架源码分析 文章。

clusterBeforeSleep

在clusterBeforeSleep函数中,如果节点带有 CLUSTER_TODO_HANDLE_FAILOVER 标记,会调用 clusterHandleSlaveFailover 函数进行处理:

clusterHandleSlaveFailover 函数在上面我们已经见到过,这次我们来关注集群的故障转移处理。

如果当前节点获取了大多数的投票,也就是 failover_auth_count (得到的投票数量)大于等于 needed_quorum , needed_quorum 数量为集群中节点个数的一半+1,即可执行故障转移,接下来会调用 clusterFailoverReplaceYourMaster 函数完成故障转移。

clusterFailoverReplaceYourMaster

如果从节点收到了集群中过半的投票,就可以成为新的master节点,并接手下线的master节点的slot,具体的处理在clusterFailoverReplaceYourMaster函数中,主要处理逻辑如下:

总结

以上就是关于【Redis】Redis Cluster-集群故障转移全部的内容,包括:【Redis】Redis Cluster-集群故障转移、、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9565126.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存