Redis 集群会出现脑裂问题吗?
- 标签:后端、Redis
🏛 业务架构师
会。脑裂的场景:主节点与从节点、哨兵之间网络分区,哨兵判定主挂了完成故障转移,旧主还活着并继续接收客户端写入——此刻两个节点同时可写,分区恢复后旧主降级、这段时间的写入整段丢失。
业务后果我按真实场景算:分区 30 秒里旧主写入了 800 个 key 的订单缓存更新,恢复后这些更新蒸发,缓存与数据库不一致,用户看到"已支付"又变"待支付";如果 Redis 上还扛着计数器、去重标记,错账和重复发券就是资损。
防护配置是我的必查项:
min-slaves-to-write 1
min-slaves-to-write-lag 10主节点发现健康从库数量不足就拒绝写入——用"牺牲分区期间的可用性"换"不会双写"。这是典型的 CAP 取舍:Redis 场景宁可短暂拒绝服务(客户端降级读 DB、稍后重试),也不能接受静默丢数据。
引申到架构原则:任何带主从复制的系统都要回答"怎么防旧主复活"——MySQL 半同步、Kafka 的 fencing epoch、ZK 的 zxid,思路同源:给"领导权"一个可验证的纪元编号。我在评审缓存架构时一定会问这一句,答不上来的方案,脑裂就是它未来的故障报告。
🏗 系统架构师
会。经典场景:主从切换瞬间,旧主没真正下线(网络分区或自身卡顿),继续接受写入;哨兵已把从提升为新主,分区恢复后旧主被降级、期间写入的数据丢失或被覆盖。这就是脑裂——同一时刻两个节点都认为自己是主。
Redis 哨兵的应对:
- 哨兵要求多数派(quorum + majority)授权才能 failover,防哨兵侧脑裂;
- 主节点可配
min-replicas-to-write N+min-replicas-max-lag T:从库存活不足 N 个或延迟超 T 秒时主拒绝写入,旧主失联后写不进数据,丢数据窗口被压缩到秒级。
我的生产配置思路:
- 哨兵至少 3 节点奇数部署,跨机房/可用区分散,quorum 设多数派;
- min-replicas-to-write 设 1,牺牲分区期间旧主可用性保数据不丢(CAP 里选 CP 语义);
- 客户端必须实现订阅 +switch-master 事件刷新连接拓扑,否则切换后持续打到旧主报错;
- 极端一致性场景不靠 Redis 主从而用 Redis 加分布式锁/日志型存储兜底。
脑裂是所有主从架构的通病,解法永远是"多数派裁决 + 失联侧自禁写"。
💻 全栈开发专家
会。典型场景:主从之间网络抖动,哨兵/集群判定超时触发故障转移,旧 master 还活着并继续接收客户端写入;从库提升为新 master 后旧主被降级,重连时那段写入直接被清掉——这就是脑裂丢数据。
防线配置(写 master 侧):
text
min-replicas-to-write 1 # 至少 1 个从库在同步
min-replicas-max-lag 10 # 从库延迟不超过 10s
# 两个条件不满足时,master 拒绝写入(返回错误)这样旧主在从库全部失联时会自杀写入,窗口缩短到秒级。代价:网络抖动时可用性下降(写报错),要根据业务在"丢数据"和"可写"之间取舍——我做交易系统时宁可拒写。
客户端侧配合:捕获 NOREPLICAS/MASTERDOWN 错误降级重试;等待故障转移完成(订阅 +switch-master)再恢复写。
引申(加分):cluster 的 cluster-node-timeout 判定和 gossip 传播也有类似窗口;Redis 官方 asynchronous replication 本质是异步复制,不存在绝对不丢,真正强一致要求的数据(账户余额扣减的最终裁定)我都会落 DB,Redis 只做加速层。