zookeeper简述

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件

ZooKeeper 使用 Java 所编写,但是支持 Java 和 C 两种编程语言。

提供的功能包括:
        配置管理:集群中配置文件的同步
        分布式锁:解决分布式环境中数据同步问题
        集群管理:负载均衡,容灾处理等。
        命名服务:
        其他等等

1、zookeeper工作原理

Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。

为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。

每个Server在工作过程中有三种状态:
                LOOKING:当前Server不知道leader是谁,正在搜寻
                LEADING:当前Server即为选举出来的leader
                FOLLOWING:leader已经选举出来,当前Server与之同步

2、zookeeper数据同步过程:

选完leader以后,zk就进入状态同步过程。
1. leader等待server连接;
2 .Follower连接leader,将最大的zxid发送给leader;
3 .Leader根据follower的zxid确定同步点;
4 .完成同步后通知follower 已经成为uptodate状态;
5 .Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。
流程图如下所示:

3、zookeeper工作流程

1、Leader工作流程

Leader主要有三个功能:
        1 .恢复数据;
        2 .维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型;
       3 .Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。
        PING消息是指Learner的心跳信息;
        REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;
        ACK消息是Follower的对提议的回复,超过半数的Follower通过,则commit该提议;
        REVALIDATE消息是用来延长SESSION有效时间。

Leader的工作流程简图如下所示,在实际实现中,流程要比下图复杂得多,启动了三个线程来实现功能。

2、Follower工作流程

Follower主要有四个功能:
        1. 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
        2 .接收Leader消息并进行处理;
        3 .接收Client的请求,如果为写请求,发送给Leader进行投票;
        4 .返回Client结果。

Follower的消息循环处理如下几种来自Leader的消息:
        1 .PING消息:心跳消息;
        2 .PROPOSAL消息:Leader发起的提案,要求Follower投票;
        3 .COMMIT消息:服务器端最新一次提案的信息;
        4 .UPTODATE消息:表明同步完成;
        5 .REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
        6 .SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。

Follower的工作流程简图如下所示,在实际实现中,Follower是通过5个线程来实现功能的。

        observer流程和Follower的唯一不同的地方就是observer不会参加leader发起的投票。

4、zookeeper中session的状态

我们知道ZooKeeper允许客户端创建两种类型的节点:persistent、ephemeral,ephemeral类型的节点是与创建它的客户端一起共存亡的。

那么这中间就有问题,ZooKeeper是如何知道客户端还存不存在呢?

ZooKeeper是使用session来解决这个问题的,这也是为什么我们在客户端创建ZooKeeper实例时需要传入一个sessionout的参数。当客户端与Follower连接时,实际上是成功创建了一个session,Follower和Leader都保存了这个session信息(实际上Session的建立也是需要Leader同意的)。一方面,客户端会定期的向Follower发送Ping包来告诉这个Follower我还活着;另一方面,Leader也会定期向Follower发送ping包,一则检测它的Follower们是否至少有超过一半还活着,二则Follower们返回他们各自正在服务的客户端(未超时的session),来告诉Leader那些客户端还活着,这样Leader就可以删除那些客户端已经不存在的ephemeral类型的节点

5、zookeeper中的选举算法

我们有一个zookeeper集群,有好几个节点。每个节点都可以接收请求,处理请求。那么,如果这个时候分别有两个客户端向两个节点发起请求,请求的内容是修改同一个数据。比如客户端c1,请求节点n1,请求是set a = 1; 而客户端c2,请求节点n2,请求内容是set a = 2;
那么最后a是等于1还是等于2呢? 这在一个分布式环境里是很难确定的。解决这个问题有很多办法,而zookeeper的办法是,我们选一个总统出来,所有的这类决策都提交给总统一个人决策,那之前的问题不就没有了么。

如何在zookeeper集群中选举出一个leader,zookeeper使用了三种算法,具体使用哪种算法,在配置文件中是可以配置的,对应的配置项是”electionAlg”,其中1对应的是LeaderElection算法,2对应的是AuthFastLeaderElection算法,3对应的是FastLeaderElection算法.默认使用FastLeaderElection算法.

logicalclock -》逻辑时钟
Epoch -》 epoch,zxid的高32,表示leader的变动,选举的轮数,即逻辑时钟。Epoch会随着选举轮数的增加而递增。
zxid -》 事务id号,每个操作都有一个zxid, 64位
server id -》配置的myid,服务器编号

