Zookeeper 总结

 1.ZooKeeper是什么?

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是GoogleChubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。

2.应用场景

· 命名服务   

· 配置管理   

· 集群管理   

· 分布式锁  

· 队列管理

3.架构

4.设计目的

Zookeeper是一个高效的、可扩展的服务,readwrite操作都被设计为快速的,readwrite操作更快。

· 顺序一致性(Sequential Consistency):从一个客户端来的更新请求会被顺序执行。

· 原子性(Atomicity):更新要么成功要么失败,没有部分成功的情况。

· 唯一的系统镜像(Single System Image):无论客户端连接到哪个Server,看到系统镜像是一致的。

· 可靠性(Reliability):更新一旦有效,持续有效,直到被覆盖。

· 时间线(Timeliness):保证在一定的时间内各个客户端看到的系统信息是一致的。

5.数据模型

Zookeeper会维护一个具有层次关系的数据结构,它非常类似于一个标准的文件系统,如图所示:

 

树节点被称为znode。可以存储数据,有一个与之关联的ACL(AccessControlLists)。数据大小限制在1MB内。

(1) 引用方式

Zonde通过绝对路径引用,路径必须是绝对的、唯一的,必须由斜杠字符来开头。路径由Unicode字符串组成,字符串"/zookeeper"用以保存管理信息,比如关键配额信息。

(2) Znode组成

· ①stat:状态信息, 描述该Znode的版本, 权限,ACL(访问控制列表)等信息

· ②data:与该Znode关联的数据

· children:该Znode下的子节点

(3) 节点类型

· 临时节点:该节点的生命周期依赖于创建它们的会话。一旦会话(Session)结束,临时节点将被自动删除。临时节点不允许拥有子节点。

· 永久节点

· 顺序节点:当创建Znode的时候,用户可以请求在ZooKeeper的路径结尾添加一个递增的计数。这个计数对于此节点的父节点来说是唯一的,它的格式为"%10d"(10位数字,没有数值的数位用0补充,例如"0000000001")。当计数值大于2^32-1时,计数器将溢出。

6.Watcher

Watcher(事件监听器),是 ZooKeeper 中的一个很重要的特性。

ZooKeeper 允许用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候,ZooKeeper 服务端会将事件通知到感兴趣的客户端上去,该机制是 ZooKeeper 实现分布式协调服务的重要特性。

7.zxid (Zookeeper Transaction id)

致使ZooKeeper节点状态改变的每一个操作都将使节点接收到一个Zxid格式的时间戳,并且这个时间戳全局有序。它是一个64为数字。

8.Zookeeper的角色

  •  领导者(leader),负责进行投票的发起和决议,更新系统状态
  • 跟随者(follower),用于接受客户端请求并想客户端返回结果,在选主过程中参与投票
  •  观察者(observer),可以接受客户端连接,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度

9.读写数据过程

· 写过程

(1)Client向Zookeeper的server1发送一个写请求,客户端写数据到服务器1上;

(2)如果server1不是Leader,那么server1会把接收到的写请求转发给Leader;然后Leader会将写请求转发给每个server; server1和server2写数据成功后,通知Leader;

(3)当Leader收到集群半数以上的节点写成功的消息后,说明该写操作执行成功;为client访问的是server1,所以Leader会告知server1集群中数据写成功;

(4)被访问的server1进一步通知client数据写成功,这时,客户端就知道整个写操作成功了。

· 读过程

直接返回

10.工作原理

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

每个Server在工作过程中有三种状态:

· LOOKING:当前Server不知道leader是谁,正在搜寻

· LEADING:当前Server即为选举出来的leader

· FOLLOWING:leader已经选举出来,当前Server与之同步

11.选举过程

