什么是 Redis 集群脑裂问题,怎么解决?

一则或许对你有用的小广告

欢迎 加入小哈的星球 ,你将获得: 专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目: 《Spring AI 项目实战(问答机器人、RAG 增强检索、联网搜索)》 正在持续爆肝中,基于 Spring AI + Spring Boot3.x + JDK 21...点击查看;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot3.x + JDK 17...点击查看项目介绍; 演示链接: http://116.62.199.48:7070/;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/

面试考察点

  1. 问题识别能力:面试官不仅仅是想知道 "脑裂" 这个名词,更是想知道你是否能从 网络分区 的角度理解脑裂的产生原因,以及脑裂为什么会带来 数据丢失数据不一致 的严重后果。

  2. 原理理解深度:考察你是否了解哨兵模式和 Cluster 模式下脑裂的具体触发机制(主观下线 → 客观下线 → 故障转移),以及旧 Master 在被隔离期间仍然接受写入的危害。

  3. 方案落地能力:能否给出具体的配置参数(如 min-slaves-to-writemin-slaves-max-lag)和最佳实践,而不是只停留在 "避免脑裂" 的概念层面。

核心答案

脑裂(Split Brain) 是指 Redis 集群中,由于 网络分区 导致出现了 两个 Master 同时接受写入的情况。

维度说明
产生原因网络分区导致哨兵/Cluster 认为旧 Master 宕机,选举出新 Master,但旧 Master 实际还在运行
核心危害客户端同时向新旧两个 Master 写入数据,导致数据冲突和丢失
发生场景哨兵模式、Cluster 模式都可能发生
核心解法配置 min-slaves-to-write + min-slaves-max-lag,让 Master 在从节点不足时 拒绝写入

一句话结论:脑裂的本质是网络分区导致 "一主变两主",解决思路是让旧 Master 在与从节点失联后 主动拒绝写入,从源头切断数据不一致的可能。

深度解析

一、脑裂是怎么发生的?

上图展示了脑裂的完整产生过程:

  • 正常状态:Sentinel 集群正常监控 Master 和 Slave,一切运行正常。
  • 网络分区发生:假设网络出现故障,将 Master 和 Sentinel S1 分在一个分区,Slave 和 Sentinel S3 分在另一个分区。两个分区之间无法通信。
  • 分区 B 的动作:Sentinel S3 发现 Master 不可达,认为 Master 宕机了。S3 联合其他 Sentinel(如果有足够 quorum)执行故障转移,将 Slave 晋升为新 Master。此时分区 B 的客户端开始向新 Master 写入数据。
  • 分区 A 的问题:旧 Master 实际上还活着,分区 A 的客户端仍然在向旧 Master 写入数据。
  • 网络恢复后:旧 Master 发现自己被替代,降级为新 Master 的 Slave,触发全量同步。在旧 Master 上写入的数据 A 会全部丢失!

二、脑裂的危害

上图总结了脑裂的三大危害:

  • 数据丢失(最严重):网络恢复后,旧 Master 被降级为 Slave,会清空自身数据并从新 Master 全量同步。脑裂期间写入旧 Master 的所有数据都会 不可逆地丢失
  • 数据不一致:同一个 Key 可能被不同客户端分别写入新旧 Master,最终以新 Master 的数据为准,旧数据被覆盖。
  • 客户端混乱:不同客户端连接到不同 Master,读到不一致的数据,业务逻辑出错。

三、解决方案

方案一:配置 min-slaves-to-write + min-slaves-max-lag(最核心)

这是 Redis 官方推荐的最主要解决方案,核心思想是:让 Master 在从节点不可达时主动拒绝写入

上图展示了 min-slaves-to-write + min-slaves-max-lag 的防护原理:

  • 配置含义min-slaves-to-write 1 表示 Master 至少要有 1 个可用的 Slave 连接才能接受写入;min-slaves-max-lag 10 表示 Slave 的复制延迟不能超过 10 秒。两个条件必须 同时满足,Master 才会接受写入请求。
  • 脑裂时的防护:网络分区后,旧 Master 联系不上 Slave,不满足 min-slaves-to-write 条件,主动拒绝所有写入,返回 NOREPLICAS 错误。这样客户端无法向旧 Master 写入数据,网络恢复后就不会有数据丢失。
  • 效果:确保任意时刻只有一个 Master 能接受写入,从根本上避免了脑裂。

配置示例redis.conf):

# Master 至少需要 1 个 Slave 连接才能写入
min-slaves-to-write 1

# Slave 的复制延迟不能超过 10 秒
min-slaves-max-lag 10

方案二:合理配置 Sentinel 参数