1、第一阶段:数据恢复阶段
        首先,每个在zookeeper服务器先读取当前保存在磁盘的数据,zookeeper中的每份数据,都有一个对应的id值,这个值是依次递增的,换言之,越新的数据,对应的ID值就越大.
2、第二阶段:首次发送自己投票信息
        在读取数据完毕之后,每个zookeeper服务器发送自己选举的leader,这个协议中包含了以下几部分的数据:
        2.1所选举leader的id(就是配置文件中写好的每个服务器的id) ,在初始阶段,每台服务器的这个值都是自己服务器的id,也就是它们都选举自己为leader.
        2.2 服务器最大数据的id,这个值大的服务器,说明存放了更新的数据.
        2.3逻辑时钟的值,这个值从0开始递增,每次选举对应一个值,也就是说
                2.3.1 如果在同一次选举中,那么这个值应该是一致的
                2.3.2 逻辑时钟值越大,说明这一次选举leader的进程更新.
        2.4 本机在当前选举过程中的状态,有以下几种:LOOKING,FOLLOWING,OBSERVING,LEADING。
3、第三阶段:接受其他机器的选举信息
        3.1如果所接收数据服务器的状态还是在选举阶段(LOOKING 状态),那么首先判断逻辑时钟值,又分为以下三种情况:
                3.1.1:如果发送过来的逻辑时钟大于目前的逻辑时钟,那么说明这是更新的一次选举,此时需要更新一下本机的逻辑时钟值,同时将之前收集到的来自其他服务器的选举清空,因为这些数据已经不再有效了.然后判断是否需要更新当前自己的选举情况.在这里是根据选举leader id,保存的最大数据id来进行判断的,这两种数据之间对这个选举结果的影响的权重关系是:首先看数据id,数据id大者胜出;其次再判断leader id,leader id大者胜出.然后再将自身最新的选举结果(也就是上面提到的三种数据广播给其他服务器)
                3.1.2: 发送过来数据的逻辑时钟小于本机的逻辑时钟,说明对方在一个相对较早的选举进程中,这里只需要将本机的数据发送过去就是了.
                3.1.3:两边的逻辑时钟相同,此时也只是调用totalOrderPredicate函数判断是否需要更新本机的数据(首先看数据id,数据id大者胜出;其次再判断leader id,leader id大者胜出.),如果更新了再将自己最新的选举结果广播出去就是了

3.2:三种情况的处理完毕之后,再处理两种情况:
                3.2.1:服务器判断是不是已经收集到了所有服务器的选举状态,如果是那么根据选举结果设置自己的角色(FOLLOWING还是LEADER),然后退出选举过程就是了.
                3.2.2:即使没有收集到所有服务器的选举状态,也可以判断一下根据以上过程之后最新的选举leader是不是得到了超过半数以上服务器的支持,如果是,那么尝试在200ms内接收一下数据,如果没有新的数据到来,说明大家都已经默认了这个结果,同样也设置角色退出选举过程.

3.3: 如果所接收服务器不在选举状态,也就是在FOLLOWING或者LEADING状态,做以下两个判断:
                3.3.1:如果逻辑时钟相同,将该数据保存到recvset,如果所接收服务器宣称自己是leader,那么将判断是不是有半数以上的服务器选举它,如果是则设置选举状态退出选举过程
                3.3.2 否则这是一条与当前逻辑时钟不符合的消息,那么说明在另一个选举过程中已经有了选举结果,于是将该选举结果加入到outofelection集合中,再根据outofelection来判断是否可以结束选举,如果可以也是保存逻辑时钟,设置选举状态,退出选举过程.(从这里可以看出,当某个节点已经确定选举结果不再处于LOOKING状态时,其收到LOOKING消息时都会直接回应选举的最终结果。结合上面那个比方,相当于某次选举结束了,这个时候来了选民4又发起一次新的选举,那么其他选民就直接告诉它当前的Leader情况)

zookeeper原理白话说明:

Paxos描述了这样一个场景,有一个叫做Paxos的小岛(Island)上面住了一批居民,岛上面所有的事情由一些特殊的人决定,他们叫做议员(Senator)。议员的总数(Senator Count)是确定的,不能更改。岛上每次环境事务的变更都需要通过一个提议(Proposal),每个提议都有一个编号(PID),这个编号是一直增长的,不能倒退。每个提议都需要超过半数((Senator Count)/2 +1)的议员同意才能生效。每个议员只会同意大于当前编号的提议,包括已生效的和未生效的。如果议员收到小于等于当前编号的提议,他会拒绝,并告知对方:你的提议已经有人提过了。这里的当前编号是每个议员在自己记事本上面记录的编号,他不断更新这个编号。整个议会不能保证所有议员记事本上的编号总是相同的。现在议会有一个目标:保证所有的议员对于提议都能达成一致的看法。