选举(Election)阶段必须确保选出的Leader具有highestZXID,在选举的过程中会对每个Follower节点的ZXID进行对比只有highestZXID的Follower才可能当选Leader。

 1. 服务器启动时期的Leader选举

  若进行Leader选举,则至少需要两台机器,这里选取3台机器组成的服务器集群为例。在集群初始化阶段,当有一台服务器Server1启动时,其单独无法进行和完成Leader选举,当第二台服务器Server2启动时,此时两台机器可以相互通信,每台机器都试图找到Leader,于是进入Leader选举过程。选举过程如下

  (1) 每个Server发出一个投票。由于是初始情况,Server1和Server2都会将自己作为Leader服务器来进行投票,每次投票会包含所推举的服务器的myid和ZXID,使用(myid, ZXID)来表示,此时Server1的投票为(1, 0),Server2的投票为(2, 0),然后各自将这个投票发给集群中其他机器。

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

  (3) 处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下

    · 优先检查ZXID。ZXID比较大的服务器优先作为Leader。

    · 如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。

  对于Server1而言,它的投票是(1, 0),接收Server2的投票为(2, 0),首先会比较两者的ZXID,均为0,再比较myid,此时Server2的myid最大,于是更新自己的投票为(2, 0),然后重新投票,对于Server2而言,其无须更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可。

  (4) 统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于Server1、Server2而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出了Leader。

  (5) 改变服务器状态。一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。

  2. 服务器运行时期的Leader选举

  在Zookeeper运行期间,一旦Leader服务器挂了,那么整个集群将暂停对外服务,进入新一轮Leader选举。假设正在运行的有Server1、Server2、Server3三台服务器,当前Leader是Server2,若某一时刻Leader挂了,此时便开始Leader选举。选举过程如下

  (1) 变更状态。Leader挂后,余下的非Observer服务器都会讲自己的服务器状态变更为LOOKING,然后开始进入Leader选举过程。

  (2) 每个Server会发出一个投票。在运行期间,每个服务器上的ZXID可能不同,此时假定Server1的ZXID为123,Server3的ZXID为122;在第一轮投票中,Server1和Server3都会投自己,产生投票(1, 123),(3, 122),然后各自将投票发送给集群中所有机器。

  (3) 接收来自各个服务器的投票。与启动时过程相同。

  (4) 处理投票。与启动时过程相同,此时,Server1将会成为Leader。

  (5) 统计投票。与启动时过程相同。

  (6) 改变服务器的状态。与启动时过程相同。

12.同步流程

选完leader以后,zk就进入状态同步过程。

1. leader等待server连接;

2 .Follower连接leader,将最大的zxid发送给leader;

3 .Leader根据follower的zxid确定同步点;

4 .Leader根据Follower发送过来的LastZXID根据数据更新策略向Follower发送更新指令;

5 .完成同步后通知follower 已经成为uptodate状态;

6 .Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。

同步策略:

1. SNAP :如果Follower数据太老,Leader将发送快照SNAP指令给Follower同步数据;

2. DIFF :Leader发送从Follolwer.lastZXID到Leader.lastZXID议案的DIFF指令给Follower同步数据;

3. TRUNC :当Follower.lastZXID比Leader.lastZXID大时,Leader发送从Leader.lastZXID到Follower.lastZXID的TRUNC指令让Follower丢弃该段数据;

13.广播(Broadcast)

客户端提交事务请求时Leader节点为每一个请求生成一个事务Proposal;

广播消息时Leader节点为每个事务Proposal分配一个全局递增的ZXID(事务ID),每个事务Proposal都按照ZXID顺序来处理;

Leader节点为每一个Follower节点分配一个队列按事务ZXID顺序放入到队列中,且根据队列的规则FIFO来进行事务的发送。Follower节点收到事务Proposal后会将该事务以事务日志方式写入到本地磁盘中,成功后反馈Ack消息给Leader节点,Leader在接收到过半Follower节点的Ack反馈后就会进行事务的提交,以此同时向所有的Follower节点广播Commit消息,Follower节点收到Commit后开始对事务进行提交;

原文地址:https://www.cnblogs.com/april-chen/p/11002400.html