脑裂确认需直接执行cluster nodes或INFO replication命令:若哨兵模式下SENTINEL masters返回多个num-slaves为0的master,或任意节点ROLE显示两个master且connected_slaves均非零,或master_repl_offset显示旧主显著高于新主,则基本坐实脑裂。

脑裂发生后,数据丢失已经不可逆,补救的核心不是“恢复旧主上的写入”,而是快速识别、隔离、止损,并在可控范围内重建一致性——旧主上未同步的写操作注定消失,你只能决定哪些数据能被保留。
如何确认当前是否已发生脑裂
不要依赖日志或猜测,直接用 redis-cli 连上所有节点执行 cluster nodes(集群模式)或 INFO replication(哨兵模式),重点看:
- 哨兵模式下,执行
SENTINEL masters,若返回多个num-slaves为 0 的 master 状态节点,极可能已双主 - 任意节点执行
ROLE,若出现两个节点都返回master,且各自connected_slaves非零,基本坐实脑裂 - 对比各节点的
master_repl_offset:若旧主的 offset 显著高于新主,说明它在分区期间持续接收写入——这些数据即将被清空
脑裂刚暴露时必须立即做的三件事
此时网络通常已恢复,但旧主尚未自动降级,新主也未完成全量同步,窗口期极短(几十秒到几分钟):
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 暂停所有客户端对 Redis 的写请求(通过应用层开关、LB 摘除、或临时封禁旧主 IP 的 6379 端口)
- 用
redis-cli -h <old_master_ip> -p 6379 CONFIG SET stop-writes-on-bgsave-error yes</old_master_ip>强制旧主拒绝新写入(防止同步过程中又写入) - 立刻备份旧主内存数据:
redis-cli -h <old_master_ip> -p 6379 BGSAVE</old_master_ip>,然后从dir路径拷出最新 RDB 文件——这是你唯一能抢救的“脏数据”
旧主降级前能否人工保留它的增量数据
不能直接保留,但可折中提取关键字段。旧主一旦执行 SLAVEOF <new_master_ip> 6379</new_master_ip>,就会触发 flushall + 全量加载,原有数据彻底覆盖。可行路径只有:
- 在旧主仍为 master 且未开始同步前,用
redis-cli --scan --pattern "*"扫描键,配合GET/HGETALL等命令导出变更集(仅适用于数据量小、key 结构清晰的场景) - 若业务有 binlog 或操作日志,比对旧主 RDB 中缺失的 key,用日志补全(需提前有该机制)
- 对支付、订单类强一致性场景,必须回查上游系统(如 MySQL 订单表)做最终状态对账,Redis 只作为最终一致的缓存层
为什么 min-slaves-to-write 无法挽救已发生的脑裂
这个配置只在脑裂“发生前”起作用。它要求主节点写入前检查健康从节点数和延迟,但前提是哨兵未触发切换。一旦哨兵因网络抖动判定主节点失联并完成选举,旧主就脱离了哨兵监管,min-slaves-to-write 规则不再生效——它防不住假故障,只限制“还在线但同步异常”的主节点继续写入。
真正起作用的是部署前的预防:把 min-slaves-to-write 设为至少 2,min-slaves-max-lag 控制在 5 秒内,并确保哨兵部署跨物理机架/可用区。脑裂补救永远慢于预防,而线上最常被忽略的,是压测时从未模拟过“主节点 CPU 打满但进程存活”的假故障场景。

















