Redis 集群中的纪元(epoch)

本文深入探讨RedisCluster中的纪元(epoch)概念,包括currentEpoch和configEpoch的作用及其实现机制,阐述了它们在集群状态变更和节点配置管理中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

纪元(epoch)

Redis Cluster 使用了类似于 Raft 算法 term(任期)的概念称为 epoch(纪元),用来给事件增加版本号。Redis 集群中的纪元主要是两种:currentEpoch 和 configEpoch。

currentEpoch

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

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

currentEpoch 作用

currentEpoch 作用在于,当集群的状态发生改变,某个节点为了执行一些动作需要寻求其他节点的同意时,就会增加 currentEpoch 的值。目前 currentEpoch 只用于 slave 的故障转移流程,这就跟哨兵中的sentinel.current_epoch 作用是一模一样的。当 slave A 发现其所属的 master 下线时,就会试图发起故障转移流程。首先就是增加 currentEpoch 的值,这个增加后的 currentEpoch 是所有集群节点中最大的。然后slave A 向所有节点发起拉票请求,请求其他 master 投票给自己,使自己能成为新的 master。其他节点收到包后,发现发送者的 currentEpoch 比自己的 currentEpoch 大,就会更新自己的 currentEpoch,并在尚未投票的情况下,投票给 slave A,表示同意使其成为新的 master。

configEpoch

这是一个集群节点配置相关的概念,每个集群节点都有自己独一无二的 configepoch。所谓的节点配置,实际上是指节点所负责的槽位信息。

每一个 master 在向其他节点发送包时,都会附带其 configEpoch 信息,以及一份表示它所负责的 slots 信息。而 slave 向其他节点发送包时,其包中的 configEpoch 和负责槽位信息,是其 master 的 configEpoch 和负责的 slot 信息。节点收到包之后,就会根据包中的 configEpoch 和负责的 slots 信息,记录到相应节点属性中。

configEpoch 作用

configEpoch 主要用于解决不同的节点的配置发生冲突的情况。举个例子就明白了:节点A 宣称负责 slot 1,其向外发送的包中,包含了自己的 configEpoch 和负责的 slots 信息。节点 C 收到 A 发来的包后,发现自己当前没有记录 slot 1 的负责节点(也就是 server.cluster->slots[1] 为 NULL),就会将 A 置为 slot 1 的负责节点(server.cluster->slots[1] = A),并记录节点 A 的 configEpoch。后来,节点 C 又收到了 B 发来的包,它也宣称负责 slot 1,此时,如何判断 slot 1 到底由谁负责呢?

这就是 configEpoch 起作用的时候了,C 在 B 发来的包中,发现它的 configEpoch,要比 A 的大,说明 B 是更新的配置。因此,就将 slot 1 的负责节点设置为 B(server.cluster->slots[1] = B)。在 slave 发起选举,获得足够多的选票之后,成功当选时,也就是 slave 试图替代其已经下线的旧 master,成为新的 master 时,会增加它自己的 configEpoch,使其成为当前所有集群节点的 configEpoch 中的最大值。这样,该 slave 成为 master 后,就会向所有节点发送广播包,强制其他节点更新相关 slots 的负责节点为自己。

参考资料

  1. Redis Cluster Specification
  2. Redis cluster tutorial
  3. Redis系列九:redis集群高可用
  4. Redis源码解析:27集群(三)主从复制、故障转移

License

遵守创作共享 CC BY-NC-SA 3.0协议

### Redis集群优先级处理机制 在Redis集群中,节点或请求的优先级处理机制主要体现在主节点故障时从节点的选举过程。以下是关于优先级处理机制的具体内容: #### 1. 优先级配置与判断 Redis通过`replica-priority`参数定义从节点的优先级,该参数位于`redis.conf`文件中,默认值为100。优先级数值越小,表示该从节点被选为主节点的可能性越高[^1]。如果某个从节点的优先级设置为0,则该节点将永远不会参与选举[^3]。 #### 2. 数据同步状态(复制偏移量) 在优先级相同的情况下,Redis会根据复制偏移量(`replica offset`)来判断哪个从节点的数据是最新的。复制偏移量表示从节点接收到的主节点数据量的字节数。偏移量越大,说明该从节点的数据越新,因此更有可能被选为主节点[^2]。 #### 3. 配置纪元(Configuration Epoch) 在故障转移过程中,Redis集群会优先选择配置纪元(Configuration Epoch)最大的从节点作为新的主节点。配置纪元是一个递增的计数器,用于标识当前集群的配置版本。配置纪元越大的从节点,通常意味着其数据更可能是最新的。 #### 4. 节点断开时间 每个从节点都会检查与故障主节点的断线时间。如果断开时间超过`cluster-node-timeout * cluster-slave-validity-factor`,则该从节点将失去参与选举的资格。默认情况下,`cluster-slave-validity-factor`的值为10,这意味着如果从节点与主节点断开的时间过长,其数据可能已经过时,无法参与选举。 #### 5. runid 比较 如果多个从节点的优先级、复制偏移量和配置纪元都相同,则Redis会选择`runid`最小的从节点作为新的主节点。`runid`是每个Redis实例启动时随机生成的一个唯一标识符,长度为40位字符[^3]。 #### 6. Sentinel 集群中的选举流程 在Sentinel集群中,当主节点发生故障时,选举新主节点的过程包括以下步骤: - 主观下线:Sentinel检测到主节点不可用,并标记为主观下线。 - 客观下线:多个Sentinel达成一致,确认主节点确实不可用。 - Leader选举:Sentinel集群选举出一个Leader负责协调故障转移。 - 新主节点选择:根据上述优先级规则,从剩余的从节点中选出一个新的主节点[^4]。 ```python # 示例代码:查看从节点的优先级和偏移量 info = redis_client.info('replication') print(f"Replica Priority: {info['master_repl_offset']}") print(f"Replica Offset: {info['repl_offset']}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值