Zookeeper工做过程详解

1、Zookeeper工做机制

分布式和集中式系统相比,有不少优点,好比更强的计算能力,存储能力,避免单点故障等问题。可是因为在分布式部署的方式遇到网络故障等问题的时候怎么保证各个节点数据的一致性和可用性是比较关键的问题。node

那么,对于分布式集群来讲,咱们须要一个可以在各个服务和节点之间进行协调和服务的中间人——Zookeeper。linux

Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,负责存储和管理你们都关心的数据,而后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者作出相应的回应。设计模式

2、数据结构

Zookeeper的数据结构和linux的目录结构相似,也像数据结构中的树,以下图:服务器

Zookeeper的数据存储基于节点,这种节点称为Znode。Znode的引用方式是路径的引用,每一个Znode均可以经过其路径惟一标识。网络

其中Znode中包含有:数据,子节点引用,访问权限等,以下图:数据结构

  • data:Znode存储的数据信息
  • ACL:记录Znode的访问权限,即哪些人或哪些IP能够访问本节点
  • child:当前节点的子节点引用,相似于二叉树的左孩子右孩子
  • stat:包含Znode的各类元数据,好比事务ID、版本号、时间戳、大小等等

stat 查看根目录的详细信息:负载均衡

[zk: localhost:2181(CONNECTED) 0] stat /框架

cZxid = 0x0异步

ctime = Thu Jan 01 08:00:00 CST 1970分布式

mZxid = 0x0

mtime = Thu Jan 01 08:00:00 CST 1970

pZxid = 0x0

cversion = -1

dataVersion = 0

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 0

numChildren = 1

3、选举机制

Zookeeper集群是一主多从的模式,主为leader,从为follower,其中leader是经过选举获得。

Zookeeper集群有以下特色:

- Zookeeper:一个领导者(leader),多个跟随者(follower)组成的集群

- Leader负责进行投票的发起和决议,更新系统状态

- Follower用于接收客户请求并向客户端返回结果,在选举Leader过程当中参与投票

- 集群中只要有半数以上节点存活,Zookeeper集群就能正常服务,因此Zookeeper适合安装奇数台服务器

- 全局数据一致:每一个server保存一份相同的数据副本,client不管链接到哪一个server,数据都是一致的

- 更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行

- 数据更新原子性,一次数据更新要么成功,要么失败

- 实时性,在必定时间范围内,client能读到最新数据

Leader选举是保证分布式数据一致性的关键所在,当Zookeeper进入如下两种状态时,须要进入leader选举:

  1. 服务器初始化启动
  2. leader宕机挂掉

1. 服务器初始化启动时的选举

(1)以三台服务器组成的集群为例,在集群的初始化阶段,当server1启动时,其单独没法完成选举;当server2启动时,此时两台机器能够互相通讯,每台机器都试图找到leader,因而进入选举状态

(2)每一个server首先给本身投票:初始阶段,每一个服务器都将本身做为leader来投票,每次投票包含的信息有(myid,ZXID,epoch),此时Server1的投票为(1, 0),Server2的投票为(2, 0),而后各自将这个投票发给集群中其余机器

其中epoch用来判断多个投票是否在同一轮选举周期中,该值在服务端是一个自增序列,每次进入新一轮的投票后,都会对该值进行加1操做

(3)每一个server接受来自各个服务器的投票:集群的每一个服务器收到投票后,首先判断该投票的有效性,如检查是不是本轮投票、是否来自LOOKING状态的服务器

(4)处理投票。针对每个投票,服务器都须要将别人的投票和本身的投票进行PK,PK规则以下:

  • 优先检查ZXID。ZXID比较大的服务器优先做为Leader
  • 若是ZXID相同,那么就比较myid。myid较大的服务器做为Leader服务器

对于Server1而言,它的投票是(1, 0),接收Server2的投票为(2, 0),首先会比较二者的ZXID,均为0,再比较myid,此时Server2的myid最大,因而更新本身的投票为(2, 0),而后从新投票,对于Server2而言,其无须更新本身的投票,只是再次向集群中全部机器发出上一次投票信息便可

(5)统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于Server一、Server2而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出了Leader,一旦选出leader,后边的机器无论myid和ZXID多大,都自动成为leader的小弟

(6)改变服务器状态。一旦肯定了Leader,每一个服务器就会更新本身的状态,若是是Follower,那么就变动为FOLLOWING,若是是Leader,就变动为LEADING

2. leader服务器挂掉的投票机制

与启动时不一样的就是,每一个服务器上都有历史数据,在选举以前,首先非leader的服务器改变状态为LOOKING状态,由于运行期间每一个服务器ZXID不一样,会和启动时的选举同样进行从新投票选举。

4、监听机制

  1. 首先要有一个main()线程
  2. 在main线程中建立Zookeeper客户端,这时就会建立两个线程,一个负责网络链接通讯(connet),一个负责监听(listener)
  3. 经过connect线程将注册的监听事件发送给Zookeeper
  4. 在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中
  5. Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程
  6. listener线程内部调用了process()方法

5、API应用

Zookeeper经常使用的API以下:

create
建立节点

delete
删除节点

exists
判断节点是否存在

getData
得到一个节点的数据

setData
设置一个节点的数据

getChildren
获取节点下的全部子节点复制代码

这其中,exists,getData,getChildren属于读操做。Zookeeper客户端在请求读操做的时候,能够选择是否设置Watch

Watch是什么意思呢?

咱们能够理解成是注册在特定Znode上的触发器。当这个Znode发生改变,也就是调用了create,delete,setData方法的时候,将会触发Znode上注册的对应事件,请求Watch的客户端会接收到异步通知

具体交互过程以下:

  1. 客户端调用getData方法,watch参数是true。服务端接到请求,返回节点数据,而且在对应的哈希表里插入被Watch的Znode路径,以及Watcher列表。
  2. 当被Watch的Znode已删除,服务端会查找哈希表,找到该Znode对应的全部Watcher,异步通知客户端,而且删除哈希表中对应的Key-Value

6、应用场景

Zookeeper提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。

欢迎关注下方公众号,获取更多文章信息
1
相关文章
相关标签/搜索