hadoop系列:zookeeper(2)——zookeeper核心原理(选举)
1、前述
上篇文章《hadoop系列:zookeeper(1)——zookeeper单点和集群安装》(http://blog.csdn.net/yinwenjie/article/details/47361419)我们介绍了zookeeper的两种安装方式。相信您的測试机或者VM上面已经有了一个可用的zookeeper环境了。
本文是zookeeper解说的第二篇文章。我们主要介绍zk中的重要基本原理。为后文给大家解说zk的java api使用打下基础。
不管您在工作中实际的角色是什么。假设您准备在实际工作中使用zookeeper技术,那么这篇文章介绍的基本原理您都应该了解。
2、zk的数据组织方式
首先我们在您的zk环境上使用zkCli.sh连接上去:
[root@vm2 ~]# zkCli.sh
Connecting to localhost:2181
2015-08-12 23:43:53,624 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT
2015-08-12 23:43:53,639 [myid:] - INFO [main:Environment@100] - Client environment:host.name=vm2
2015-08-12 23:43:53,639 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.7.0_71
2015-08-12 23:43:53,642 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
。。
。。。
。
。。
。。
。。
。。。。。
。
。
。。。。。
[zk: localhost:2181(CONNECTED) 0]
然后我们使用ls命令,查看zookeeperserver上的数据存储信息:
[zk: localhost:2181(CONNECTED) 1] ls /
[filesq, zookeeper]
当然您还能够使用非常多命令,例如以下:
connect host:port
get path [watch]
ls path [watch]
set path data [version]
rmr path
delquota [-n|-b] path
quit
printwatches on|off
create [-s] [-e] path data acl
stat path [watch]
close
ls2 path [watch]
history
listquota path
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
setquota -n|-b val path
假设您对以上命令感兴趣,能够查询zookeeper的官方文档去了解。
本文的内容我们将从ls命令得到的zookeeper中的数据结构讲开。
2.1、znode
依据本小结第一部分的描写叙述,非常显然zookeeper集群自身维护了一套数据结构。
这个存储结构是一个树形结构。其上的每个节点,我们称之为“znode”。
例如以下如所看到的:
每个znode默认能够存储1MB的数据(对于记录状态性质的数据来说。够了)
能够使用zkCli命令。登录到zookeeper上。并通过ls、create、delete、sync等命令操作这些znode节点
znode除了名称、数据以外,另一套属性:zxid。这套zid与时间戳相应,记录zid不同的状态(兴许我们将用到)
那么每个znode结构又是什么样的呢?例如以下图所看到的:
此外,znode还有操作权限。假设我们把以上几类属性细化。又能够得到下面属性的细节:
- czxid:创建节点的事务的zxid
- mzxid:对znode近期改动的zxid
- ctime:以距离时间原点(epoch)的毫秒数表示的znode创建时间
- mtime:以距离时间原点(epoch)的毫秒数表示的znode近期改动时间
- version:znode数据的改动次数
- cversion:znode子节点改动次数
- aversion:znode的ACL改动次数
- ephemeralOwner:假设znode是暂时节点。则指示节点全部者的会话ID;假设不是暂时节点。则为零。
- dataLength:znode数据长度。
- numChildren:znode子节点个数。
2.2、znode中的存在类型
我们知道了zookeeper内部维护了一套数据结构:由znode构成的集合。znode的集合又是一个树形结构。每个znode又有非常多属性进行描写叙述。而且znode的存在性还分为四类,例如以下如所看到的:
znode是由client创建的。它和创建它的client的内在联系,决定了它的存在性:
PERSISTENT-持久化节点:创建这个节点的client在与zookeeper服务的连接断开后,这个节点也不会被删除(除非您使用API强制删除)。
PERSISTENT_SEQUENTIAL-持久化顺序编号节点:当client请求创建这个节点A后,zookeeper会依据parent-znode的zxid状态。为这个A节点编写一个全文件夹唯一的编号(这个编号仅仅会一直增长)。当client与zookeeper服务的连接断开后。这个节点也不会被删除。
EPHEMERAL-暂时文件夹节点:创建这个节点的client在与zookeeper服务的连接断开后,这个节点(还有涉及到的子节点)就会被删除。
EPHEMERAL_SEQUENTIAL-暂时顺序编号文件夹节点:当client请求创建这个节点A后。zookeeper会依据parent-znode的zxid状态,为这个A节点编写一个全文件夹唯一的编号(这个编号仅仅会一直增长)。当创建这个节点的client与zookeeper服务的连接断开后,这个节点被删除。
另外,不管是EPHEMERAL还是EPHEMERAL_SEQUENTIAL节点类型,在zookeeper的client异常终止后,节点也会被删除。
3、zk中的选举FastLeaderELection
在上篇文章中,我们已经知道了一个zookeeper集群中。有一个处于leader身份的节点,其他的节点都是flower状态。
那么一个leader是怎么产生的呢?这就是zookeeper中的选举规则,默认的选举规则称为:FastLeaderELection(网上的资料还有提到另外的选举算法,实际上它们的核心思想都是一样的)
3.1、选举算法的中心思想
网上的资料有使用纯文字进行算法描写叙述的,也有使用流程图进行算法描写叙述的,可是假设读者不细致看,还是easy昏头转向,这里我们使用一张过程图和文字相结合的方式对FastLeaderELection选举算法进行描写叙述。
实际上FastLeaderELection说的中心思想无外乎下面几个关键点:
全天下我最牛,在我没有发现比我牛的推荐人的情况下,我就一直推举我当leader。第一次投票那必须推举我自己当leader。
每当我接收到其他的被推举者。我都要回馈一个信息。表明我还是不是推举我自己。
假设被推举者没我大,我就一直推举我当leader,是我是我还是我!
我有一个票箱, 和我属于同一轮的投票情况都在这个票箱里面。一人一票 反复的或者过期的票,我都不接受。
一旦我不再推举我自己了(这时我发现别人推举的人比我推荐的更牛),我就把我的票箱清空。又一次发起一轮投票(这时我的票箱一定有两票了。都是选的我觉得最牛的人)。
一旦我发现收到的推举信息中投票轮要高于我的投票轮,我也要清空我的票箱。而且还是投当初我觉得最牛的那个人(除非当前的人比我最初的推荐牛,我就顺带更新我的推荐)。
不断的反复上面的过程,不断的告诉别人“我的投票是第几轮”、“我推举的人是谁”。直到我的票箱中“我推举的最牛的人”收到了不少于 N /2 + 1的推举投票。
这时我就能够决定我是flower还是leader了(假设至始至终都是我最牛,那我就是leader咯。其他情况就是follower咯)。而且不论随后收到谁的投票,都向它直接反馈“我的结果”。
3.2、一张理想的图
那么我们依照以上的原则,进行一次投票。这是一个比較理想的状态,我们不考虑当中的网络延迟,不考虑启动zookeeper节点时本身的时间差,我们假设发出包的先后顺序,就是目标节点接受这些包的先后顺序。这个理想的过程中,我们同一时候开启5个zookeeper节点,让他们进行选举:
在第一轮中,依照“我最牛逼,我怕谁”的原则,每个节点都推荐它自己为集群的leader节点。
依照我们假设的理想条件,节点S1首先收到了S2发送来的推荐者“2”。节点S1发现“2”要比它之前推荐的“1”(也就是它自己)牛。依据谁牛推荐谁的原则,“S1”清空自己的票箱,又一次选举“2”(注意。此时“S1”的新票箱中已经有两票选举“2”了。一票是它自己,另外一票是”S2”,而且全部节点都是Looking状态)
相同的事情发生在“S2”身上:”S2”收到了”S3”发过来的推荐信息,发现“3”这个被推举者比之前自己推举的“2”要牛,于是也清空自己的票箱,发起一轮新的投票,此时“S2”选举“3”。
依次类推”S3”、”S4”。
这里要注意S5这个节点,在第一轮接受到了来源于“S1”——“S4”的推举者(一定注意,每一次接受信息,都会广播一次“我坚持推举的人”),发现“还是推荐的5最牛”。于是“我继续推举S5吧”。
以上这个过程在整个理想的网络环境上一直持续。
到了第四轮,“S1”收到了“S2”发送来的推举者“5”,发现“5”要比当前“S1”推荐的“4”要牛。
所以“S1”清空了自己的票箱。又一次推举“5”(发送给其他全部节点)。
关键的第五轮来了,我们再反复一下。经过之前的选举,如今“S2”——“S5”都已经推举“5”为Leader了,而且都处于第四轮。这时他们收到了”S1”发来的新的“第五轮”投票,于是都和之前一样,做相同的一件事:清空自己的票箱,又一次向其他全部节点广播自己的第五轮投票“5”。
于是,节点X,收到了大于N / 2 +1的选举“5”的投票。且都是第五轮投票。这样每个节点就都知道了自己的角色。。选举结束。全部将成为Follower状态的节点,向将要成为Leader的节点发起最后一次“工作是否正常”的询问。得到肯定的ack后。整个集群的工作状态就确认了。
3.3、实际上没有那么理想
关于上节的算法或者关于上上节的白话描写叙述,假设您一边没有看懂。请多看几遍。假设您看晕了,请歇息一下,清空脑袋。再看。选举算法的整个流程第一次是不好理解,可是一旦理解了当中的关键点,它就变得非常easy。
我们在上文中介绍的选举流程是基于一个主要的考虑:理想的网络环节,理想的节点处理能力。但其实。没有这种环境。网络情况的多变导致了我们须要让选举算法兼容各种的情况。
下面我们假设在选举的过程中,“S1”,“S2”两个节点出现了宕机的情况(或者是网络延迟,或者是网络物理层断开,不管您怎么想吧,反正其他节点再也收到”S1”,”S2”的投票信息了)。例如以下图所看到的:
上图所看到的。在第三轮的选举过程后,“S1”,“S2”两个节点就断开了,他们的投票信息根本没有发送出去。
这样一来。“S3”收到了“S4”,“S5”发来的投票信息。这时“S3”的票箱处于第3轮,而且发现了占大多数的投票结果:大家选举“S5”为Leader节点。
相同的事情也发生在“S4”身上。
这样“S3”,“S4”两个节点领先知道了投票结果,在最后一次询问Leader节点能否正常工作,并得到了肯定的ACK之后,“S3”,“S4”两个节点变成了Follower状态。
- 之后,不管“S3”,“S4”两个节点收到了不论什么节点的投票信息,都直接向源节点反馈投票结果,不会再进行投票了。
这样一来,在投票完毕后,“S1”,“S2”又一次连入后,尽管他们发起了投票,可是不会再收到投票反馈了。
直接依据“S3”或者“S4”发来的结果状态。变成Follower状态。
3.4、网上的资料
上图是网络上的一张选举过程图。步骤是怎么样的,笔者我就不再多说了,仅仅希望这个能辅助大家更好的理解选举过程。
哦,如今您知道为什么zookeeper在少于 N / 2 + 1的节点处于工作状态的情况下会崩溃了吧。由于。不管怎么选也没有不论什么节点能够获得 N / 2 + 1 的票数。
4、后文介绍
本来,我是希望这篇文章向大家说明包含zookeeper选举原理和zookeeper中的事件监听watcher原理在内的两个核心原理。
奈何。内容量已经超出了我的想象。这种话同一时候介绍两种原理不利于大家对知识点的吸收消化。
所以我决定zookeeper事件监听的watcher原理,在下一篇文章中再具体介绍,当然会包含演示样例代码。
敬请期待。
hadoop系列:zookeeper(2)——zookeeper核心原理(选举)的更多相关文章
- Hadoop 系列(八)—— 基于 ZooKeeper 搭建 Hadoop 高可用集群
一.高可用简介 Hadoop 高可用 (High Availability) 分为 HDFS 高可用和 YARN 高可用,两者的实现基本类似,但 HDFS NameNode 对数据存储及其一致性的要求 ...
- ZooKeeper系列(一)—— ZooKeeper 简介及核心概念
一.Zookeeper简介 Zookeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护.Zookeeper 可以用于实现分布式系统中常见的发布/订阅.负载均衡.命令服务.分布式协调 ...
- zookeeper核心原理全面解析
下述各zookeeper机制的java客户端实践参考zookeeper java客户端之curator详解. 官方文档http://zookeeper.apache.org/doc/current/z ...
- ZooKeeper系列(7):ZooKeeper一致性原理
一.ZooKeeper 的实现 1.1 ZooKeeper处理单点故障 我们知道可以通过ZooKeeper对分布式系统进行Master选举,来解决分布式系统的单点故障,如图所示. 图 1.1 ZooK ...
- Zookeeper核心原理
Zookeeper 的核心原理 Zookeeper 的由来 各个节点的数据一致性 怎么保证任务只在一个节点执行 如果orderserver1挂了,其他节点如何发现并接替 存在共享资源,互斥性.安全性 ...
- 深入了解Zookeeper核心原理
之前的文章Zookeeper基础原理&应用场景详解中将Zookeeper的基本原理及其应用场景做了一个详细的介绍,虽然介绍了其底层的存储原理.如何使用Zookeeper来实现分布式锁.但是我认 ...
- Zookeeper概论(对zookeeper的概论、原理、架构等的理解)
Zookeeper概论(对zookeeper的概论.原理.架构等的理解) 一.概论 Zookeeper是一个分布式的.开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是h ...
- zookeeper基本概念及原理
zookeeper是一个分布式的,开源的分布式应用程序,该程序主要用于管理其他分布式应用程序.其他分布式应用程序可以基于zookeeper实现数据同步,配置维护和命名服务等等.zookeeper是Ha ...
- ZooKeeper学习之路(一)—— ZooKeeper简介及核心概念
一.Zookeeper简介 Zookeeper是一个开源的分布式协调服务,目前由Apache进行维护.Zookeeper可以用于实现分布式系统中常见的发布/订阅.负载均衡.命令服务.分布式协调/通知. ...
随机推荐
- POJ 1948
这道题我记得是携程比赛上的一道. 开始时想直接设面积,但发现不可以,改设能否构成三角形.设dp[i][j][k]为前i根木棍构成边长为j和k的三角形,那么转移可以为dp[i][j][k]=dp[i-1 ...
- vehicle time series data analysis
以HADOOP为代表的云计算提供的仅仅是一个算法执行环境,为大数据的并行计算提供了在现有软硬件水平下最好的(近似)方法.并不能解决大数据应用中的全部问题.从详细应用而言,通过物联网方式接入IT圈的数据 ...
- IOC与DI区别
(1)IOC:控制反转,把对象创建交给spring进行配置. (2)DI:依赖注入,向类里面的属性中设置值. (3)关系:依赖注入不能单独存在,需要在IOC的基础之上完成操作.
- 0x27 A*
终于完全了解A*到底是什么玩意儿了 对于当前的决策,选取当前花费+预估花费最小来拓展. 因为假如预估出现失误,那么很可能就会延伸到一个错误的决策点,而这个决策点偏偏就是ed,而由于预估失误,其他点的当 ...
- vue.js和node.js的认识
首先vue.js 是库,不是框架,不是框架,不是框架. Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据. Vue.js 的核心是一个允许你 ...
- Centos6.5添加Epel和Remi源安装Lamp环境
想搭建一个Lamp环境,因为编译安装太麻烦,对于我这样的新手来说,太过于复杂.而CentOS自带的Apache.MySql和PHP的版本都太低,不想用.上百度搜了一轮,原来可以通过添加Epel和Rem ...
- SQL CASE WHEN语句性能优化
背景:性能应该是功能的一个重要参考,特别是在大数据的背景之下!写SQL语句时如果仅考虑业务逻辑,而不去考虑语句效率问题,有可能导致严重的效率问题,导致功能不可用或者资源消耗过大.其中的一种情况是,处理 ...
- CREATE TABLE 语句后的 ON [PRIMARY] 起什么作用
CREATE TABLE [dbo].[table1] ( [gh] [char] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ...
- 【XSY2988】取石子
题目来源:NOI2018模拟测试赛(二十六) 题解: 设a<b: 可以先考虑a=1的特殊情况,注意到后手的最优策略是跟着另外一个人取,取到最后剩余不到$a+b$时再看奇偶性: 那么很容易想到把所 ...
- rest-framework框架
rest-framework框架是Django里面非常重要的框架,但提到rest-framework框架就不得不说两种请求方式,那就是CBV和FBV. FBV(function base views) ...