ZooKeeper leader election

转载 2013年12月04日 00:39:14

Paxos是分布式应用中解决同步问题的核心。作为应用研发工程师,我们总是倾向于使用一种相对简洁的方式实现复杂的算法。ZooKeeper leader election实现就是一个非常好的参考。

其实现比标准Paxos算法简单,基本过程是:
1                                                                                          
收票->

2

判断是否是本轮投票->如是本轮开始查票;如是新一轮投票,清空本轮投票;如是上轮投票,抛弃->
3                                                         
更新最大的leader id和提案id;如无更新,沉默;->

4

通知其他peer->
5
检查收到选票是否来自全部投票人/来自大多数投票人->
6
检查自己是否被选为leader

(投票轮次在code里是:n.epoch +"|"+ logicalclock,在log里叫:n.round;round看起来比epoch要清楚。)

大致就是这样,ZooKeeper leader election代码写的很漂亮。我给出一个election状态图,结合上面6步的解释,可以看清楚。





下面再给出一个时序图。但主要是收发notification逻辑,和election无关。属于基本socket通信。
第三步是向所有配置文件中的所有Server发election notification,default proposal leader id一定是自己;
第12步根据自己的状态和notification的状态处理,
self.getPeerState() == QuorumPeer.ServerState.LOOKING -> 继续election
(self.getPeerState() == QuorumPeer.ServerState.LOOKING && notification.state == QuorumPeer.ServerState.LOOKING && 自己轮次大) || notification.state == QuorumPeer.ServerState.LOOKING
-> Send notification
简而言之就是,如果你找他也找,如果你轮次大,你就说话,否则沉默;如果只有别人找,直接告诉他你的状态;



最后再以The peer who is looking为例,看看Fast Paxos的过程



Notification数据结构是

static public class Notification {
long leader;  //所推荐的Server id

long zxid;      //所推荐的Server的zxid(zookeeper transtion id)

long epoch;   //描述leader是否变化(每一个Server启动时都有一个logicalclock,初始值为0)

QuorumPeer.ServerState state;   //发送者当前的状态
InetSocketAddress addr;            //发送者的ip地址
}

相关的ZooKeeper log是



2011-07-07 21:39:46,591 - INFO  [QuorumPeer:/0:0:0:0:0:0:0:0:2181:FastLeaderElection@663] - New election. My id =  3, Proposed zxid = 64424509440

2011-07-07 21:39:46,593 - DEBUG [WorkerSender Thread:QuorumCnxManager@367] - Opening channel to server 2

2011-07-07 21:39:46,598 - DEBUG [WorkerSender Thread:QuorumCnxManager$SendWorker@541] - Address of remote peer: 2

2011-07-07 21:39:46,601 - DEBUG [WorkerSender Thread:QuorumCnxManager@367] - Opening channel to server 4

...



2011-07-07 21:39:46,602 - INFO  [WorkerReceiver Thread:FastLeaderElection@496] - Notification: 3 (n.leader), 64424509440 (n.zxid), 1 (n.round), LOOKING (n.state), 3 (n.sid), LOOKING (my state)

2011-07-07 21:39:46,606 - INFO  [WorkerReceiver Thread:FastLeaderElection@496] - Notification: 4 (n.leader), 60129542144 (n.zxid), 16 (n.round), FOLLOWING (n.state), 2 (n.sid), LOOKING (my state)

2011-07-07 21:39:46,607 - INFO  [WorkerReceiver Thread:FastLeaderElection@496] - Notification: 4 (n.leader), 60129542144 (n.zxid), 16 (n.round), FOLLOWING (n.state), 2 (n.sid), LOOKING (my state)

2011-07-07 21:39:46,608 - INFO  [WorkerReceiver Thread:FastLeaderElection@496] - Notification: 4 (n.leader), 60129542144 (n.zxid), 16 (n.round), LEADING (n.state), 4 (n.sid), LOOKING (my state)

2011-07-07 21:39:46,609 - INFO  [WorkerReceiver Thread:FastLeaderElection@496] - Notification: 4 (n.leader), 60129542144 (n.zxid), 16 (n.round), LEADING (n.state), 4 (n.sid), LOOKING (my state)

2011-07-07 21:39:46,611 - INFO  [QuorumPeer:/0:0:0:0:0:0:0:0:2181:QuorumPeer@643] - FOLLOWING


使用leader node是一个很好的设计。我是很赞成使用一个Leader Node去处理所有写request。这非常有助于session ID等global unique资源的分配。选举Leader确保了cluster中leader node的健壮,但是在实际情况中,Leader Node Machine是否应该比Follower Node Machine更强大?

