关于集群中的"脑裂"问题,不清楚的可以看这里(https://www.cnblogs.com/kevingrace/p/7205846.html),下面重点说下 Zookeeper 脑裂问题的处理办法。ZooKeeper 是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调内核,用户可以在此之上构建更多复杂的分布式协调功能。脑裂通常会出现在集群环境中,比如 ElasticSearch、Zookeeper 集群,而这些集群环境有一个统一的特点,就是它们有一个大脑,比如 ElasticSearch 集群中有 Master 节点,Zookeeper 集群中有 Leader 节点。

一 Zookeeper 集群节点为什么要部署成奇数
zookeeper 容错指的是:当宕掉几个 zookeeper 节点服务器之后,剩下的个数必须大于宕掉的个数,也就是剩下的节点服务数必须大于 n/2,这样 zookeeper 集群才可以继续使用,无论奇偶数都可以选举 leader。例如5台 zookeeper 节点机器最多宕掉 2 台,还可以继续使用,因为剩下 3 台大于 5/2。那么为什么最好为奇数个节点呢?是在以最大容错服务器个数的条件下,会节省资源。比如,最大容错为 2 的情况下,对应的zookeeper 服务数,奇数为5,而偶数为6,也就是6个zookeeper 服务的情况下最多能宕掉2个服务,所以从节约资源的角度看,没必要部署6(偶数)个 zookeeper 服务节点。

zookeeper 集群有这样一个特性:集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的。也就是说如果有 2 个 zookeeper 节点,那么只要有1个zookeeper 节点死了,那么 zookeeper 服务就不能用了,因为1没有过半,所以2个 zookeeper 的死亡容忍度为0;同理,要是有3个 zookeeper,一个死了,还剩下2个正常的,过半了,所以3个 zookeeper 的容忍度为1;同理也可以多列举几个:2->0; 3->1; 4->1; 5->2; 6->2 就会发现一个规律,2n 和 2n-1 的容忍度是一样的,都是 n-1,所以为了更加高效,何必增加那一个不必要的 zookeeper 呢。

根据以上可以得出结论:从资源节省的角度来考虑,zookeeper 集群的节点最好要部署成奇数个!!

二  Zookeeper 集群中的"脑裂"场景说明
对于一个集群,想要提高这个集群的可用性,通常会采用多机房部署,比如现在有一个由 6 台 zkServer 所组成的一个集群,部署在了两个机房:

图1

正常情况下,此集群只会有一个 Leader,那么如果机房之间的网络断了之后,两个机房内的 zkServer 还是可以相互通信的,如果不考虑过半机制,那么就会出现每个机房内部都将选出一个 Leader。

图2

这就相当于原本一个集群,被分成了两个集群,出现了两个"大脑",这就是所谓的"脑裂"现象。对于这种情况,其实也可以看出来,原本应该是统一的一个集群对外提供服务的,现在变成了两个集群同时对外提供服务,如果过了一会,断了的网络突然联通了,那么此时就会出现问题了,两个集群刚刚都对外提供服务了,数据该怎么合并,数据冲突怎么解决等等问题。刚刚在说明脑裂场景时有一个前提条件就是没有考虑过半机制,所以实际上 Zookeeper 集群中是不会轻易出现脑裂问题的,原因在于过半机制。

zookeeper 的过半机制:在领导者选举的过程中,如果某台 zkServer 获得了超过半数的选票,则此 zkServer 就可以成为 Leader 了。

举个简单的例子:如果现在集群中有 5 台 zkServer,那么 half=5/2=2,那么也就是说,领导者选举的过程中至少要有三台 zkServer 投了同一个 zkServer,才会符合过半机制,才能选出来一个 Leader。

有个疑问:zookeeper 选举的过程中为什么一定要有一个过半机制验证?因为这样不需要等待所有 zkServer 都投了同一个 zkServer 就可以选举出来一个Leader 了,这样比较快,所以叫快速领导者选举算法。

再来想一个问题,过半机制中为什么是大于,而不是大于等于呢?这就是更脑裂问题有关系了,比如回到上文出现脑裂问题的场景 [如上图1]:

当机房中间的网络断掉之后,机房1内的三台服务器会进行领导者选举,但是此时过半机制的条件是 "节点数 > 3",也就是说至少要4台 zkServer 才能选出来一个  Leader,所以对于机房1来说它不能选出一个 Leader,同样机房2也不能选出一个  Leader,这种情况下整个集群当机房间的网络断掉后,整个集群将没有 Leader。

而如果过半机制的条件是 "节点数 >= 3",那么机房1和机房2都会选出一个Leader,这样就出现了脑裂。这就可以解释为什么过半机制中是大于而不是大于等于,目的就是为了防止脑裂。

如果假设我们现在只有5台机器,也部署在两个机房:

此时过半机制的条件是 "节点数 > 2",也就是至少要3台服务器才能选出一个  Leader,此时机房件的网络断开了,对于机房1来说是没有影响的,Leader 依然还是 Leader,对于机房2来说是选不出来 Leader 的,此时整个集群中只有一个Leader。所以可以简单总结得出,有了过半机制,对于一个 Zookeeper 集群来说,要么没有 Leader,要么只有1个 Leader,这样 zookeeper 也就能避免了脑裂问题。

三  Zookeeper 集群"脑裂"问题处理
1.  什么是脑裂?

简单点来说,脑裂 (Split-Brain) 就是比如当你的 cluster 里面有两个节点,它们都知道在这个 cluster 里需要选举出一个 master。那么当它们两个之间的通信完全没有问题的时候,就会达成共识,选出其中一个作为 master。但是如果它们之间的通信出了问题,那么两个结点都会觉得现在没有 master,所以每个都把自己选举成 master,于是 cluster 里面就会有两个 master。

对于 Zookeeper 来说有一个很重要的问题,就是到底是根据一个什么样的情况来判断一个节点死亡 down 掉了。 在分布式系统中这些都是有监控者来判断的,但是监控者也很难判定其他的节点的状态,唯一一个可靠的途径就是心跳,Zookeeper 也是使用心跳来判断客户端是否仍然活着。

使用 ZooKeeper 来做 Leader HA 基本都是同样的方式:每个节点都尝试注册一个象征 leader 的临时节点,其他没有注册成功的则成为 follower,并且通过 watch  机制 (这里有介绍) 监控着leader所创建的临时节点,Zookeeper 通过内部心跳机制来确定 leader 的状态,一旦 leader 出现意外 Zookeeper 能很快获悉并且通知其他的 follower,其他 flower 在之后作出相关反应,这样就完成了一个切换,这种模式也是比较通用的模式,基本大部分都是这样实现的。但是这里面有个很严重的问题,如果注意不到会导致短暂的时间内系统出现脑裂,因为心跳出现超时可能是  leader 挂了,但是也可能是 zookeeper 节点之间网络出现了问题,导致 leader 假死的情况,leader其实并未死掉,但是与 ZooKeeper 之间的网络出现问题导致Zookeeper 认为其挂掉了然后通知其他节点进行切换,这样 follower 中就有一个成为了 leader,但是原本的 leader 并未死掉,这时候 client 也获得 leader 切换的消息,但是仍然会有一些延时,zookeeper 需要通讯需要一个一个通知,这时候整个系统就很混乱可能有一部分 client 已经通知到了连接到新的 leader 上去了,有的 client 仍然连接在老的 leader 上,如果同时有两个 client 需要对 leader 的同一个数据更新,并且刚好这两个 client 此刻分别连接在新老的 leader 上,就会出现很严重问题。

这里做下小总结:假死:由于心跳超时(网络原因导致的)认为 leader 死了,但其实 leader 还存活着。脑裂:由于假死会发起新的 leader 选举,选举出一个新的 leader,但旧的 leader 网络又通了,导致出现了两个 leader ,有的客户端连接到老的 leader,而有的客户端则连接到新的 leader。

2.  zookeeper 脑裂是什么原因导致的?主要原因是 Zookeeper 集群和 Zookeeper client 判断超时并不能做到完全同步,也就是说可能一前一后,如果是集群先于 client 发现,那就会出现上面的情况。同时,在发现并切换后通知各个客户端也有先后快慢。一般出现这种情况的几率很小,需要 leader 节点与 Zookeeper 集群网络断开,但是与其他集群角色之间的网络没有问题,还要满足上面那些情况,但是一旦出现就会引起很严重的后果,数据不一致。

3.  zookeeper 是如何解决"脑裂"问题的?要解决 Split-Brain 脑裂的问题,一般有下面几种种方法:- Quorums (法定人数) 方式: 比如3个节点的集群,Quorums = 2, 也就是说集群可以容忍1个节点失效,这时候还能选举出1个 lead,集群还可用。比如4个节点的集群,它的 Quorums = 3,Quorums 要超过3,相当于集群的容忍度还是1,如果2个节点失效,那么整个集群还是无效的。这是 zookeeper 防止"脑裂"默认采用的方法。- 采用 Redundant communications  (冗余通信)方式:集群中采用多种通信方式,防止一种通信方式失效导致集群中的节点无法通信。- Fencing (共享资源) 方式:比如能看到共享资源就表示在集群中,能够获得共享资源的锁的就是 Leader,看不到共享资源的,就不在集群中。- 仲裁机制方式。- 启动磁盘锁定方式。

要想避免 zookeeper"脑裂"情况其实也很简单,在 follower 节点切换的时候不在检查到老的 leader 节点出现问题后马上切换,而是在休眠一段足够的时间,确保老的  leader 已经获知变更并且做了相关的 shutdown 清理工作了然后再注册成为  master 就能避免这类问题了,这个休眠时间一般定义为与 zookeeper 定义的超时时间就够了,但是这段时间内系统可能是不可用的,但是相对于数据不一致的后果来说还是值得的。

1) zooKeeper 默认采用了 Quorums 这种方式来防止"脑裂"现象,即只有集群中超过半数节点投票才能选举出 Leader。这样的方式可以确保 leader 的唯一性,要么选出唯一的一个 leader,要么选举失败。在 zookeeper 中 Quorums 有3个作用:

