diff --git a/中间件/redis/redis.md b/中间件/redis/redis.md index b51586a..b467e07 100644 --- a/中间件/redis/redis.md +++ b/中间件/redis/redis.md @@ -237,6 +237,8 @@ - [Configuration handling, propagation, and failovers](#configuration-handling-propagation-and-failovers) - [Cluster current epoch](#cluster-current-epoch) - [Configuration epoch](#configuration-epoch) + - [replica election and promotion](#replica-election-and-promotion) + - [Replica Rank](#replica-rank) # redis @@ -3728,3 +3730,63 @@ epoch为cluster的逻辑时钟,并且,epoch越大则epoch对应的消息更 #### Configuration epoch 对每个master节点,其都会在ping/pong packet中广播其configEpoch和`set of slots it serves`。 +当新的master节点创建时,其configEpoch将会被设置为0。 + +在replica election时会创建一个新的configEpoch,尝试代替failing masters的replicas将会对其epoch进行增加,并且从majority of masters处获得许可。当replica被许可后,会生成一个新的unique configEpoch,并且replica会变为新的master,并使用新生成的configEpoch。 + +在不同节点声称不同的configuration时,通过configEpoch能够帮助解决冲突。 + +对于replica节点而言,其也会在ping/pong packet中广播configEpoch,但是configEpoch的值为`configEpoch of its master as of the last time they exchanged packets`。 + +> 通过configEpoch,其他节点能够发现replica发送的配置是过时的 + +每次已知节点的configEpoch发生变化,所有接收到该信息的节点都会将该变化存储到redis.conf文件中。通常的,对currentEpoch的变化也是这样。这两个变量的变化将会被确定保存并fsync到磁盘中。 + +在failover时,configEpoch值得生成将会使用简单的算法,并被确保是`new, incremental, unique`。 + +#### replica election and promotion +replica election和promotion由replica nodes来处理,同时masters也会投票决定将哪一个replica提升为master。当master处于FAIL状态时,如果master至少存在一个replica,那么将会发生replica election。 + +对于replica而言,如果其想要将其自身提升为master,其需要开启选举并赢得选举。在master处于FAIL状态时,master所有的replicas都可以发起选举,但是只能有一个replica赢得选举并将其本身提升为master。 + +当满足如下条件时,replica就会发起选举: +- replica的master处于FAIL状态 +- master负责的slots数量不为0 +- replica replication连接的丢失不超过指定时间,用于确保被提升的replica不至于过于老旧。`这个指定时间由用户进行配置` + +为了选举成功,对replica而言第一步就是递增其currentEpoch计数器,并向master instances要求投票。 + +在请求投票时,会向集群中所有的master nodes广播FAILOVER_AUTH_REQUEST包,并等待最多`2 * NODE_TIMEOUT`。 + +一旦master针对特定replica进行了投票,会返回`FAILOVER_AUTH_ACK`,在`NODE_TIMEOUT * 2`的时间范围内,将无法针对同一master下另一replica进行投票,即正在改时间范围内,将无法响应针对同一master的其他授权请求,这样能够避免多个replicas同时被选中。 + +在投票请求被发送后,replica会对接收到的`epoch比currentEpoch小`的AUTH_ACK响应进行丢弃,这样能够避免将上一次选举的选票也计入。 + +一旦replica从majority of masters中接收到`ACKs`,其将会赢得选举。但是,当`2 * NODE_TIMEOUT`时间范围内,选票数没有达到多数,那么当前选举将会被废弃,并且在`NODE_TIMEOUT * 4`时间后会重新发起一个新的选举。 + +#### Replica Rank +一旦master处于FAIL状态,在尝试发起选举前,replica将会等待一小段时间。等待的delay将会根据如下公式进行计算 +``` +DELAY = 500 milliseconds + random delay between 0 and 500 milliseconds + REPLICA_RANK * 1000 milliseconds +``` +- 在上述公式中,`fixed delay`部分(500ms)确保FAIL状态在集群中的传播,不然replica可能会在masters尚未感知到FAIL状态的时刻就发起选举,导致masters拒绝投票。 +- random delay部分则是将replicas发起选举的时机交错开,令其不太可能同时都发起选举 +- `REPLICA_RANK`则是`replica在处理来自master的replication data数量的排名`。 + - 当master处于failing状态时,replicas相互之间会交换消息,并建立一个rank:拥有最新replication offset的replica将会排在rank 0,第二新offset的replica将会排在rank 1。 + - 在建立排名后,拥有最新offset的replica,其`REPLICA_RANK`会最小,其向masters发送`FAILOVER_AUTH_REQUEST`的时机也最靠前,抢到master选票的概率也越大 + +> mastes在failover过程中向replicas投票的机制如下: +> - replica在发起选举(发送FAILOVER_AUTH_REQUEST请求)之前,会等待一小段时间,等待时间受`REPLICA_RANK`决定 +> - `REPLICA_RANK`为replica在replicas间replication offset的排名,排名越靠前,replica的数据越新,`REPLICA_RANK`就越小,发起`FAILOVER_AUTH_REQUEST`请求的时间也就越早 +> - replica越早发起`FAILOVER_AUTH_REQUEST`,就越有可能抢到master的选票,在相同epoch期间master只能为一个replica进行投票,master在一个epoch期间内会为最早向其发送AUTH_REQUEST请求的符合条件的replica投票 +> - 通过上述机制,replication offset最新的replica最有可能抢到masters的选票,最有可能赢得选举 + +一旦replica赢得选举,其会获取一个`new, incremental, unique configEpoch`,该configEpoch将会比`any other existing master`的configEpoch都要大。并且,完成promoting的replica将会通过ping/pong packet广播其master身份,并且在packet中提供`set of served slots with a configEpoch that win over the past ones`。 + +为了加速其他节点的reconfiguration,pong packet将会被广播给cluster中所有的节点。 + +当前不可访问的节点最终会被reconfigured,可能时机如下: +- 从其他节点接收到ping/pong packet时 +- 其向其他节点发送的heartbeat packet被检测为过时,从其他节点接收到UPDATE packet时 + +对于其他节点,将会探知到`a new master serving the same slots served by the old master but with greater configEpoch`,并且其他节点会更新configuration。`replicas of the old master`不仅会更新配置,还会`replicate from the new master`。