Redis 集群脑裂(Split-Brain)详解与解决方案
1. 什么是 Redis 集群脑裂?
Redis 脑裂(Split-Brain) 指的是 由于网络分区(Network Partition)或其他原因,导致同一个 Redis 集群的多个 Master 失去同步和一致性,从而可能出现:
- 多个 Master 认为自己是主节点,但它们的数据可能不一致。
- 不同的客户端连接到不同的 Master,导致读取或写入不同的数据版本。
- 主从切换后,旧 Master 恢复后仍以 Master 身份运行,导致数据丢失或数据冲突。
2. Redis 脑裂的触发场景
Redis 脑裂通常发生在 分布式环境 下,主要触发原因包括:
(1)网络分区(Network Partition)
- 由于 网络故障,Redis 节点之间无法正常通信。
- 例如,Redis Cluster 的 Master 与 Slave 之间的网络中断,导致 Slave 误判 Master 宕机,并自行选举新的 Master。
(2)Redis Sentinel 误判
- Redis Sentinel 模式 依赖于 多个 Sentinel 进行投票 判断 Master 是否宕机。
- 若 部分 Sentinel 由于网络抖动误判 Master 宕机,就可能选举出新的 Master,而原 Master 仍然认为自己正常工作,从而导致 多个 Master 并存。
(3)主从切换异常
- 旧 Master 在宕机恢复后,仍然认为自己是 Master,但新 Master 已经产生了新的数据,从而导致数据不一致。
(4)集群分裂
- 如果 多个 Redis Cluster 由于网络问题变成两个孤立的子集群,那么这两个子集群可能会各自选举 Master,导致脑裂。
3. Redis 集群脑裂的影响
🚨 数据丢失
- 如果两个 Master 分裂,并各自写入新数据,当网络恢复后,旧 Master 被重新加入集群时,它的数据可能被覆盖或丢失。
🚨 数据不一致
- 客户端 A 连接 Master 1,写入
set key "A"
; - 客户端 B 连接 Master 2,写入
set key "B"
; - 最终,集群恢复时,两个 Master 可能有不同的数据,导致数据不一致。
🚨 客户端请求异常
- 由于某些客户端可能连接到旧 Master,而其他客户端连接到新 Master,导致数据查询不一致或部分请求失败。
4. 解决 Redis 集群脑裂问题
(1)Redis Sentinel 模式下的解决方案
🚀 方案 1:配置 quorum
和 down-after-milliseconds
quorum
:最少需要 多少个 Sentinel 认为 Master 宕机,才触发故障转移。down-after-milliseconds
:Sentinel 需要 等待多少毫秒后确认 Master 宕机。- 建议配置:
sentinel monitor mymaster 192.168.1.100 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 15000
- 至少 2 个 Sentinel 认为 Master 宕机 才进行切换,避免误判。
- Master 5 秒内无响应,Sentinel 才认为 Master 宕机。
🚀 方案 2:配置 min-replicas-to-write
和 min-replicas-max-lag
-
min-replicas-to-write
:保证至少有 N 个 Slave 存活,Master 才允许写入,防止数据丢失。 -
min-replicas-max-lag
:限制 Slave 的最大复制延迟,防止过期数据被同步。示例:
min-replicas-to-write 2 min-replicas-max-lag 10
- 至少 2 个从节点存活,Master 才能写入,防止孤立 Master 写入导致数据不一致。
🚀 方案 3:开启 protected-mode
- 避免 Redis 在 网络异常时自动成为 Master,防止脑裂。
protected-mode yes
🚀 方案 4:使用 raft
共识算法
- Redis 7.0 开始支持
raft
共识算法,可以提高一致性,避免脑裂。
(2)Redis Cluster 模式下的解决方案
🚀 方案 1:调整 cluster-node-timeout
cluster-node-timeout
控制 Master 节点与其他节点断连多久后被视为宕机。- 建议配置 10s 以上,避免误判:
cluster-node-timeout 10000
🚀 方案 2:设置 cluster-require-full-coverage
- 避免部分 Master 失联时,集群仍然提供服务,导致数据不一致。
- 建议开启:
cluster-require-full-coverage yes
🚀 方案 3:采用 Gossip 协议
进行健康检查
- Redis Cluster 通过 Gossip 协议 让所有节点互相检测健康状态。
- 如果 Master 失联,其他 Master 需要达成共识(majority votes)才能选举新 Master,避免脑裂。
🚀 方案 4:定期执行 reshard
重新分配数据槽
- 通过
redis-cli --cluster reshard
重新分配hash slot
,确保数据均衡,防止部分 Master 负载过高导致宕机。
🚀 方案 5:使用 wait
命令提高数据一致性
WAIT
命令可以确保写入请求在多个从节点同步成功后再返回:WAIT 2 500
- 等待 至少 2 个 Slave 确认写入成功,最多 500ms 超时。
- 保证数据不会在 Master 失败后丢失。
🚀 方案 6:使用 Redis 代理层(如 Twemproxy、Codis)
- 代理层可以检测 Master 切换,自动调整客户端连接,减少脑裂风险。
5. Redis 脑裂问题最佳实践总结
策略 | 适用模式 | 作用 |
---|---|---|
配置 quorum + down-after-milliseconds | Sentinel | 避免误判 Master 宕机 |
min-replicas-to-write + min-replicas-max-lag | Sentinel & Cluster | 保障数据同步完整性 |
cluster-require-full-coverage | Cluster | 避免部分数据丢失 |
cluster-node-timeout | Cluster | 防止过快切换 Master |
WAIT 命令 | Cluster & Sentinel | 保证写入数据同步 |
Redis 代理(Twemproxy, Codis) | Cluster | 解决客户端访问多个 Master 问题 |
6. 总结
- Redis 脑裂主要由网络分区、误判、主从切换异常引起。
- Redis Sentinel 可通过 quorum、timeout、min-replicas-to-write 等机制避免误判。
- Redis Cluster 通过 Gossip 协议、full-coverage、WAIT 命令等机制提高一致性。
- 合理配置 Redis,避免误判 Master 宕机,使用
raft
算法或代理层增强一致性。
Redis 集群脑裂问题虽然复杂,但通过 合理配置和优化策略,可以大大降低风险 🚀🚀🚀