返回目录
说明
- clusterCron 每秒执行10次
- clusterCron 内置了一个iteration计数器。每一次运行clusterCron,iteration都加1。当 iteration % 10 == 0的时候,就会随机选取一个节点,给它发送PING。而由于clusterCron每秒执行10次,所以实际上每秒才会PING一次随机节点。
过程
++iteration
if 配置的cluster-announce-hostname发生了变化:
更新myself的hostname
计算handshakeTimeout = max(cluster-node-timeout, 3000)
statsPfailNodes = 0
遍历cluster节点字典中的每个node:
对于node的inbound link和outbound link:
1. 检查它们的发送buffer能否收缩,从而节省内存
2. 如果配置的cluster-link-sendbuf-limit != 0,检查它们的发送buffer
(可能经过1的收缩)是否超过了限制,若是则释放掉相应的link
3. 更新统计它们对内存的使用量
跳过myself
跳过处于NOADDR的node
if node处于PFAIL状态:
++statsPfailNodes
if node处于handshake &&
(当前时间 - node的创建时间)> handshakeTimeout:
删除node
检查node是否disconnected,若是,则重建连接
在连接创建成功之后:
if node处于MEET状态:
向它发送MEET消息
else:
向它发送PING消息
清除node的MEET标记
if iteration % 10 == 0:
从cluster节点字典中随机选取5个node,它们满足以下条件:
1. 已连接上(有outbound link)
2. pingSent == 0 (没有在等待PONG)
3. 不是myself
4. 没有处于handshake
再从这5个node中,选取pongReceived最小的node
if 这样的node存在:
给它发送PING消息
orphanedMasters = 0
maxSlaves = 0
thisSlaves = 0
遍历cluster节点字典的每个node:
跳过myself
跳过没有地址(NOADDR)的node
跳过处于handshake的node
if myself是slave && node是master && node没有FAIL:
okSlaves = node上没有处于FAIL的slave数
if okSlaves == 0 && node的slots > 0 && node有MIGRATE_TO标记:
++orphanedMasters
maxSlaves = max(okSlaves, maxSlaves)
if node是myself的master:
thisSlaves = okSlaves
pingDelay = 当前时间 - node的pingSent
dataDelay = 当前时间 - node的dataReceived
if node的link存在 &&
当前时间 - link的创建时间 > cluser-node-timeout &&
node的pingSent > 0 &&
pingDelay > cluster-node-timeout/2 &&
dataDelay > cluster-node-timeout/2:
释放掉link,下次会自动重连(参考上面的逻辑)
if node的link存在 &&
node的pingSent == 0 &&
当前时间 - node的pongReceived > cluster-node-timeout/2:
给node发送PING消息
if 我们是node的master,而它对我们请求了manual failover:
给node发送PING消息
if node的pingSent > 0:
nodeDelay = min(pingDelay, dataDelay)
if nodeDelay > cluster-node-timeout &&
node没有处于PFAIL或FAIL:
把node设置成timeout(PFAIL状态)
if myself是slave && master有地址了 && 还没开始复制master:
更新master的IP和port,开始复制
if manual failover已经timeout:
重置manual failover的状态
if myself是slave:
处理 Manual Failover
处理 Slave Failover
if orphanedMasters > 0 &&
maxSlaves >= 2 && thisSlaves == maxSlaves &&
cluster-allow-replica-migration:
if 我们认为当前cluster处于FAIL:
跳过migration
if 我们的master拥有的正常slave数 < cluster-migration-barrier:
跳过migration
target = null
遍历cluster节点字典中的每个node:
okSlaves = 0
isOrphaned = 1
if node是slave || node处于FAIL || node没有MIGRATE_TO标记):
isOrphaned = 0
if node是master:
okSlaves = node拥有的没有处于FAIL的slave数
if okSlaves > 0:
isOrphaned = 0
if isOrphaned:
if target == null &&
node的slots > 0:
target = node
if node的orphanedTime == 0:
设置为当前时间
else:
重置node的orphanedTime为0
if okSlaves == maxSlaves:
minID = 从node的slaves中查找出最小的ID
if myself的ID < minID:
candidate = myself
if target != null &&
candidate == myself &&
当前时间 - target的orphanedTime > 5000ms:
把target设置为我们的新master
if cluster信息发生了变化 || 我们认为cluster处于FAIL状态:
更新nodes.conf文件