Apache ZooKeeper是由Apache Hadoop的子项目发展而来,于2010年11月正式成为了Apache的顶级项目。git
ZooKeeper是一个开放源代码的分布式协调服务。它具备高性能、高可用的特色,同时也具备严格的顺序访问控制能力(主要是写操做的严格顺序性)。基于对ZAB协议(ZooKeeper Atomic Broadcast,ZooKeeper原子消息广播协议)的实现,它可以很好地保证分布式环境中数据的一致性。也正是基于这样的特性,使得ZooKeeper成为了解决分布式数据一致性问题的利器。github
ZooKeeper总体架构算法
请见上图,文字说明以下:数据库
ZooKeeper由两部分组成:ZooKeeper服务端和客户端。apache
ZooKeeper服务器采用集群的形式。值得一提的是,只要集群中存在超过一半的、处于正常工做状态的服务器,那么整个集群就可以正常对外服务。组成ZooKeeper集群的每台服务器都会在内存中维护当前的ZooKeeeper服务状态,而且每台服务器之间都互相保持着通讯。服务器
客户端在链接ZooKeeper服务集群时,会按照必定的随机算法选择集群中的某台服务器,而后和它共同建立一个TCP链接,使客户端连上到那台服务器。而当那台服务器失效时,客户端自动会从新选择另外一台服务器进行链接,从而保证服务的连续性。架构
当其中一个客户端修改数据时,ZooKeeper会将修改同步到集群中全部的服务器上,从而使链接到集群中其它服务器上的客户端也能当即看到修改后的数据,很好地保证了分布式环境中数据的一致性。负载均衡
ZooKeeper数据模型运维
请见上图,文字说明以下:分布式
Zookeeper的数据模型采用相似于文件系统的树结构。树上的每一个节点称为ZNode,而每一个节点均可能有一个或者多个子节点。ZNode的节点路径标识方式是由一系列斜杠【/】进行分割的路径表示。
能够向ZNode节点写入、修改、读取数据,也能够建立、删除ZNode节点或ZNode节点下的子节点。值得注意的是,ZooKeeper的设计目标不是传统的数据库存储或者大数据对象存储,而是协同数据的存储,所以在实现时ZNode存储的数据大小不该超过1MB。另外,每个节点都有个ACL(Access Control List,访问控制列表),据此控制该节点的访问权限。
ZNode数据节点是有生命周期的,其生命周期的长短取决于数据节点的节点类型。节点类型共有4种:持久节点(PERSISTENT)、持久顺序节点(PERSISTENT_SEQUENTIAL)、临时节点(EPHEMERAL)、临时顺序节点(EPHEMERAL_SEQUENTIAL)。
ZooKeeper的Watcher机制,归纳为三个过程:客户端注册Watcher成为订阅者、服务端处理Watcher以及客户端回调Watcher。
客户端在本身须要关注的位于ZooKeeper服务器里的ZNode节点上注册一个Watcher监听后,一旦这个ZNode节点发生变化,则在该节点上注册过Watcher监听的全部客户端会收到ZNode节点变化通知。在收到通知时,客户端经过回调Watcher作相应的处理,从而实现特定的功能。
经过对ZooKeeper中丰富的数据节点类型进行交叉使用,配合Watcher事件通知机制,能够很是方便地构建分布式应用中都会涉及的核心功能,如:数据发布/订阅(即配置中心)、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等。
Demo中的【ConfigServiceDemo(配置服务Demo)】适用于ZooKeeper的配置中心应用场景:
应用中用到的一些经常使用配置信息放到ZooKeeper的一系列ZNode节点上,供应用获取配置数据;同时,若是某应用在须要关注的配置项节点上注册了个Watcher,则之后每次被关注的配置项有更新的时候,都会实时通知到该应用,从而达到获取最新配置信息的目的。
a. 减小咱们的运维工做人员的工做量:当公司的应用程序以集群环境模式被部署的时候,若第1次部署应用程序或遇到须要配置新增/修改/删除的状况,咱们的运维工做人员不得不为集群中的每台服务器进行一台一台地修改。而利用了ZooKeeper后,他们只须要修改一次,就能为集群中的全部服务器完成配置新增/修改/删除。
b. 使任意客户端可以看到即时生效的被改后的配置数据:目前现状:因为运维工做人员须要为集群中的每台服务器进行一台一台地配置修改,而致使出现了配置延时问题,使得集群中的每台服务器的配置数据不一致。也就是说,客户端(如应用程序)可能会没法当即读取到最新的配置值,须要过段时间后才能读取到。当运维工做人员利用ZooKeeper修改配置数据后,新的配置数据会当即被同步到集群中的全部服务器,从而保证集群中的全部服务器的配置数据对于任意客户端而言每时每刻都是准确无误的(可选加Watcher)。
下图显示的是ZooKeeper配置服务页面。
咱们都知道,集群中的服务器通常只有1台起着Master角色。一旦这台具备Master角色的服务器出现宕机状况,则就出现了服务器单点故障问题。而且,咱们并不知道这台具备Master角色的服务器是从何时开始处于宕机状态。利用ZooKeeper的“对在ZooKeeper上建立的临时顺序节点(EPHEMERAL_SEQUENTIAL),一旦建立它的客户端与ZooKeeper服务集群之间的会话失效,那么该临时节点也就被自动清除”这一特性,再加上Watcher事件通知机制的使用,就可以解决服务器的单点故障问题——一旦当前具备Master角色的服务器宕机了,它建立的临时顺序节点(EPHEMERAL_SEQUENTIAL)会立刻消失;紧接着集群中注册过Watcher的全部服务器会立刻收到当前Master服务器已宕机的通知,而后将从新进行Master选举。