redis-cluster不可用情况

1、集群主库半数宕机

2、集群某个节点的主从全数宕机

当某个master挂掉后,在cluster集群仍然可用的前提夏,由于某个master有多个slave,某个slave提升为master,这个过程称为选举。

currentEpoch 这是一个集群状态相关的概念,可以当作记录集群状态变更的递增版本号。每个集群节点,都会通过server.cluster->currentEpoch记录当前的currentEpoch。

集群节点创建时,不管是master还是slave,都置currentEpoch为0.当前节点接收到来自其他节点的包时,如果发送者的currentEpoch大于当前节点会更新currentEpoch为发送者的currentEpoch。因此,集群的所有节点从currentEpoch最终会达成一致,相当于对集群状态的认知达成了一致。

过程如下

1、slave发现自己的master变为FAIL

2、发起选举前,slave先给自己的epoch加1,然后请求其它master给自己投票。slave是通过广播FAILOVER_AUTH_REQUEST包给集中的每个masters。

3、slave发起投票后,会等待至少两倍NODE_TIMEOUT时长接收自己投票结果,不管NODE_TIMEOUT何值,也至少会等待2秒。

4、master接收投票后给slave响应FAILOVER_AUTH_ACK,并且在NODE_TIMEOUT*2 时间内不会给同一个master的其他slave投票。

5、如果slave收到FAILOVER_AUTH_ACK响应的epoch值小于自己的epoch,则会直接丢弃。以但slave收到多数master的FAILOVER_AUTH_ACK则声明自己赢得选举。

6、如果slave在两倍的NODE_TIMEOUT时间内至少2秒未赢得选举,则放弃本次选举,然后4倍NODE_TIMEOUT时间发起再次选举

之所以强制延迟至少0.5秒选举,是为确保master的fail状态在整个集群内传开,否则可能只有小部分master知晓,而master只会给处于fail状态的master的slaves投票。

如果一个slave的master状态不是fail,则其他的master不会给它投票,redis通过八卦协议传播fail。而在固定延迟上再加一个随机延迟是为了多高slaves同时发起选举。

延迟计算公式:

DELAY = 500 + RANDOM(0~500)+SLAVE_RANK*1000ms

SLAVE_RANK表示此slave已经从master复制的数据越新。这种方式下,持有最新数据的slave将会首先发起选举。