好,现在议会开始运作,所有议员一开始记事本上面记录的编号都是0。有一个议员发了一个提议:将电费设定为1元/度。他首先看了一下记事本,嗯,当前提议编号是0,那么我的这个提议的编号就是1,于是他给所有议员发消息:1号提议,设定电费1元/度。其他议员收到消息以后查了一下记事本,哦,当前提议编号是0,这个提议可接受,于是他记录下这个提议并回复:我接受你的1号提议,同时他在记事本上记录:当前提议编号为1。发起提议的议员收到了超过半数的回复,立即给所有人发通知:1号提议生效!收到的议员会修改他的记事本,将1好提议由记录改成正式的法令,当有人问他电费为多少时,他会查看法令并告诉对方:1元/度。

现在看冲突的解决:假设总共有三个议员S1-S3,S1和S2同时发起了一个提议:1号提议,设定电费。S1想设为1元/度, S2想设为2元/度。结果S3先收到了S1的提议,于是他做了和前面同样的操作。紧接着他又收到了S2的提议,结果他一查记事本,咦,这个提议的编号小于等于我的当前编号1,于是他拒绝了这个提议:对不起,这个提议先前提过了。于是S2的提议被拒绝,S1正式发布了提议: 1号提议生效。S2向S1或者S3打听并更新了1号法令的内容,然后他可以选择继续发起2号提议。

好,我觉得Paxos的精华就这么多内容。现在让我们来对号入座,看看在ZK Server里面Paxos是如何得以贯彻实施的

小岛(Island)——ZK Server Cluster
议员(Senator)——ZK Server
提议(Proposal)——ZNode Change(Create/Delete/SetData…)
提议编号(PID)——Zxid(ZooKeeper Transaction Id)
正式法令——所有ZNode及其数据

貌似关键的概念都能一一对应上,但是等一下,Paxos岛上的议员应该是人人平等的吧,而ZK Server好像有一个Leader的概念。没错,其实Leader的概念也应该属于Paxos范畴的。如果议员人人平等,在某种情况下会由于提议的冲突而产生一个“活锁”(所谓活锁我的理解是大家都没有死,都在动,但是一直解决不了冲突问题)。Paxos的作者Lamport在他的文章”The Part-Time Parliament“中阐述了这个问题并给出了解决方案——在所有议员中设立一个总统,只有总统有权发出提议,如果议员有自己的提议,必须发给总统并由总统来提出。好,我们又多了一个角色:总统。

总统——ZK Server Leader

又一个问题产生了,总统怎么选出来的?oh, my god! It’s a long story.
现在我们假设总统已经选好了,下面看看ZK Server是怎么实施的。
情况一:

屁民甲(Client)到某个议员(ZK Server)那里询问(Get)某条法令的情况(ZNode的数据),议员毫不犹豫的拿出他的记事本(local storage),查阅法令并告诉他结果,同时声明:我的数据不一定是最新的。你想要最新的数据?没问题,等着,等我找总统Sync一下再告诉你。

情况二:

屁民乙(Client)到某个议员(ZK Server)那里要求政府归还欠他的一万元钱,议员让他在办公室等着,自己将问题反映给了总统,总统询问所有议员的意见,多数议员表示欠屁民的钱一定要还,于是总统发表声明,从国库中拿出一万元还债,国库总资产由100万变成99万。屁民乙拿到钱回去了(Client函数返回)。

情况三:

总统突然挂了,议员接二连三的发现联系不上总统,于是各自发表声明,推选新的总统,总统大选期间政府停业,拒绝屁民的请求。

