2015.6.9(zookeeper角色)

来源:互联网 发布:北京市大数据公司 编辑:程序博客网 时间:2024/06/05 06:49

Zookeeper角色:
1) Leader
Leader不直接接受client的请求,但接受由其他Follower和Observer转发过来的Client请求,此外,Leader还负责投票的发起和决议,即时更新状态和数据。
2) Follower
Follower角色接受客户端请求并返回结果,参与Leader发起的投票和选举,但不具有写操作的权限。
3) Observer
Observer角色接受客户端连接,将写操作转给Leader,但Observer不参与投票(即不参加一致性协议的达成),只同步Leader节点的状态,Observer角色是为集群系统扩展而生的。
4) Learner
和Leader进行状态同步的server都称为Learner,Follower和Observer都可以称为Learner。

选举算法-Paxos:
Paxos是一个基于消息传递的一致性算法,被广泛运用于分布式应用中,是Zookeeper实现一致性服务的核心。Paxos算法中的角色有三种状态:Leading,Looking,Following,这里Observing状态暂且不考虑,因为Observing不参与选举,只同步选举后的结果。
下面举例说明:
假设我们(Client)生活在一个民主的小村庄(Zookeeper集群),有豫、湘、浙,贵,皖5个议员,编号分别为1,2,3,4,5(Zid)。有什么事情必须经过议员讨论形成决议,总统签署过法令后,才能向公民发布。这五人中只有一人是总统,总统负责签署法令(写操作),其余几个议员只能发起提案(投票和向Leader节点请求和同步更新),向支持自己的选民公布法案(向Client提供读操作),没有修改法案的权利(不能进行写操作)。法案编号只能递增,每个议员手里都有从总统哪里同步的法案编号,不过每个议员手里的法案最大编号可能会不同。现在假设完毕,人们开始快乐的生活。
情形一,这个村庄刚形成,有五个议员,还没有总统,且还没有任何法案公布(每个Znode下面都是空白的,没有任何数据),总统(Leader)如何产生?
Paxos算法给出了这样的答案:假设五个议员(五个Zookeeper节点)按编号启动,1号启动后,处于Looking状态,它发出去的数据包(选举自己为总统+Zid)没有得到任何回应,接着2号启动,他与1号交换选举数据,因为Paxos选举中有一个原则是Zid大着优先,2号的Zid为2大于1号的Zid为1,所以1号修改自己的选举列表,把2号选为总统,但现在参加选举的机器数为2小于(集群中总的节点数的一半)3,所以2号还不能成为总统,接着3号启动,加入交换数据行列,他选举自己并与1号和2号交换数据包(选举自己为总统+Zid),本着Zid大者优先的原则,1号和2号都将自己选举列表中的总统编号改为3,现在3号议员有3票,超过了半数,所以它成为了这几台机器的Leader,即被选举成为了总统,尽管后面还有4号、5号比3号大,但当4和5启动后加入集群时候,1,2已经从Looking状态变为Following状态,3处于Leading状态,4和1、2、3交换信息后,更新了自己的Leader信息,并变为Following状态,只能作为Follower角色加入集群。
情形二,有一天一些村民找到某个议员(假设是1号),要求颁布一个新法令《反对虐待小动物法》,1号议员收到村民的请求后,先查看目前自己手中最大的法案编号为X,所以他将这个新提议编号为X+1,他无权私自颁布新法令,他向总统发送了这个编号为X+1的请求(Follower将Client的写操作转给Leader),总统将这个请求发给其他议员进行了讨论,当超过半数以上的议员同意通过该法令时,总统就签署了法令,使其生效,并将这个法案公布给了所有的议员,每个议员都将这个新法案更新到自己的手里(Follower节点与Leader的数据同步)。
情形三,某一天,有一个村民找到4号议员,问他《反对虐待小动物法》的第三条是什么内容时,因为4号之前已经同步更新了3号议员给总统提的请求,所以他可以轻松的将自己手里的内容告诉村民(Client向Follower的读操作)。
情形四,假设有一天还是那批村民感觉《反对虐待小动物法》需要完善和修改了,他们找到某一个议员(假设5号),5号议员没有修改法案的权利,他将这个请求发给总统,总统向所有议员公布了这个提案,如果获得半数以上的议员通过,那么总统就可以签署法令(Leader向所有节点公布数据),修改生效。(Follower将Client的写操作转给Leader)。
情形五,假设有一天总统(Leader)挂了,现在群龙无首,谁来签署法令呢?
Paxos给出了这样的解决方案:当1号发现3号Leader挂了后(ping不同,连接断开),将自己的状态从Following改为Looking,并将自己的编号(或选的总统的编号)+自己手里最大的法案编号发送给其他议员,结果是每个议员都会收到其他所有议员发给自己的数据包(他人选择的总统+他人手里的最大法案编号),并将自己手里的最大法案编号和收到的法案编号对比,如果自己手里的法案编号小于收到的法案编号,就更新自己的选举内容(通过totalOrderPredicate(n.leader, n.zxid,getInitId(), getInitLastLoggedZxid())方法,返回true,则说明需要更行),选举收到的编号为总统,并将这个信息发给其他议员,最终所有议员手里选举的总统编号会变成同一个,实际上当超过集群半数的节点选举某一个编号为总统时,总统就诞生了,其余节点都更新自己的状态(从Looking变为Following)和Leader节点信息,然后继续维持小村庄的正常运转。
演职员表:
村民——Client
总统——Leader
议员——Follower
村庄——Zookeeper 集群
法案编号——事物ID(=数据ID)
总统签署的法案——Znode下的数据
对法案编号大者优先选择的理解:事物ID是递增的,某个节点下的事物ID越大,说明它手里的数据越新,他掌握的数据越多,选举他为Leader,可以最好的实现数据同步。
当然,上面描述的几种情形,可能有些简化了,Paxos选举算法的情形可能复杂的多,实际上选举的原则,还要考虑接收到的逻辑时钟的值(用来表征选举的时序,逻辑时钟值越大,说明选举越新)与自己的逻辑时钟值的大小关系,但这几种情形能够基本模拟Paxos选举算法的原理和Zookeeper集群的工作原理。
我的疑问是情形二种所提到的,为什么只需要超过一半的节点同意写,Leader就可以进行写操作了?

1 0
原创粉丝点击