集群中最少的节点数用来选举 leader 保证集群可用。

通知客户端数据已经安全保存前集群中最少数量的节点数已经保存了该数据。一旦这些节点保存了该数据,客户端将被通知已经安全保存了,可以继续其他任务。而集群中剩余的节点将会最终也保存了该数据。

假设某个 leader 假死,其余的 followers 选举出了一个新的 leader。这时,旧的leader 复活并且仍然认为自己是 leader,这个时候它向其他 followers 发出写请求也是会被拒绝的。因为每当新 leader 产生时,会生成一个 epoch 标号(标识当前属于那个 leader 的统治时期),这个epoch是递增的,followers 如果确认了新的leader 存在,知道其 epoch,就会拒绝 epoch 小于现任 leader epoch 的所有请求。那有没有 follower 不知道新的 leader 存在呢,有可能,但肯定不是大多数,否则新 leader 无法产生。Zookeeper 的写也遵循 quorum 机制,因此,得不到大多数支持的写是无效的,旧 leader 即使各种认为自己是 leader,依然没有什么作用。

zookeeper 除了可以采用上面默认的 Quorums 方式来避免出现"脑裂",还可以可采用下面的预防措施:2) 添加冗余的心跳线,例如双线条线,尽量减少“裂脑”发生机会。3) 启用磁盘锁。正在服务一方锁住共享磁盘,"裂脑"发生时,让对方完全"抢不走"共享磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共享盘的一方不主动"解锁",另一方就永远得不到共享磁盘。现实中假如服务节点突然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用服务。于是有人在  HA 中设计了"智能"锁。即正在服务的一方只在发现心跳线全部断开(察觉不到对端)时才启用磁盘锁。平时就不上锁了。4) 设置仲裁机制。例如设置参考 IP(如网关 IP),当心跳线完全断开时,2个节点都各自 ping 一下 参考 IP,不通则表明断点就出在本端,不仅"心跳"、还兼对外"服务"的本端网络链路断了,即使启动(或继续)应用服务也没有用了,那就主动放弃竞争,让能够 ping 通参考 IP 的一端去起服务。更保险一些,ping 不通参考 IP 的一方干脆就自我重启,以彻底释放有可能还占用着的那些共享资源。

