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 election的更多相关文章

  1. Zookeeper 学习笔记之 Leader Election

    ZooKeeper四种节点类型: Persist Persist_Sequential Ephemeral Ephemeral_Sequential 在节点上可注册的Watch,客户端先得到通知再得到 ...

  2. [译]ZOOKEEPER RECIPES-Leader Election

    选主 使用ZooKeeper选主的一个简单方法是,在创建znode时使用Sequence和Ephemeral标志.主要思想是,使用一个znode,比如"/election",每个客 ...

  3. Leader Election 选举算法

    今天讲一讲分布式系统中必不可少的选举算法. leader 就是一堆服务器中的协调者,某一个时刻只能有一个leader且所有服务器都承认这个leader. leader election就是在一组进程中 ...

  4. Leader Election

    Leader Election Zookeeper的基本操作 Zookeeper虽然是分布式系统,但它并不是为文件存储而设计的,Zookeeper里存储的一般是配置信息和源信息.实际上,Zookeep ...

  5. Kafka学习笔记(4)----Kafka的Leader Election

    1. Zookeeper的基本操作 zookeeper中的节点可以持久化/有序的两个维度分为四种类型: PERSIST:持久化无序(保存在磁盘中) PERSIST_SEQUENTIAL:持久化有序递增 ...

  6. Kafka配置项unclean.leader.election.enable造成consumer出现offset重置现象

    消费端出现offset重置为latest, earliest现象,类似log: (org.apache.kafka.clients.consumer.internals.Fetcher.handleF ...

  7. zookeeper leader选举算法源码

    服务器状态 在QuorumPeer中有定义,这个类是一个线程. LOOKING:寻找Leader状态.处于该状态时,它会认为当前集群中没有Leader,进入选举流程. FOLLOWING: LEADI ...

  8. Zookeeper——分布式一致性协议及Zookeeper Leader选举原理

    文章目录 一.引言 二.从ACID到CAP/BASE 三.分布式一致性协议 1. 2PC和3PC 2PC 发起事务请求 事务提交/回滚 3PC canCommit preCommit doCommit ...

  9. zookeeper leader作用

    一个zookeeper 集群 只有一个leader: 类似master/slave模式 客户端提交请求之后,先发送到leader,leader作为接收者,广播到每个server 在folloer上创建 ...

随机推荐

  1. [ExtJS5学习笔记]第十七节 Extjs5的panel组件增加accodion成为折叠导航栏

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/39102335 官方例子:http://dev.sencha.com/ext/5.0.1 ...

  2. "ORA-20100: 为 FND_FILE 创建文件 o0003167.tmp 失败"

     今天在运行请求时候得到如下的错误日志: 原因:由于ORA-20100:为FND_FILE创建文件o0003167.tmp失败. 在请求日志的错误原因中您会找到更详细的信息. 查找了一些资料,总结 ...

  3. Java-IO之BufferedReader(字符缓冲输入流)

    BufferedReader是缓冲字符输入流,继承于Reader,BufferedReader的作用是为其他字符输入流添加一些缓冲功能. BufferedReader主要的函数列表: Buffered ...

  4. MyEclipse2014搭建JSF项目实例

    开发环境:  Windows2008 R2 64位 + MyEclipse Professional 2014 +JDK1.7+Tomcat7.0 搭建步骤: 1.打开MyEclipse2014后新建 ...

  5. 1049. Counting Ones (30)

    题目如下: The task is simple: given any positive integer N, you are supposed to count the total number o ...

  6. oracle 选取出现次数最多的前5条数据

    SELECT * FROM ( SELECT PROJECT_LISTING.MATERIAL, COUNT (*) AS "出现次数" FROM PROJECT_LISTING ...

  7. Windows Server2012R2 安装 SharePoint 2013 的必备组件

    Windows Server2012R2目前支持SharePoint Server 2013 with Service Pack 1 和 SharePoint Foundation 2013 with ...

  8. 《java入门第一季》之有趣的集合小案例---获取10个【1-20之间】的随机数,要求不能重复。

    import java.util.ArrayList; import java.util.Random; /* * 获取10个[1-20之间]的随机数,要求不能重复.(注意:不是获取10个数,如果单纯 ...

  9. Android自制浏览器WebView-android学习之旅(64)

    简单讲解如何使用WebView加载百度的网页 acticity代码 public class MainActivity extends Activity { private WebView webVi ...

  10. 网站开发进阶(三十五)JSP页面中的pageEncoding和contentType两种属性

    JSP页面中的pageEncoding和contentType两种属性 本文介绍了在JSP页面中经常用的两种属性,分别是pageEncoding和contentType,希望对你有帮助,一起来看. 关 ...