另一个很好的设计是对node进行角色的划分。其实几乎所有cluster设计都需要在对等和差异角色的设计上取舍。如果全是对等角色,则cluster健壮性最佳。但是状态可能需要同步到全cluster,会降低性能。如果是有单一node承担角色,则健壮性下降。以角色区分,在cluster内部选取一部分node作为一种角色的小集群,是非常聪明的。

具体到ZooKeeper,每个participate node相互之间都是socket连接,显然如果cluster node过多,会很糟糕。比如一个500个node的cluster,会要求participate node仅仅为leader election就维护499个socket。但通过角色设置,只有10%的node参与leader election,即设置为participate node。就可有效的解决以上问题。

参考,
ZK Paxos算法描述的清晰易懂的是:http://www.spnguru.com/?p=232
代码描述的另一详文是:http://rdc.taobao.com/blog/cs/?p=162

ZooKeeper使用场景-Leader选举

Leader选举又称为master选举是zookeeper中最为经典的应用场景了。 在分布式环境中,相同的业务应用分布在不同的机器上,有些业务逻辑(例如一些耗时的计算,网络I/O处理),往往只需要让...
  • lzlchangqi
  • lzlchangqi
  • 2014年12月24日 21:01
  • 4523

跟着实例学习ZooKeeper的用法: Leader选举

http://colobu.com/2014/12/12/zookeeper-recipes-by-example-1/ ZooKeeper官方给出了使用zookeeper的几种用途。 L...
  • smallnest
  • smallnest
  • 2014年12月12日 16:21
  • 13462

zookeeper与kafka的选举算法

kafka zookeeper 选举算法
  • yu280265067
  • yu280265067
  • 2017年03月17日 09:01
  • 1561

【Zookeeper】Leader选举机制示例

提到Leader选举,先需要重点介绍下创建znode时的Flag选项。 ZOO_EPHEMERAL ZOO_EPHEMERAL,用来标记当创建这个znode的节点和Zookeeper失去连接后,...
  • nellson
  • nellson
  • 2016年02月03日 14:27
  • 2128

Zookeeper选举算法( FastLeader选主)

FastLeader选主算法:        看网上关于 zookeeper选主节点fast算法的描述,虽然有几篇写的非常不错,但是总感觉描述的差一些,因此打算写一个我认为的较为详细的版本让大家提点意...
  • cnh294141800
  • cnh294141800
  • 2016年10月28日 19:14
  • 3324

zookeeper源码分析之leader选举

zookeeper默认选举算法为FastLeaderElection.java,其主要方法为FastLeaderElection.lookForLeader,选举的结果保存在类Vote中源码分析LOO...
  • oDaiLiDong
  • oDaiLiDong
  • 2014年12月10日 23:27
  • 35344

ZooKeeper学习之配置【4】集群配置

当配置一个集群时,我们需要为每一个server配置好时间相关的参数,并指定一个server列表,这样server之间就能彼此连接并检测失败。这些配置必须在所有server中保持一致。   init...
  • damacheng
  • damacheng
  • 2015年01月04日 16:18
  • 863

ZooKeeper的三种角色

上周有人和我说,有篇讲怎么调zk API的水文都上了csdn首页,我表示相当无奈,毕竟大多数人看一门技术就是想知道怎么调API,很少有人去了解内部机制。而懂不懂原理,恰恰是码农和架构师的最大区别。我肯...
  • mayp1
  • mayp1
  • 2016年07月25日 19:32
  • 3798

zookeeper的leader选举和最大故障节点数

法定数量是通过严格意义上的多数节点来表示的。在集合体中,可以包含一个节点,但它不是一个高可用和可靠的系统。如果在集合体中有两个节点,那么这两个节点都必须已经启动并让服务正常运行,因为两个节点中的一个并...
  • Dream_Flying_BJ
  • Dream_Flying_BJ
  • 2017年06月13日 15:55
  • 657

【分布式】Zookeeper的Leader选举-选举过程介绍比较清晰

http://www.cnblogs.com/leesf456/p/6107600.html 一、前言   前面学习了Zookeeper服务端的相关细节,其中对于集群启动而言,很重要的一部分就是Le...
  • gaoshan12345678910
  • gaoshan12345678910
  • 2017年03月28日 16:52
  • 2041
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ZooKeeper leader election
举报原因:
原因补充:

(最多只允许输入30个字)