上图展示了通过 Sentinel 参数调优来降低脑裂概率:

  • 增大 down-after-milliseconds:超时时间越长,Sentinel 越不容易因为短暂的网络抖动而误判 Master 宕机。但代价是故障恢复变慢,需要在 灵敏度稳定性 之间权衡。
  • 合理设置 quorum:quorum 值越大,需要越多的 Sentinel 同意才能判定客观下线,误判概率越小。一般建议 ≥ 2。
  • Sentinel 分部署部署:不要把所有 Sentinel 放在同一台机器或同一机架上,避免单点网络故障导致大面积误判。
  • 核心思路:降低 Sentinel 的误判概率,就能降低脑裂的发生概率。

方案三:Cluster 模式下的防护

上图展示了 Cluster 模式下的脑裂防护手段:

  • cluster-node-timeout:控制节点超时判定时间,适当调大可以减少网络抖动导致的误判。
  • cluster-require-full-coverage yes(默认):只要有任何一个 slot 不可用,整个集群停止服务。这在脑裂场景下反而是一种保护——集群直接拒绝写入,避免数据不一致,但代价是牺牲了可用性。
  • min-slaves-to-write:Cluster 中的每个 Master 节点同样支持这个配置,效果和哨兵模式一样。

四、方案对比与最佳实践

上图对比了各方案的优缺点和最佳实践:

  • min-slaves-to-write + min-slaves-max-lag最核心、必须配置 的方案。它从源头阻止了旧 Master 继续接受写入,是解决脑裂的根本手段。
  • 其他方案(调大超时、增大 quorum)是辅助手段,用于 降低脑裂的发生概率
  • 生产环境建议组合使用:必配 min-slaves-to-write + min-slaves-max-lag,同时合理设置 Sentinel 的超时和 quorum 参数,并将节点分散部署到不同机房/机架。

五、如何检测脑裂是否发生?

上图展示了脑裂的检测手段:

  • 监控 Sentinel 日志:关注 +sdown+odown 事件,频繁的主客观下线可能意味着网络不稳定,脑裂风险增加。
  • 监控复制偏移量:通过 INFO replication 命令查看 Master 和 Slave 的 replication offset 差距,差距过大说明复制延迟严重。
  • 监控 Master 切换事件:关注 +switch-master 事件,短时间内多次切换可能是脑裂的信号。
  • 监控连接的 Slave 数量connected_slaves 突然变为 0 说明网络可能已经分区。

面试高频追问

  1. 追问一:min-slaves-to-write 设为多少合适?

    一般设为 1 即可(至少 1 个 Slave 连接才能写)。如果对数据安全性要求极高,可以设为 2,但会降低可用性(任意一个 Slave 挂了,Master 就拒绝写入)。min-slaves-max-lag 一般设为 10 秒,根据网络状况调整。

  2. 追问二:脑裂和 Sentinel 的 "主观下线 → 客观下线" 有什么关系?

    脑裂的触发就是从 Sentinel 的主观下线开始的。网络分区后,分区 B 的 Sentinel 联系不上 Master,先标记主观下线,再联合其他 Sentinel 标记客观下线,然后触发故障转移。如果这个过程中是 误判(Master 实际还活着),就会产生脑裂。所以调大超时时间和 quorum 可以减少误判。

  3. 追问三:CAP 理论和 Redis 脑裂的关系?

    脑裂本质是 CP vs AP 的取舍。Redis 选择的是 AP(可用性优先)——故障转移后新 Master 立即服务,不等待旧 Master 的数据同步。配置 min-slaves-to-write 是在向 CP(一致性优先) 倾斜——宁可牺牲可用性(拒绝写入),也要保证数据一致性。这是一个工程上的权衡。

常见面试变体

  • 变体一:"Redis 哨兵模式下网络分区会导致什么问题?"
  • 变体二:"如何保证 Redis 主从切换时不丢数据?"
  • 变体三:"Redis 的 min-slaves-to-write 参数有什么作用?"
  • 变体四:"Redis 集群中出现两个 Master 怎么办?"

记忆口诀

脑裂原因:网络分区 → 哨兵误判 → 新旧两主同时写 → 数据丢失。

核心解法min-slaves-to-write + min-slaves-max-lag,从节点不够就不让写。

辅助手段:调大超时、增大 quorum、分散部署、监控告警。

本质:CP 和 AP 的权衡,Redis 默认偏向 AP,配置后向 CP 倾斜。

总结

Redis 脑裂是网络分区导致出现两个 Master 同时接受写入的问题,网络恢复后旧 Master 降级为 Slave 会导致数据丢失。最核心的解决方案 是配置 min-slaves-to-write + min-slaves-max-lag,让 Master 在从节点不可达时主动拒绝写入。辅助手段包括调大 Sentinel 超时时间、增大 quorum 值、分散部署 Sentinel 节点,以及建立完善的监控告警机制。