zookeeper的脑裂问题相关推荐

  1. 【Zookeeper】Zookeeper集群“脑裂”问题处理大全

    本文重点分享Zookeeper脑裂问题的处理办法.ZooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调内核,用户可以在此之上构建更多复杂的分布式协调功能. 脑裂通常会出现在 ...

  2. Zookeeper集群脑裂问题

    关于集群中的"脑裂"问题,之前已经在这里详细介绍过,下面重点说下Zookeeper脑裂问题的处理办法.ooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调 ...

  3. 关于ZooKeeper集群脑裂及其解决方案

    本文来说下ZooKeeper集群脑裂及其解决方案 文章目录 概述 Zookeeper集群节点为什么要部署成奇数 Zookeeper集群中的"脑裂"场景说明 Zookeeper集群& ...

  4. 分布式系统的“脑裂”到底是个什么玩意?

    目前大多数项目都在往分布式上发展,一旦系统采用分布式系统,便会引入更多复杂场景和解决方案.比如,当你在系统中使用了Elasticsearch.ZooKeeper集群时,你是否了解过集群的"脑 ...

  5. it 脑裂_脑裂是什么?Zookeeper是如何解决的?

    什么是脑裂 脑裂(split-brain)就是"大脑分裂",也就是本来一个"大脑"被拆分了两个或多个"大脑",我们都知道,如果一个人有多个大 ...

  6. Zookeeper和分布式环境中的假死脑裂问题(转)

    Zookeeper和分布式环境中的假死脑裂问题 最近和同事聊天无意间发现他们的系统也存在脑裂的问题.想想当初在我们的系统中为了解决脑裂花了非常大的功夫,现在和大家一起讨论下脑裂,假死等等这些问题和解决 ...

  7. 【zookeeper】zookeeper 脑裂问题

    1.概述 转载:https://blog.csdn.net/yjp198713/article/details/79400927 1.1 为什么zookeeper要部署基数台服务器? 所谓的zooke ...

  8. 脑裂是什么?Zookeeper是如何解决的?

    什么是脑裂 脑裂(split-brain)就是"大脑分裂",也就是本来一个"大脑"被拆分了两个或多个"大脑",我们都知道,如果一个人有多个大 ...

  9. zookeeper脑裂

    出现: 在搭建hadoop的HA集群环境后,由于两个namenode的状态不一,当active的namenode由于网络等原因出现假死状态,standby接收不到active的心跳,因此判断activ ...

