ZooKeeper简介

上文我们介绍过ZooKeeper的核心算法ZAB,也可以说是ZooKeeper的灵魂。本文我们从整体性来认识下ZooKeeper。

 

一、ZooKeeper是什么?

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户使用。

二、ZooKeeper设计目的

ZooKeeper保证如下分布式一致性特性。

1、最终一致性

client不论连接到哪个Server,展示给它都是同一个视图,这是ZooKeeper最重要的性能。 

2、可靠性

具有简单、健壮、良好的性能,如果消息被到一台服务器接受,那么它将被所有的服务器接受。

3、实时性

ZooKeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,ZooKeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。 

4、等待无关(wait-free)

慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。 

5、原子性

更新只能成功或者失败,没有中间状态。 

6、顺序性

包括全局有序和偏序两种:

全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;

偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。  

三、 ZooKeeper角色描述

ZooKeeper与客户端

四、ZooKeeper的特性

1、重要概念

(1)ZooKeeper本身就是一个分布式程序,主要半数以上节点存活,ZooKeeper就能正常服务。

(2)为了保证高可用,最好以集群方式不是ZooKeeper,这样只要集群中大部分机器是可用的,ZooKeeper本身仍然可用。

(3)ZooKeeper将数据保存在内存中,保证了高吞吐和低延迟,但是内存限制了能够存储的容量不太大,限制了Znode中存储的数据量较小的进一步原因。

(4)ZooKeeper是高性能的,在读多于写的应用程序中尤其的高性能,因为写会导致所有服务器同步状态。

(5)ZooKeeper有临时节点的概念,当创建临时节点的客户端会话一直保持活动,瞬时节点就一直存在,而当会话终结时,瞬时节点被删除。持久节点是指一旦这个Znode被创建,除非主动进行Znode的移除操作,否则这个Znode将一直保存在ZooKeeper上。

(6)ZooKeeper底层其实提供了两个功能,管理用户程序提交的数据(Znode);为用户程序提供节点监听服务(Watcher)

2、Seesion-会话

Session是指ZooKeeper服务器与客户端会话。在ZooKeeper中,一个客户端连接是指客户端和服务器之间的一个TCP长连接。客户端启动的时候,首先会与服务器建立一个TCP连接,从第一次连接建立开始,客户端会话的生命周期就开始了。通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够像ZooKeeper服务器发送请求并接受响应,同时还能够通过该连接接收来自服务器的Watch事件通知。

Session的sessionTimeout可以设置客户端会话的超时事件。由于服务压力大,网络故障或者客户端主动断开连接等各种原因导致客户端连接断开时,只要在sessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。

在为客户端创建会话之前,服务端首先会为每个客户端都分配一个sissionID,由于sessionID是ZooKeeper会话的一个重要标识,许多与会话相关的运行机制都是基于sessionID的,因此,无论是哪台服务器为客户端分配的sessionID,都需要保证全局唯一。

3、Znode

在ZooKeeper中,节点分为两类,第一类是指构成集群的机器,称为机器节点,第二类是指数据模型中的数据单元,称为数据节点-Znode。

ZooKeeper将所有数据存储在内存中,数据模型是一棵树,由/进行分割的路径,就是一个Znode,每个节点上都会保存自己的数据内容,同时还会保存一系列属性信息。

和Unix文件系统一样,我们能够自由的增加、删除Znode,在一个Znode下增加、删除子Znode,唯一的不同在于Znode是可以存储数据的。 

有四种类型的Znode: 

(1)PERSISTENT-持久化目录节点 

客户端与ZooKeeper断开连接后,该节点依旧存在 

(2)PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点 

客户端与ZooKeeper断开连接后,该节点依旧存在,只是ZooKeeper给该节点名称进行顺序编号 

(3)EPHEMERAL-临时目录节点 

客户端与ZooKeeper断开连接后,该节点被删除 

(4)EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点 

客户端与zookeeper断开连接后,该节点被删除,只是ZooKeeper给该节点名称进行顺序编号 

