为什么创建 Redis 集群时会自动错开主从节点?
时间:2026-10-08 16:48 来源:未知 人气:
哈喽大家好,我是咸鱼。
在《一台服务器上部署 Redis 伪集群》这篇文章中,咸鱼在创建 Redis 集群时并没有明确指定哪个 Redis 实例将担任 master,哪个将担任 slave,然而 Redis 却自动完成了主从节点的分配工作。
如果大家在多台服务器部署过 Redis 集群的话,比如说在三台机器上部署三主三从的 redis 集群,你会观察到 Redis 自动地将主节点和从节点的部署位置错开。
举个例子:master 1 和 slave 3 在同一台机器上;master 2和 slave 1 在同一台机器上;master 3 和 slave 2 在同一台机器上,这是为什么呢?
我们知道老版本的 Redis 集群管理命令是 redis-trib.rb,新版本则换成了 redis-cli,这两个可执行文件其实是一个用 C 编写的脚本,小伙伴们如果看过这两个文件的源码就会发现原因就在下面这段代码里:
通过注释我们可以得知,clusterManagerGetAntiAffinityScore 函数是用来计算反亲和性得分,这个得分表示了当前 Redis 集群布局中是否符合反亲和性的要求,反亲和性指的是 master 和 slave 不应该在同一台机器上,也不应该在相同的 IP 地址上,那如何计算反亲和性得分呢?
- 如果有多个 slave 与同一个 master 在相同的 IP 地址上,那么对于每个这样的 slave,得分增加 10000
- 如果有多个 slave 在相同的 IP 地址上,但它们彼此之间不是同一个 master,那么对于每个这样的 slave,得分增加 1
- 最终得分是上述两部分得分之和。
也就是说,得分越高,亲和性越高;得分越低,反亲和性越高;得分为零表示完全符合反亲和性的要求。
获得得分之后,就会对得分高(反亲和性低)的节点进行优化。
为了让 Redis 主从之间的反亲和性更高,clusterManagerOptimizeAntiAffinity 函数会对那些反亲和性很低的节点进行优化,它会尝试通过交换从节点的主节点,来改善集群中主从节点分布,从而减少反亲和性低问题。
接下来我们分别来看下这两个函数:
反亲和性得分计算
可以看到,该函数接受了四个参数:
- ipnodes:一个包含多个clusterManagerNodeArray结构体的数组,每个结构体表示一个 IP 地址上的节点数组
- ip_count:IP 地址的总数
- offending:用于存储违反反亲和性规则的节点的指针数组(可选参数)
- offending_len:存储offending数组中节点数量的指针(可选参数)