最新文章

  1. python27安装-二、Python2.7的安装并与Python3.8共存
  2. logstic 回归文章链接
  3. HawtIO在JBoss EAP上(第二部分)
  4. 中国替扎尼定行业市场供需与战略研究报告
  5. 有趣的算法(五):一文读懂二叉搜索树的插入、删除
  6. 第六次团队作业+登录界面
  7. Roboware主题配置教程
  8. centos/linux 服务器的内存不够了怎么办?centos用虚拟内存扩展内存
  9. unity入门——实现一个简单的跑酷游戏(准备工作)
  10. c语言房屋程序运行截图,c程序截取屏幕截图
  11. 用Javascript实现放大镜效果
  12. 《击掌为盟》读后感1742字
  13. 什么是robots.txt文件?
  14. React Redux入门
  15. 经典算法研究系列:九、图像特征提取与匹配之SIFT算法
  16. window docker 安装 宝塔bt
  17. php 不要平铺的代码,css怎么设置图片不平铺
  18. React从入门到精通教程01
  19. mysql性能分析三驾马车_MySQL知识体系的三驾马车
  20. 非深度网络 Non-deep Network:低延迟平行网络 ParNet,仅 12 层媲美 ResNet

热门文章

  1. Handle的详细用法
  2. java中的同步与异步
  3. 码农、程序员、开发者
  4. CANoe 之 CAPL编程
  5. 【JavaScript练习】用户输入一个数判断是否是素数,并弹出返回值
  6. 你见过的最全面的Python重点(附代码演示)
  7. 在ORACLE中用DBCA创建数据库
  8. 国产直流马达驱动芯片SS6216的功能参数以及应用
  9. oracle 错误代码
  10. Mysql创建自增序列方案(模拟Oracle序列)