4、版本

ZooKeeper的每个Znode上都会存储数据,对应于每个Znode,ZooKeeper都会为其维护一个State数据结构,Stat中记录了这个Znode的三个数据版本,分别是Version-当前Znode的版本,cversion-当前Znode子节点的版本和aversion-当前Znode的ACL版本。

5、Watcher

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

客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。

6、ACL

ZooKeeper采用ACL策略来进行权限控制,分为:

(1)CREATE:创建子节点的权限。

(2)READ:获取节点数据和子节点列表的权限。

(3)WRITE:更新节点数据的权限。

(4)DELETE:删除子节点的权限。

(5)ADMIN:设置节点的ACL权限。

其中CREATE和DELETE这两种权限都是针对子节点的控制权限。

7、事务ID

在ZooKeeper中,事务是指能够改变ZooKeeper服务器状态的操作,我们也称之为事务操作或更新操作。包括以下五种类型:

(1)数据节点创建

(2)数据节点创建

(3)数据节点内容更改

(4)客户端会话创建

(5)客户端会话失效。 

对于每一个事务请求,ZooKeeper都会为其分配一个全局唯一的事务ID,用ZXID来表示。

五、ZooKeeper的典型应用

ZooKeeper主要是利用其Znode文件系统特性和Watcher监听事件两大特性来解决和实现分布式一致性问题。 

1、数据发布/订阅

数据发布/订阅系统即所谓的配置中心,也就是发布者将数据发布到ZooKeeper的一个节点或者一系列节点上,提供订阅者进行数据订阅,从而实现动态更新数据的目的,实现配置信息的集中式管理和数据的动态更新。ZooKeeper采用的是推拉相结合的方式:客户端向服务器注册自己需要关注的节点,一旦该节点的数据发生改变,那么服务端就会向相应的客户端发送Wacher事件通知,客户端接收到消息通知后,需要主动到服务端获取最新的数据。

实际系统开发过程中:我们可以将初始化配置信息放到节点上集中管理,应用在启动时都会主动到ZooKeeper服务端进行一次配置读取,同时在指定节点注册Watcher监听,主要配置信息一旦变更,订阅者就可以获取读取最新的配置信息。通常系统中需要使用一些通用的配置信息,比如机器列表信息、运行时的开关配置、数据库配置信息等全局配置信息,这些都会有以下3点特性:

(1)数据量通常比较小(通常是一些配置文件)

(2)数据内容在运行时会经常发生动态变化(比如数据库的临时切换等)

(3)集群中各机器共享,配置一致(比如数据库配置共享)。

利用的ZooKeeper特性是:ZooKeeper对任何节点(包括子节点)的变更,只要注册Wacther事件(使用Curator等客户端工具已经被封装好)都可以被其它客户端监听。

 

2、ZooKeeper命名服务

在ZooKeeper的文件系统里创建一个目录,即有唯一的path。在我们无法确定上游程序的部署机器时即可与下游程序约定好path,通过path即能互相探索发现确定命名空间的全局唯一。 

3、ZooKeeper集群管理

所谓集群管理无在乎两点:是否有机器退出和加入、选举master。 

对于第一点,所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与ZooKeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除。新机器加入也是类似,所有机器收到通知:新兄弟目录加入。

对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。

4、ZooKeeper分布式锁

有了ZooKeeper的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控制时序。 

对于第一类,我们将ZooKeeper上的一个Znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建/distribute_lock节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock节点就释放出锁。 

对于第二类,/distribute_lock已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次排序。

5、ZooKeeper队列管理

两种类型的队列:

1、同步队列

当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。

也称作,Barrier,分布式屏障。 

2、队列按照FIFO方式进行入队和出队操作。 

第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。 

第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。 

 

 

参考资料:

《从Paxos到ZooKeeper分布式一致性原理与实践》

https://blog.csdn.net/zhongqi2513/java/article/details/52435811

原文地址:https://www.cnblogs.com/orange-CC/p/13343579.html