33 Redis 主从集群中脑裂问题

33 Redis 主从集群中脑裂问题文章目录前言一 为什么会发生脑裂 二 为什么脑裂会导致数据丢失 三 如何应对脑裂问题 总结前言在使用主从集群时 主从集群有 1 个主库 5 个从库和 3 个哨兵实例 在使用的过程中 发现客户端发送的一些数据丢失了 这直接影响到了业务层的数据可靠性 这其实是主从集群中的脑裂问题导致的 脑裂是指在主从集群中 同时有两个主节点 它们都能接收写请求 而脑裂最直接的影响 是客户端不知道应该往哪个主节点写入数据 结果就是不同的客户端会往不同的主节点上写入数据 而且严重的话 脑裂会进一步导致数据丢失 一 为什


前言

在使用主从集群时,主从集群有 1 个主库、5 个从库和 3 个哨兵实例,在使用的过程中,发现客户端发送的一些数据丢失了,这直接影响到了业务层的数据可靠性。

这其实是主从集群中的脑裂问题导致的。脑裂是指在主从集群中,同时有两个主节点,它们都能接收写请求。而脑裂最直接的影响,是客户端不知道应该往哪个主节点写入数据,结果就是不同的客户端会往不同的主节点上写入数据。而且严重的话,脑裂会进一步导致数据丢失。

一、为什么会发生脑裂?

第一步:确认是不是数据同步出现了问题

在主从集群中发生数据丢失,最常见的原因就是主库的数据还没有同步到从库,结果主库发生了故障,等从库升级为主库后,未同步的数据就丢失了。

在部署主从集群时,也监测了主库上的 master_repl_offset,以及从库上的 slave_repl_offset。但是当发现数据丢失后,检查了新主库升级前的 slave_repl_offset,以及原主库的 master_repl_offset,它们是一致的,这个升级为新主库的从库,在升级时已经和原主库的数据保持一致了。

第二步:排查客户端的操作日志,发现脑裂现象

在排查客户端的操作日志时,发现在主从切换后的一段时间内,有一个客户端仍然在和原主库通信,并没有和升级的新主库进行交互。这就相当于主从集群中同时有了两个主库。根据这个迹象想到了在分布式主从集群发生故障时会出现的一个问题:脑裂。

但是不同客户端给两个主库发送数据写操作,按道理来说只会导致新数据会分布在不同的主库上,并不会造成数据丢失。那么为什么数据仍然丢失了呢?脑裂是发生在主从切换的过程中,猜测是漏掉了主从集群切换过程中的某个环节。

第三步:发现是原主库假故障导致的脑裂

采用哨兵机制进行主从切换的,当主从切换发生时,一定是有超过预设数量 (quorum 配置项)的哨兵实例和主库的心跳都超时了,才会把主库判断为客观下线,然后哨兵开始执行切换操作。哨兵切换完成后,客户端会和新主库进行通信,发送请求操作。

但是在切换过程中,既然客户端仍然和原主库通信,表明原主库并没有真的发生故障(例如主库进程挂掉)。猜测主库是由于某些原因无法处理请求,也没有响应哨兵的心跳,才被哨兵错误地判断为客观下线的。结果在被判断下线之后,原主库又重新开始处理请求了,而此时哨兵还没有完成主从切换,客户端仍然可以和原主库通信, 客户端发送的写操作就会在原主库上写入数据了。

为了验证原主库只是“假故障”,查看了原主库所在服务器的资源使用监控记录。看到原主库所在的机器有一段时间的 CPU 利用率突然特别高,这是在机器上部署的一个数据采集程序导致的。因为这个程序基本把机器的 CPU 都用满了,导致 Redis 主库无法响应心跳了,在这个期间内,哨兵就把主库判断为客观下线,开始主从切换了。不过这个数据采集程序很快恢复正常,CPU 的使用率也降下来了。此时原主库又开始正常服务请求了。

正因为原主库并没有真的发生故障,在客户端操作日志中就看到了和原主库的通信记录。等到从库被升级为新主库后,主从集群里就有两个主库了,就把脑裂发生的原因摸清楚了。

二、为什么脑裂会导致数据丢失?

主从切换后,从库一旦升级为新主库,哨兵就会让原主库执行 slave of 命令,和新主库重新进行全量同步。而在全量同步执行的最后阶段,原主库需要清空本地的数据,加载新主库发送的 RDB 文件,原主库在主从切换期间保存的新写数据就丢失了。

在主从切换的过程中,如果原主库只是“假故障”,它会触发哨兵启动主从切换,等它从假故障中恢复后,又开始处理请求,就会和新主库同时存在,形成脑裂。 等到哨兵让原主库和新主库做全量同步后,原主库在切换期间保存的数据就丢失了。

三、如何应对脑裂问题?

主从集群中的数据丢失事件,归根结底是因为发生了脑裂。所以要找到应对脑裂问题的策略。 既然问题是出在原主库发生假故障后仍然能接收请求上,就开始在主从集群机制的配置项中查找是否有限制主库接收请求的设置。

Redis 提供了两个配置项来限制主库的请求处理,分别是 min- slaves-to-write 和 min-slaves-max-lag:

  • min-slaves-to-write:设置了主库能进行数据同步的最少从库数量;
  • min-slaves-max-lag:设置了主从库间进行数据复制时,从库给主库发送 ACK 消息的最大延迟(以秒为单位)。

min-slaves-to-write 和 min-slaves-max-lag 这两个配置项搭配起来使用, 分别给它们设置一定的阈值,假设为 N 和 T。这两个配置项组合后的要求是,主库连接的从库中至少有 N 个从库,和主库进行数据复制时的 ACK 消息延迟不能超过 T 秒,否则主库就不会再接收客户端的请求了。

