Zookeeper专题——4、选主过程,脑裂问题如何解决

目前有5台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,它们的选择举过程如下:

  • 服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于Looking。
  • 服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,由于服务器2的编号大所以服务器2胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是LOOKING。
  • 服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号最大所以服务器3胜出,此时投票数正好大于半数,所以服务器3成为领导者,服务器1,2成为小弟。
  • 服务器4启动,给自己投票,同时与之前启动的服务器1,2,3交换信息,尽管服务器4的编号大,但之前服务器3已经胜出,所以服务器4只能成为小弟。

 

  • 服务器5启动,后面的逻辑同服务器4成为小弟。

    小说了一下Zookeeper,接下来讨论一下脑裂,假死等等问题以及解决方法吧。


    假死脑裂 
    在一个大的集群中往往会有一个master的存在,在长期运行过程中不可避免会出现宕机等等的问题导致master不可用,在出现这样的情况以后往往会对系统产生很大的影响,所以一般的分布式集群中的master都采用了高可用的解决方案来避免这样的情况发生。 
    master-slaver方式,存在一个master的节点,平时对外服务,同时有一个slaver节点来监控master,监控的同时有某种方式来进行数据同步。假如现在master挂掉了,slaver能很快获知并且迅速切换为新的master。但是在这种方式中,监控切换是一个很大的难题,但是现在Zookeeper的watch和分布式锁机制能比较好的解决这个问题。虽然Zookeeper很好的解决了这个问题,但是它的使用也存在其他的问题,比如脑裂。 
    导致脑裂的一个根源问题就是假死。


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

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

    如何避免? 
    在slaver切换的时候不在检查到老的master出现问题后马上切换,而是在休眠一段足够的时间,确保老的master已经获知变更并且做了相关的shutdown清理工作了然后再注册成为master就能避免这类问题了,这个休眠时间一般定义为与Zookeeper定义的超时时间就够了,但是这段时间内系统不可用了。

<think>嗯,我现在需要解释一下Zookeeper过程中的作用。首先,我得回忆一下Zookeeper的基本概念,它通常用于分布式系统中的协调服务。,也就是Leader Election,是分布式系统中的一个常见问题,确保在多个节点中出一个节点来协调任务。 那Zookeeper是如何帮助实现这个过程的呢?我记得Zookeeper提供了一些原语,比如临时节点和顺序节点。可能过程会用到这些特性。比如,每个参与的节点都会在Zookeeper的一个指定路径下创建一个临时顺序节点。临时节点的好处是,如果某个节点宕机,它的节点会被自动删除,这样其他节点可以及时感知到。 接下来,每个节点创建节点后,会检查该路径下的所有子节点,并确定自己是否是序号最小的那个。如果是,那么这个节点就会成为节点。如果不是,它会监听比自己序号小的前一个节点的变化。这样,一旦前一个节点失效,当前节点就会收到通知,并重新检查自己是否成为新的最小序号节点,从而接替成为节点。 不过,这里可能还有一些细节需要注意,比如如何处理节点崩溃的情况,以及如何确保所有节点都能正确监听到前一个节点的状态变化。此外,Zookeeper的Watch机制在这里起到了关键作用,允许节点在关注的节点发生变化时收到通知,从而触发后续的逻辑。 可能还需要提到Zookeeper的原子性和一致性保证,比如通过ZAB协议来确保所有节点的状态同步,这样在过程中不会出现脑裂问题。另外,临时顺序节点的特性确保了即使有节点故障,系统也能自动恢复,保持高可用性。 总结一下,过程大致分为以下几个步骤:节点注册、顺序检查、监听前驱节点、处理节点失效以及节点的重新举。整个过程依赖于Zookeeper提供的临时节点、顺序节点和Watch机制,确保了分布式系统中节点的高效、可靠举。</think>Zookeeper实现过程要依赖**临时顺序节点(Ephemeral Sequential Znode)**与**Watch机制**,具体步骤如下: --- ### 1. **节点注册** 所有参与的客户端(候节点)在Zookeeper的指定路径(如`/election`)下**创建临时顺序节点**: ```bash # 节点创建后,Zookeeper自动生成唯一递增序号,例如: /election/node_000000001 /election/node_000000002 /election/node_000000003 ``` --- ### 2. **确定节点** 每个客户端检查`/election`下的所有子节点: - **规则**:序号最小的节点成为节点(Leader)。 - **示例**:若存在节点`node_000000001`,则其对应客户端自动成为Leader。 --- ### 3. **非节点监听前驱节点** 若客户端不是Leader(如`node_000000002`): 1. 找到比自己序号小的**前一个节点**(如`node_000000001`)。 2. 对该前驱节点设置**Watch监听**。 --- ### 4. **节点失效处理** - **场景**:若当前Leader(`node_000000001`)宕机,其临时节点被Zookeeper自动删除。 - **触发机制**:后续节点(`node_000000002`)通过Watch感知到前驱节点消失。 - **重新举**:客户端再次检查最小序号节点,`node_000000002`晋升为新Leader。 --- ### 关键特性保障 - **临时节点**:客户端会话终止时节点自动删除,避免手动清理。 - **顺序节点**:全局唯一递增序号,天然支持优先级判定。 - **Watch机制**:实时监听节点变化,实现快速故障转移。 - **一致性**:ZAB协议确保所有节点状态同步,防止脑裂。 --- ### 应用场景 - **Hadoop YARN**:ResourceManager高可用。 - **Kafka Controller**:Broker的Leader举。 - **分布式锁**:通过类似机制实现互斥访问。 通过上述机制,Zookeeper以简单高效的方案解决了分布式系统中的问题,同时保证了高可用性与强一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值