From 04e8485dcaa9f50f2f933aead1211193c9a56ec7 Mon Sep 17 00:00:00 2001 From: asahi Date: Wed, 15 Oct 2025 14:54:17 +0800 Subject: [PATCH] =?UTF-8?q?doc:=20=E9=98=85=E8=AF=BBredis=20cluster?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 中间件/redis/redis.md | 94 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/中间件/redis/redis.md b/中间件/redis/redis.md index 7ae2a82..6b1d4da 100644 --- a/中间件/redis/redis.md +++ b/中间件/redis/redis.md @@ -240,6 +240,12 @@ - [replica election and promotion](#replica-election-and-promotion) - [Replica Rank](#replica-rank) - [masters reply to replica vote request](#masters-reply-to-replica-vote-request) + - [Example of configuration epoch usefulness during partitions](#example-of-configuration-epoch-usefulness-during-partitions) + - [Hash slots configuration propagation](#hash-slots-configuration-propagation) + - [Rule 1](#rule-1) + - [Rule 2](#rule-2) + - [UPDATE message, a closer look](#update-message-a-closer-look) + - [How nodes rejoin the cluster](#how-nodes-rejoin-the-cluster) # redis @@ -3803,4 +3809,90 @@ DELAY = 500 milliseconds + random delay between 0 and 500 milliseconds + REPLICA - 如果master已经投过票,那么在`NODE_TIMEOUT * 2`的时间范围内,master并不会再次针对`同一master的replica`投票 - 对master而言,其并不会对`选取最佳副本`做任何尝试。如果replica的master处于FAIL状态,并且master在本epoch内没有针对`master of replica`进行投票,那么直接会授予选票。但是,基于replica发起AUTH REQUEST之前的延迟,最佳的副本最有可能赢得选举,因为其发起请求最早 - 如果master拒绝为replica进行投票,那么其并不会向replica发送negative reply,仅仅会无视请求 -- master不会为 \ No newline at end of file +- 如果replicas发送的configEpoch小于`master table中负责replica宣称slots的configEpoch`,那么master将不会为replica投票 + +#### Example of configuration epoch usefulness during partitions +如下示例展示了epoch如何令replica promotion的过程在network partition的场景下容错性更高: +- 假如一个master之后都不再可访问,且其拥有3个replicas A, B, C +- replica A赢得选举并且被提升为master +- network partition令A不再可被majority of clusters访问 +- replica B赢得选举并被提升为master +- partition又令B不再可被majority of clusters访问 +- 此时第一次partition恢复,A再次可被访问 + +在这种场景下,B宕机而A又重新可访问,此时A的role仍为master;同时,replica也在尝试发起选举,具体发生如下: +- C会尝试被选举并且成功,因为对于majority of masters而言C的masterB已经宕机,C将会获取一个新的configEpoch +- A在通过ping/pong packet向其他节点生成其为master的操作会失败;对于其他节点而言,A宣称的slots已经关联了更高版本configEpoch +- 故而,所有节点都会更新其table,将对应hash slots分配给C + +#### Hash slots configuration propagation +在redis cluster中,`节点负责slots集合信息的传播机制`是重要的部分。该机制对于`新集群启动`以及`replica被提升为master后升级configuration`都至关重要。 + +通过该机制,允许节点在被partitioned away任意长时间之后,都能以合理的方式重新加入集群。 + +如下存在两种hash slot configuration的传播方式: +- heartbeat message: ping/pong packet的发送者总会将其负责slots的信息添加到packet中 +- update message: 由于每个heartbeat message中都包含发送方的configEpoch以及负责slots的信息,如果heartbeat message的接收方发现发送方的信息已过时,则会向发送方发送一个update message用于对发送方进行更新,update message中包含新的信息 + +heartbeat/UPDATE message的接收方会使用简单的规则来更新hash slots到node的映射table。当创建新的cluster node时,新节点的local hash slot table将会简单初始化为NULL entires,故而每个hash slot都没有和任何node相关联,示例如下: +``` +0 -> NULL +1 -> NULL +2 -> NULL +... +16383 -> NULL +``` +##### Rule 1 +如果一个hash slot并没有被分配给任何节点(设置为NULL),并且有一个known node对该slot做了宣称,那么会修改hash slot table,将该hash slot与宣称节点做关联。 + +故而,如果从A节点处接收到了heartbeat packet,宣称A将负责1和2slot,且configEpoch值为3,那么table被修改后的值如下: +``` +0 -> NULL +1 -> A [3] +2 -> A [3] +... +16383 -> NULL +``` + +当创建新的cluster时,系统管理员需要手动将slots分配给masters,并且该分配信息将会在集群内传播。 + +但是,hash slots可以通过如下两种事件进行修改,故而上述规则是不够的: +- 当failover导致replica promotion时,由原master负责的节点会被重新分配给replica +- 通过reshard,一个slot可以从一个节点被移动到另一个节点 + +当故障转移发生时,其会获取一个新的configEpoch,该configEpoch比之前生成过的任何configEpoch都要大。在完成故障转移后,其会在集群范围内广播heartbeat packet,而packet的接收方将更新其slot table。 + +##### Rule 2 +如果hash slot已经被分配,并且一个known node声称其负责该hash slot,那么会比较configEpoch的大小。如果heartbeat的大小要大于当前hash slot table中该hash slot的configEpoch,其会将hash slot重新绑定给新的节点。 + +故而,在从B处收到消息,声称其负责hash slot 1和hash slot 2,且configEpoch为4时,接收方则会将其hash slot table更新,更新后内容如下: +``` +0 -> NULL +1 -> B [4] +2 -> B [4] +... +16383 -> NULL +``` +由于Rule 2,最终集群中所有的节点都会达成共识,hash slot的owner为`声称该slot的所有节点中configEpoch最大的节点`。 + +redis cluster中该机制被称为`last failover wins`。 + +在resharding的过程中,也会发生上述流程。当`node importing a hash slot`完成import操作时,其configuration epoch将会递增,确保该改动将会在集群中传播。 + +### UPDATE message, a closer look +在先前的章节中表明了update message的工作机制。node A可能在一段时间后重新加入到集群中,其会发送heartbeat packets来声称其对hash slot 1和2的所有权,epoch为3。所有`receivers with updated information`都会发现被声称的slot已经被分配,且该分配的configEpoch更大。 + +故而,拥有更大configEpoch的接收者将会向node A发送UPDATE message,向A发送最新的配置,而A会对slot的分配进行更新。 + +### How nodes rejoin the cluster +当节点重新加入到cluster时,将使用同样的机制。 + +继续使用上述的示例,node A将会被通知hash slot 1和2目前归属于node B。假设slot 1和2是A仅有的slots,那么A所负责的slots的数量将会变为0,故而A将会重新变为新master的replica。 + +在实际场景下,可能会更加复杂。如果A在过了很久之后才重新加入集群,那么A原来负责的slots可能散布在多个节点中,例如slot 1现可能归属于B而slot 2现归属于C。 + +实际的cluster node role switch rule如下: +- a master node will change its configuration to replciate the node that stole its last hash slot + +对于replicas而言,其行为和master相同,也会`reconfigure to replicate the node that stole the last hash slot of its former master` +