即使原主库是假故障,它在假故障期间也无法响应哨兵心跳,也不能和从库进行同步,自然也就无法和从库进行 ACK 确认了。min-slaves-to-write 和 min-slaves- max-lag 的组合要求就无法得到满足,原主库就会被限制接收客户端请求,客户端也就不能在原主库中写入新数据了。

等到新主库上线时,就只有新主库能接收和处理客户端请求,新写的数据会被直接写到新主库中。而原主库会被哨兵降为从库,即使它的数据被清空了,也不会有新数据丢失。

假设将 min-slaves-to-write 设置为 1,把 min-slaves-max-lag 设置为 12s,把哨兵的 down-after-milliseconds 设置为 10s,主库因为某些原因卡住了 15s,导致哨兵判断主库客观下线,开始进行主从切换。同时因为原主库卡住了 15s,没有一个从库能和原主库在 12s 内进行数据复制,原主库也无法接收客户端请求了。这样主从切换完成 后,也只有新主库能接收请求,不会发生脑裂,也就不会发生数据丢失的问题了。

总结

主从切换时可能遇到的脑裂问题,脑裂是指在主从集群中,同时有两个主库都能接收写请求。在 Redis 的主从切换过程中,如果发生了脑裂,客户端数据就会写入到原主库,如果原主库被降为从库,这些新写入的数据就丢失了。

脑裂发生的原因主要是原主库发生了假故障,假故障的两个原因:

  1. 和主库部署在同一台服务器上的其他程序临时占用了大量资源(例如 CPU 资源),导致主库资源使用受限,短时间内无法响应心跳。其它程序不再使用资源时,主库又恢复正常。
  2. 主库自身遇到了阻塞的情况,例如,处理 bigkey 或是发生内存 swap,短时间内无法响应心跳,等主库阻塞解除后,又恢复正常的请求处理了。

为了应对脑裂可以在主从集群部署时,通过合理地配置参数 min-slaves-to-write 和 min-slaves-max-lag,来预防脑裂的发生。

在实际应用中,可能会因为网络暂时拥塞导致从库暂时和主库的 ACK 消息超时。并不是主库假故障,不用禁止主库接收请求。建议是假设从库有 K 个,可以将 min-slaves-to-write 设置为 K/2+1(如果 K 等于 1,就设为 1),将 min-slaves-max-lag 设置为十几秒(例如 10~ 20s),在这个配置下,如果有一半以上的从库和主库进行的 ACK 消息延迟超过十几秒, 就禁止主库接收客户端写请求。可以避免脑裂带来数据丢失的情况,而且也不会因为只有少数几个从库因为网络阻塞连不上主库,就禁止主库接收请求。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/210787.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午11:55
下一篇 2026年3月18日 下午11:55


相关推荐

  • SSM整合(基于XML配置方式)

    SSM整合(基于XML配置方式)我们整合SSM框架时,大部分都是基于注解+XML配置方式。只因为结合这两种方法能够实现同样的效果,而且会更加的轻松。所以在此推荐朋友们用注解+XML配置的方式,基于注解+XML配置方式会另写一篇。但是有朋友和我说,怎么用纯XML方式整合SSM呢?我做了一个入门的整理,如果不足,请多多指教。本文是基于XML配置方式整合SSM框架,由于本人不太推荐这种方式。首先可以看一下完整的目录结构…

    2022年5月11日
    57
  • ITDSD- 3.分布式工程学综述

    ITDSD- 3.分布式工程学综述英文版地址:ITDSD-3.OverviewofDistributedEngineeringSunshuo(sun.shuo@aliyun.com)导论这是关于分布式架构新手入门的第三篇文章。这一篇文章主要简要的介绍分布式工程学在理论上的基本概念,历史和现状,以及未来发展方向。让大家能够了解为什么学习分布式工程学。分布式工程学在计算机科学中的地位,以及分布式工程学要解决的问…

    2022年5月31日
    30
  • 关于Python中的lambda,这篇阅读量10万+的文章可能是你见过的最完整的讲解[通俗易懂]

    关于Python中的lambda,这篇阅读量10万+的文章可能是你见过的最完整的讲解[通俗易懂]lambda是Python编程语言中使用频率较高的一个关键字。那么,什么是lambda?它有哪些用法?网上的文章汗牛充栋,可是把这个讲透的文章却不多。这里,我们通过阅读各方资料,总结了关于Python中的lambda的“一个语法,三个特性,四个用法,一个争论”。欢迎阅读和沟通(个人微信:slxiaozju)。由于文章是从我的公众号上复制过来的,因此排版不整齐,但是内容绝对充实,欢迎关注公众…

    2022年8月12日
    9
  • 04边界值分析法

    04边界值分析法04 边界值分析法 1 边界值分析法的介绍和概念 边界值分析是一种常用的黑盒测试方法 是对等价类划分方法的补充 所谓边界值 是指相对于输入等价类和输出等价类而言 稍高于其最高值或稍低于最低值的一些特定情况 边界值分析的步骤包括确定边界 选择测试用例两个步骤 根据大量的测试统计数据 很多错误是发生在输入或输出范围的边界上 而不是发生在输入 输出范围的中间区域 因此针对各种边界情况

    2026年3月18日
    2
  • 基于Bitdeer AI Cloud 上安装与配置 OpenClaw指南

    基于Bitdeer AI Cloud 上安装与配置 OpenClaw指南

    2026年3月13日
    3
  • MetaMask以太坊钱包

    MetaMask以太坊钱包MetaMask 文档 https docs metamask io guide ethereum provider htmlMetaMask 下载 https metamask io download html 连接 MetaMaskimpo react exportdefaul constconnect gt 判断用户是否安装 MetaMask 钱包插件

    2026年3月18日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号