在拒绝连接时不重新加载集群状态
作者: bjorngylling创建于 2026年8月21日更新于 2026年8月29日
□ 预期行为
鉴于集群中一个主节点被关闭并被"奴隶"成为了主节点,当集群客户端试图从旧主节点上得到密钥时,客户端应当对网络出错作出反应并针对新主节点重试获取命令.
□ 当前的行为
鉴于集群中一个主节点被关闭并被奴隶变成主,当集群客户端试图从旧主节点上得到一个密钥时,它会继续针对旧主端的连接尝试,直到集群状态再加载Interval通过. 由于v9.22将默认值从10s调整到60s,这种情况变得更加棘手.
□ 可能的解决方案
在网络错误上立即或在很短的时间内重新装入集群状态? 我不确定,但鉴于集群已经意识到并且改变了主节点,但客户端在相当一段时间内拒绝调整,所以当前的行为似乎是一个错误.
□ 步骤重现
- 运行中的Redis集群
- 一个带有默认配置的去Redis集群客户端
- 设置密钥的值
- 向奴隶发放一个CLUSTER FAILOVER TOUGOVER,配上那个关键插槽,使其成为主人. 这样做是为了避免集群-节点超时延迟,我们当然可以跳过这个步骤来更好地模拟一个不受控制的节点故障,但这在组合中增加了另一个时点(集群-节点超时).
- 关闭那个键位的旧主节点
- 尝试获取密钥, go-Redis客户端将被拒绝连接, 重试三次, 然后放弃
通过将MaxRedivisions提升到高值(我用了100),可以使客户端重试连接直到成功. 如果我在上面第六步用 MaxRedistress=100 给指令时间 62秒后就能成功 如果我重新运行 假设,但我设置 Cluster State Reload Interval 到 10 秒 , 11 秒后成功。
□ 背景(环境)
这种行为使客户端对集群中的变化反应不合理缓慢,并随着v9.22中的默认配置变化而变得更加糟糕. 也许我们可以把集群国重装Interval设置到非常低的值,但我怀疑这会导致很多正常操作时不必要的状态重装?
内容来源: redis/go-redis