zookeeper基础整理相关推荐

  1. zookeeper基础知识整理

    http://blog.csdn.net/pelick/article/details/7269670 http://zookeeper.apache.org/doc/trunk/javaExampl ...

  2. zookeeper中展示所有节点_Zookeeper系列一:Zookeeper基础命令操作

    有些事不是努力就可以改变的,五十块的人民币设计的再好看,也没有一百块的招人喜欢. 前言 由于公司年底要更换办公地点,所以最近投了一下简历,发现面试官现在很喜欢问dubbo.zookeeper和高并发等 ...

  3. Zookeeper基础笔记

    基础信息 zookeeper的每个节点,既可以存储自身的数据,又可以扩展子节点.Zookeeper本身不提供序列化支持,我们可以使用Protobuf或者Thrift等协议把数据序列化处理. Zooke ...

  4. Zookeeper基础简介

    基础信息 zookeeper的每个节点,既可以存储自身的数据,又可以扩展子节点.Zookeeper本身不提供序列化支持,我们可以使用Protobuf或者Thrift等协议把数据序列化处理. Zooke ...

  5. 机器学习 —— 基础整理(六)线性判别函数:感知器、松弛算法、Ho-Kashyap算法...

    这篇总结继续复习分类问题.本文简单整理了以下内容: (一)线性判别函数与广义线性判别函数 (二)感知器 (三)松弛算法 (四)Ho-Kashyap算法 闲话:本篇是本系列[机器学习基础整理]在time ...

  6. 量子计算基础整理(上)

    量子计算基础整理 目录 量子计算基础整理 写在前面 量子力学基础 量子的四个特性 量子态的描述 定义 状态演化 叠加态与测量 相态,纯态和混合态 混合态的表示 可观测量与量子观测 复合系统与联合测量 ...

  7. ZooKeeper基础学习

    简介: ZooKeeper:为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如统一命名服务.配置管理和分布式锁等分布式的基础服务. Zookeeper介绍: 是一个开放源代码的分布式协调服务,设 ...

  8. lda 吗 样本中心化 需要_机器学习 —— 基础整理(四):特征提取之线性方法——主成分分析PCA、独立成分分析ICA、线性判别分析LDA...

    本文简单整理了以下内容: (一)维数灾难 (二)特征提取--线性方法 1. 主成分分析PCA 2. 独立成分分析ICA 3. 线性判别分析LDA (一)维数灾难(Curse of dimensiona ...

  9. 机器学习 —— 基础整理(一)贝叶斯决策论;二次判别函数;贝叶斯错误率;生成式模型的参数方法...

    本文简单整理了以下内容: (一)贝叶斯决策论:最小错误率决策.最小风险决策:经验风险与结构风险 (二)判别函数:生成式模型:多元高斯密度下的判别函数:线性判别函数LDF.二次判别函数QDF (三)贝叶 ...

最新文章

  1. 你哪来这么多事(五):职工信息插入
  2. 在mysql数据库中,文章表设计有啥好的思路
  3. Oracle 12c coming soon?
  4. 第三次组队赛 (DFSBFS)
  5. python蜡烛图预测_python tushare股票K线蜡烛图绘制
  6. Java设计模式之组合Composite模式代码示例
  7. SQL语句性能调整原则
  8. SWIFT(Society for Worldwide Interbank Financial SWIFT Telecommunications---环球同业银行金融电讯协会)
  9. hdu 4419 Colourful Rectangle (离散化扫描线线段树)
  10. 【APICloud系列|3】开发APP对UI的一般性要求
  11. JavaSE——面向对象进阶(封装、this、static、代码块、包、权限修饰符、main方法详解)
  12. ON DUPLICATE KEY UPDATE单个增加更新及批量增加更新的sql
  13. swift4.1 系统学习十 函数
  14. Java 网络教程: ServerSocket
  15. mysql去掉两个最高分_Excel函数 去掉最高分和最低分取平均值?这个函数不可不知...
  16. 猜姓氏c语言题目,猜姓氏的谜语及答案
  17. 如何完美的卸载Office2007?
  18. 获取access_token报错errcode: 40125,errmsg: invalid appsecret, view more at http://t.cn/RAEkdV
  19. 使用uiautomatorviewer报错Error obtaining UI hierarchy
  20. 「地埋式积水监测站」智慧防汛,科技先行

热门文章

  1. 循环队列的介绍与实现
  2. 配置 Docker 加速器
  3. 50 days before NOI2017
  4. weblogic启动受管服务器报错Authentication for user weblogic denied (weblogic 11g 域账号密码不生效的解决方法)...
  5. ios开发网络学习:一:NSURLConnection发送GET,POST请求
  6. 初步认识迭代服务器和并发服务器
  7. XML文档处理(树的应用)
  8. volatile关键字解析
  9. 【剑指offer】面试题55 - I. 二叉树的深度(java)
  10. java字符串数组排序_在Java中对字符串数组进行排序