Zookeeper服务端初始化过程(二):Leader选举过程
Server具有如下几种状态:
LOOKING:失去leader信号,选举中
FOLLOWING:环境正常,对于follower而言,正在“跟随”leader
LEADING:环境正常,对于leader而言,正在“带领”
OBSERVING:环境正常,对于observer而言,正在“观察”
选举的时机:Leader失效,或者Follower认为Leader"失效";比如Follower首次加入集群时无法确定Leader则尝试选举,比如Follower和Leader之间的网络问题,导致Follower离群,此时Follower也会尝试"选举"--尽管是徒劳.Leader失效的时机为:当Leader和Follower发送ping时,遇到"多数派"的Follower无法响应时(可能多数Follower已经离群,或者Leader离群),此时Leader进入LOOKING模式,开始选举.
F1.FastLeaderElection类初始过程
- QuromCnxManager是一个相对底层的”链接”处理类,他负责管理当前server和其他server的socket链接,以及socket上数据的输入输出,对于FastLeader选举过程中所造成的消息发送和接受,均由此manager处理,它维持当前server和其他server建立的链接,以及侦听选举端口上,其他server的链接申请或者数据IO;链接为socket链接,非NIO长连接."链接"的作用,就是为选举过程中所发生的数据交互进行IO操作(例如,接收选举数据和发送头片数据等).
- 为了避免大量server之间互相建立socket链接,造成性能问题(甚至是不必要的重复链接),manager对链接的控制采取了一种” challenge”(挑战)方式,让任意2个server之间只有一个socket链接,而且总是sid较小的server作为socket server端,sid较大的作为sock client端,在整个分布式网络中,将这种有序有向的链接逐个节点传递下去.不过在初次通信时,server会尝试和所有的其他server发起链接,对于链接的socket server端,来决定是否接受(accept)链接.如果当前server发现socket终端的sid比自己的sid小,那么当前server就会放弃已经建立的链接(假如已经建立)或者关闭此socket,并主动向sid较小的server发起socket链接.选举过程中,如果socket超时或者其他原因终端,链接将会重建.
F2.QuorumCnxManager内部结构
- Notification:”通知”,其他server发送的消息,包括server所提议(推选)的leader所具有的如下属性:leader(机器id),,zxid,peerEpoch;以及”提议者”的sid,serverState,electionEpoch.
- ToSend:”发件”,当前server需要发给其他server的消息,包括它提议的leader所具有的如下属性:leader(机器id),zxid,peerEpoch,以及当前server的如下属性:electionEpoch,serverState,sid.它和Notification相互对应.为了区别,用了2个几乎完全一样的类.
- FastLeaderElection类持有2个队列,sendqueue和recvqueue.sendqueue是当前server亟待发给其他server的消息(ToSend),recvqueue是当前server已经接收但还没有处理的消息(Notification).
- SendWorker和RecvWorker在socket建立成功后,同时被创建,实例化时同时也持有sid,dataInput或dataoutput引用,很便捷的操作socket数据.
- FastLeaderElection也不能脱俗,使用2个队列分别保存亟待发送的ToSend和Nofification,数据结构为LinkedBlockingQueue.
- QuromCnxManager持有3个数据结构,:
- queuesendMap,亟待发送的消息,key为sid,value为一个ArrayBlockingQueue,即每个sid对应socket维护一个队列,有各自的socket负责发送;
- senderWorkerMap,key为sid,value为SendWorker实例,已标记server是否和sid已经建立了链接,如果此sid下的SendWorker不为null,则标示链接已经建立.
- recvQueue,一个ArrayBlockingQueue,标示server在选举端口上接收到的”提议”消息,此队列最终将交付给FastLeaderElection类来消费.
- FastLeaderElection也不能脱俗,使用2个队列分别保存亟待发送的ToSend和Nofification,数据结构为LinkedBlockingQueue.
F3.FastLeaderElection选举过程
- 选举过程中,有几个参数容易混淆: logicalclock,这个匪夷所思的命名,意思是当前server所持有的最高选举轮数,确保自己所接受的其他server提议都处于同一轮选举上(计算投票结果才有效);Notification中有一个electionEpoch变量,标示提议者发送消息是所处于的选举轮数.a) 为了保证选举结果的有效性,所有的投票epoch必须一致,消息中较低的epoch将会被抛弃;而且server从消息中发现更高的epoch,也会将本地的logicalclock和它保持一致,并清除先前的投票集合,重新计数.b) 如果接受的”提议”消息的epoch,比本地的logicalclock要小,那么当前server会立即反馈一个ToSend,告知提议者,最新的epoch(logicalclock).
- 当前server已经计算出了leader,并且处于Following或者Leading状态,如果接收到的提议消息是Looking,那么次消息就是滞后的投票,或者是提议者加入集群,寻找Leader.
- Observer发送的投票是直接被忽略,而且server也不会向Observer发送”提议”.
F4.选举过程
-
当server接受到的”提议”消息中,epoch大于或者等于当前server本地的logicalclock时,server会对此”提议”进行校验,如果检验成功,将会将本地持有的提议信息替换.[注意,此处为server之间信息比较,而非比较”投票”信息],依次比较epoch,zxid,sid.
a) 如果proposalEpoch > peerEpoch,校验成功.此时的peerEpoch是整个集群server最近一次投票成功时的epoch;每次投票成功,每个server就会把epoch写入到文件.否则,参见b) b) 如果proposalEpoch = peerEpoch,并且proposalZxid > currentZxid,校验成功.currentZxid为当前server的zkDatabase中持有的最大的zxid.否则,参见c) c) 如果proposalZxid = currentZxid,并且”提议者”的sid比当前server的sid大,校验成功.否则失败.最终将由sid来决定,是否接受此次”提议”. Server本地保持者一份当前投票的最新(高)的提议副本,此副本包括epoch/zxid/leader(sid);如果server从消息中发现有更好的提议,将会替换本地的这些信息.并在适当的时机,将自己收集到的提议副本发送给其他”提议者”.知道最终达成一致.
- 如果”提议”被当前server校验通过,将被封装成一个更加简小的对象Vote(投票).”投票”将会被放入一个Map中,key为sid,value就是”投票”,确保每个server都参与而且只有一个有效的vote.
- “断言是否成功”:截止到目前,当前”提议”是否已经是”多数派”,如果是,即可结束投票,leader已经在集群中产生.(可以提前确定leader).
- Outofelection是个map,key为sid,value为vote(投票);它的本意是存储那些在非投票期间所产生的”vote”(类似于票据),在失效的server重新加入集群,将会触发”选举”,此时其他server的”提议”将会被加入到outofelection,当前server根据此map来判断是否存在”多数派”,如果集群处于”危险期”(少数派),那么新加入的server选举直到”多数派”出现.
- 新server加入,投票时还会进行CheckLeader操作.
if (termPredicate(outofelection, new Vote(n.leader,n.zxid, n.electionEpoch, n.peerEpoch, n.state)) && checkLeader(outofelection, n.leader, n.electionEpoch)) { synchronized(this){ logicalclock = n.electionEpoch; self.setPeerState((n.leader == self.getId()) ? ServerState.LEADING: learningState()); } Vote endVote = new Vote(n.leader, n.zxid, n.peerEpoch); leaveInstance(endVote); return endVote; }
F5.Server状态迁移
- 只有当前server处于LOOKING状态下,才会进行”投票”,当处于FOLLOWING或者LEADING状态时,说明集群中,Leader是存活的.选举的唯一条件就是”Leader”失效或者离群.[如果"多数派"不存在,则直接导致ZK Cluster中所有的"write"操作阻塞]
- “选举”所涉及到的SenderWokrer/RecvWorker线程,会一直有效.不会因为选举成功,就退出.
- 新的leader选举之后,leader将会首先根据epoch重置一下zxid,即zxid的前32位为epoch,后32为为自增counter,初始值为0.理论上说无论如何选举,均不会出现zxid重复的现象。
- Follower server/Observer server将分别有Follower类、Observer类来处理与Leader之间的数据交互,它们均继承自Learner类;在与Leader正式同步数据或者操作之前,首先会向Leader发送一个数据包,leader会反馈其此时的zxid.(registerWithLeader).
- 在Follower与Leader之间通讯有专一的IO通道,Leader会间歇性的发送ping来检测Follower或Observer的状态,如果发现ping不同,则直接导致Leader与Follower之间的连接关闭(关闭的后果就是,此后所有的请求都将不会波及到此Follower);Follower不会主动去"ping" Leader,不过Follower在Socket层面做了工作,Follower或在Socket上设定soTimeout,如果在read操作阻塞超时,也将直接操作IO关闭,Follower进入LOOKING模式.
[引导:Leader选举补充部分]
Leader: Cluster环境中操作"调度者",负责"数据一致性"的控制,主要包括"write操作"/Session过期控制等.
Follower: "跟随者",它是和Leader共同构成Cluster多数派,直接负责接收Client的read和write操作,并转发write操作给"Leader".
Observer(“围观者”):
在ZK server中,有一种特殊的server类型,是Observer(read-only),它可以在不影响写入性能的同时扩展zk。zk之所以设计这种类型的server,是可以理解的;如果一个cluster中不断新增的voting member(follower),将会导致write性能下降,这归因于write操作需要至少半数的follower同意才能被执行,所以这种“提议/投票”的开支会随着“follower”的增加而增加。
我们引入了一个新的server类型,就是Observer;它对于解决这种问题很有帮助,而且跟一步提高了ZK的扩展性。Observer为non-voting成员,即不参与leader选举和其他操作的“提议”,它就像一个“围观者”一样只会接受投票的结果,而不是投票的协议。除了这个简单的区别之外,它和follower几乎一样。client也可以和它们建立链接,发送read和write请求。Observer和Follower一样把write请求转发给leader,只是它们然后就是简单的等待(hear)此操作的投票结果;因此我们能够在无损性能的情况下增加数个observer。
Observer还有其他的优点,因为它们不参与投票,他们不是ZK成员的核心部分;所以即使它们失效了,或者离群了,也不会对ZK 服务带来任何不利影响。Observer可以链接比followers更加不可靠的网路。
Observer类中可以看到它对各种消息的处理,Observer不是ZAB的一部分,也参与提议,在processPacket()方法中可见,observer会忽略PROPOSAL/COMMIT类型的请求,而增加了一个INFORM,这个请求类型是为Observer设计的,当proposal成功执行后,会把数据packet以INFORM消息类型发给Observer(Follower不关系此类型),那么observer即可以在本地应用最新的数据。
设置Observer非常简单,只需要将zoo.cfg中peerType=observer即可。
简单的使用场景:
作为数据中心桥:如果构成ZK环境有2个数据中心,那么2个数据中心的网络延迟是一个很棘手的问题,(延迟)可能会导致“假故障”问题(超时等)。不过可以将其中一个datacenter全部设置为observer,这样可以避免这些问题,而且链接observer的客户端仍然可以看到问题提议(issue proposal)。(zk cluster中一部分机器作为observer,这部分及其可能位于位置较远的其他地区,为了不让这种“位置”距离影响了zk服务,只能这这部分zk server成为observer,比如你的zk服务一部分在中国,另部分可能位于美国机房)。
相关推荐
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终将简单易用的接口和性能高效、功能稳定的系统提供给用户。...
3. **Master选举**:HBase Master是整个系统的协调者,负责监控RegionServer的工作状态、Region的分配和迁移等。在Master出现故障时,HBase利用ZooKeeper的选举机制自动选出一个新的Master节点来接管集群的管理工作...
4. 领导者选举:Zookeeper通过zab协议实现领导者选举,保证集群的稳定运行。 5. 集群监控:Zookeeper可以监控各个服务节点的状态,及时发现并处理故障。 三、Zookeeper的应用场景 1. HBase:HBase依赖Zookeeper...
4. **HBase**:HBase使用Zookeeper监控RegionServer的状态,处理Region迁移和主Master的选举。 **五、Zookeeper的扩展性与可靠性** Zookeeper采用Paxos算法的简化版本Zab协议,确保在节点间的通信中达成一致。当...
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终将简单易用的接口和性能高效、功能稳定的系统提供给用户。...
- **Session的迁移与同步:** 在ZooKeeper中存储的Session数据可以通过同步机制在不同的服务器之间共享,保证了数据的一致性。 - **高可用性保证:** 通过ZooKeeper集群提供的选举机制,可以确保即使部分节点故障,...
Zookeeper 3.4.6是其稳定版本之一,它提供了一种简单易用的API,使得开发者能够方便地实现诸如命名服务、配置管理、集群同步、领导者选举等多种分布式应用场景。 Zookeeper的核心概念包括: 1. **节点(Znode)**...
例如,Zookeeper需要设置多个节点以实现高可用,HBase需要与Zookeeper配合以管理集群状态,而Kafka通常会依赖Zookeeper进行集群管理和元数据存储。Sqoop的配置则涉及数据库连接信息和Hadoop的路径设置。 理解并熟练...
4. **一致性**:Zookeeper保证了在分布式环境下的数据一致性,通过选举算法确保在集群中只有一个主节点(Leader),所有写操作都由该节点处理,读操作可以从任何节点读取。 5. **Watcher机制**:Watcher是Zookeeper...
3. **集群状态监控**:监控各个节点的状态,如果某个节点失效,Zookeeper会触发重新选举或者数据迁移。 配置Zookeeper集群: 1. **服务器配置**:在每台Zookeeper服务器上,配置`conf/zoo.cfg`文件,设置数据存储...
它基于一个分布式的数据模型,使得多个分布式应用程序能够共享和维护共同的状态信息。 在给定的压缩包中,我们有两个版本的 ZooKeeper:`zookeeper-3.4.8.tar.gz` 和 `apache-zookeeper-3.5.9.tar.gz`。这两个版本...
- **连接方式**:客户端可以连接任意一个Zookeeper服务器,集群内部会自动进行会话迁移。 - **连接优化**:可以通过设置`clientPort`来指定监听客户端连接的端口,避免网络拥堵。 7. **监控与维护** - **日志...
通常,我们会使用`ZooKeeper`构造函数,指定连接字符串(包含Zookeeper服务器地址和端口)、会话超时时间及一个Watcher对象,用于监听连接状态: ```java ZooKeeper zooKeeper = new ZooKeeper(ZK_ADDRESS, SESSION...
这种机制有助于监控服务器的状态,当服务器断开连接时,其对应的临时节点会自动删除,从而触发集群重新进行领导者选举。例如,`server1`、`server2`和`server3`就是这样的临时节点,存储着各自服务器的信息。 `/...
经过几年的发展和变迁,2008年6月迁移到Apache软件基金会,2010年获得了Usenix的“最佳论文奖”("ZooKeeper: Wait-free Coordination for Internet-scale Systems"),并在2011年发布了ZooKeeper 3.4版本。...
ZooKeeper 是一个专门为分布式应用程序提供协调服务的开源框架,它在分布式环境中扮演了重要的角色,如领导者选举、配置管理、命名服务等。然而,随着 Kafka 的发展,它开始寻求摆脱对 ZooKeeper 的依赖,以提高性能...
在Kafka中,ZooKeeper用来管理集群的状态,包括选举领导节点、存储和更新broker和topic的信息等。它的存在确保了Kafka集群的稳定性和一致性。 Kafka Connect是一种用于在Kafka与其他系统之间进行大规模、可靠且低...
在Mesos中,Zookeeper用于选举Master,存储和同步Master与Slave的状态信息,以及管理Framework的注册和心跳检测。 在Mesos+Zookeeper的组合中,Zookeeper保证了Mesos集群的高可用性和稳定性。例如,当新的Master被...
3. **分布式通知与协调**: 通过 Watcher 机制,Zookeeper 可以实时通知应用程序状态的变化,便于进行分布式协调操作。 4. **分布式锁**: 利用 Zookeeper 的临时顺序节点(EPHEMERAL_SEQUENTIAL)特性,可以实现高效...
ZooKeeper在此过程中提供服务发现和协调,确保Flume和HBase之间的通信稳定可靠。当需要将HBase中的数据导入关系数据库,或者分析存储在HBase中的数据时,可以使用Sqoop来完成这个任务。 总的来说,这个整合包提供了...