探究BrainSplit-集群脑裂
本篇文章将会以redis集群为例,分享在主从集群中会导致数据丢失的一个问题:BrainSplit-集群脑裂
1.什么是集群脑裂
所谓的脑裂,就是指在主从集群中,同时有两个主节点,它们都能接收写请求。而脑裂最直接的影响,就是客户端不知道应该往哪个主节点写入数据,结果就是不同的客户端会往不同的主节点上写入数据。而且,严重的话,脑裂会进一步导致数据丢失。
2.数据丢失的排查
对于排查主从集群中数据丢失的问题,通常来说我们会考虑以下两个原因:
(1) 数据同步未完成
最常见的原因就是主库的数据还没有同步到从库,结果主库发生了故障,等从库升级为主库后,未同步的数据就丢失了。
我们可以根据以下方法来排查:
比对主从库上的复制进度差值来进行判断,也就是计算 master_repl_offset和 slave_repl_offset 的差值。
如果从节点的偏移量(slave_repl_offset)小于主节点的偏移量(master_repl_offset),那么我们可以认定数据丢失是由于数据同步未完成导致的;如果从节点的偏移量(slave_repl_offset)等于主节点的偏移量(master_repl_offset),那么我们有理由怀疑很可能是由于原主库假故障导致的集群脑裂造成的。
为了直观表示这一关系,我用以下的伪代码形式来描述:
if(slave_repl_offset < master_repl_offset){
//认定数据丢失是由数据同步未完成导致的。
}else if(slave_repl_offset == master_repl_offset){
//集群脑裂
}
(2) 集群脑裂
在哨兵机制将主库判断为客观下线后,哨兵开始执行切换操作,客户端与新主库通信,但是切换过程中,客户端仍然和原主库通信,这就表明原主库并没有真的发生故障。正因为原主库并没有真的发生故障,我们在客户端操作日志中就看到了和原主库的通信记录。等到从库被升级为新主库后,主从集群里就有两个主库了。
主库为什么会出现假故障?
1.和主库部署在同一台服务器上的其他程序临时占用了大量资源(例如 CPU 资源),导致主库资源使用受限,短时间内无法响应心跳。其它程序不再使用资源时,主库又恢复正常。
2.主库自身遇到了阻塞的情况,例如,处理 bigkey 或是发生内存 swap,短时间内无法响应心跳,等主库阻塞解除后,又恢复正常的请求处理了。
接下来我们来讨论一下__bigkey删除导致的阻塞:
删除操作的本质是要释放键值对占用的内存空间。释放内存只是第一步,为了更高效地管理内存空间,在应用程序释放内存时,操作系统需要把释放掉的内存块插入一个空闲内存块的链表,以便后续进行管理和再分配。这个过程本身需要一定时间,而且会阻塞当前释放内存的应用程序,所以,如果一下子释放了大量内存,空闲内存块链表操作时间就会增加,相应地就会造成 Redis 主线程的阻塞。
3.脑裂是如何导致数据丢失的
当主库出现假故障时,哨兵将主库判断为客观下线,从库升级为新的主库,但是当主库恢复后,客户端仍然可以给恢复后的主库中写入新数据,此时从库已经升级为主库了
4.脑裂问题如何解决
对于redis的主从集群来说,修改配置项就可以了:
min-slaves-to-write:这个配置项设置了主库能进行数据同步的最少从库数量;
min-slaves-max-lag:这个配置项设置了主从库间进行数据复制时,从库给主库发送ACK 消息的最大延迟(以秒为单位)。
这两个配置项组合后的要求是:主库连接的从库中至少有 N 个从库,和主库进行数据复制时的 ACK 消息延迟不能超过 T 秒,否则,主库就不会再接收客户端的请求,即使原主库是假故障,它在假故障期间也无法响应哨兵心跳,也不能和从库进行同步,自然也就无法和从库进行 ACK 确认了。
这样一来,_min-slaves-to-write _和 _min-slaves-max-lag _的组合要求就无法得到满足,原主库就会被限制接收客户端请求,客户端也就不能在原主库中写入新数据了。
探究BrainSplit-集群脑裂的更多相关文章
- Zookeeper集群"脑裂"问题 - 运维总结
关于集群中的"脑裂"问题,之前已经在这里详细介绍过,下面重点说下Zookeeper脑裂问题的处理办法.ooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调 ...
- ZooKeeper集群“脑裂”
ZooKeeper 集群节点为什么要部署成奇数ZooKeeper 容错指的是:当宕掉几个ZooKeeper节点服务器之后,剩下的个数必须大于宕掉的个数,也就是剩下的节点服务数必须大于n/2,这样Zoo ...
- Elasticsearch部分节点不能发现集群(脑裂)问题处理
**现象描述** es1,es2,es3三台es组成一个集群,集群状态正常, 当es1 服务器重启后,es1不能加到集群中,自己选举自己为master,这就产生了es集群中所谓的“脑裂” , 把es1 ...
- 为 Raft 引入 leader lease 机制解决集群脑裂时的 stale read 问题
问题:当 raft group 发生脑裂的情况下,老的 raft leader 可能在一段时间内并不知道新的 leader 已经被选举出来,这时候客户端在老的 leader 上可能会读取出陈旧的数据( ...
- Elasticsearch之集群脑裂
https://www.cnblogs.com/zlslch/p/6477312.html
- 如何防止ElasticSearch集群出现脑裂现象(转)
原文:http://xingxiudong.com/2015/01/05/resolve-elasticsearch-split-brain/ 什么是“脑裂”现象? 由于某些节点的失效,部分节点的网络 ...
- 如何防止ElasticSearch集群出现脑裂现象
什么是“脑裂”现象? 由于某些节点的失效,部分节点的网络连接会断开,并形成一个与原集群一样名字的集群,这种情况称为集群脑裂(split-brain)现象.这个问题非常危险,因为两个新形成的集群会同时索 ...
- Zookeeper集群的"脑裂"问题处理 - 运维总结
关于集群中的"脑裂"问题,之前已经在这里详细介绍过,下面重点说下Zookeeper脑裂问题的处理办法.ooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调 ...
- 【Redis集群原理专题】分析一下相关的Redis集群模式下的脑裂问题!
技术格言 世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程. 什么是脑裂 字面含义 首先,脑裂从字面上理解就是脑袋裂开了,就是思想分家了,就是有了两个山头,就是有了 ...
- Elasticsearch学习总结 (Centos7下Elasticsearch集群部署记录)
一. ElasticSearch简单介绍 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticse ...
随机推荐
- P 算法与 K 算法
P 算法与 K 算法 作者:Grey 原文地址: 博客园:P 算法与 K 算法 CSDN:P 算法与 K 算法 说明 P 算法和 K 算法主要用来解决最小生成树问题,即:不破坏连通性删掉某些边,使得整 ...
- 这才是使用ps命令的正确姿势
这才是使用ps命令的正确姿势 前言 在linux系统当中我们通常会使用命令去查看一些系统的进程信息,我们最常使用的就是 ps (process status).ps 命令主要是用于查看当前正在运行的程 ...
- Java多线程(4):ThreadLocal
您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 为了提高CPU的利用率,工程师们创造了多线程.但是线程们说:要有光!(为了减少线程创建(T1启动)和销毁(T3切换)的时间),于是工程师们又接着 ...
- MyBatis笔记03------XXXMapper.xml文件解析
SQL映射文件的配置解析 当我们写好mapper(dao)层接口时,然后在对应的XXXMapper.xml文件中写业务逻辑对应的SQL映射语句,通过这个文件中可以实现CRU操作,那么下面说明如何编写这 ...
- java学习之IO流
java io流有四大家族分别是: 1.InputStream(字节输入流) 2.OutputStream(字节输入出流)3.Reader(字符输入流)4.Writer(字符输出流)四个类都是抽象类 ...
- 小巧快速的ZooKeeper可视化管理+实时监控工具
Zookeeper: 是一个分布式的.开源的程序协调服务,是 hadoop 项目下的一个子项目.他提供的主要功 能包括:配置管理.名字服务.分布式锁.集群管理. 平时用zkCli.sh进行管理不免有点 ...
- Go语言核心36讲06
我已经为你打开了Go语言编程之门,并向你展示了"程序从初建到拆分,再到模块化"的基本演化路径. 一个编程老手让程序完成基本演化,可能也就需要几十分钟甚至十几分钟,因为他们一开始就会 ...
- (C++) C++虚函数性能分析
class baseA { public: virtual float mulTwo(float a, float b) = 0; virtual ~baseA() = default; }; cla ...
- 关于python统计一个列表中每个元素出现的频率
第一种写法: a = ['h','h','e','a','a'] result = {} for i in a: if i not in result: result[i] = 1 else: res ...
- Python: 你所不知道的星号 * 用法
以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「englyf」https://mp.weixin.qq.com/s/FHyosiG_tegF5NRUEs7UdA 本文大概 1193 个 ...