ZooKeeper系列(一)—— ZooKeeper 简介及核心概念

1、Zookeeper简介

Zookeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护。Zookeeper 能够用于实现分布式系统中常见的发布/订阅、负载均衡、命令服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。它具备如下特性:node

  • 顺序一致性:从一个客户端发起的事务请求,最终都会严格按照其发起顺序被应用到 Zookeeper 中;
  • 原子性:全部事务请求的处理结果在整个集群中全部机器上都是一致的;不存在部分机器应用了该事务,而另外一部分没有应用的状况;
  • 单一视图:全部客户端看到的服务端数据模型都是一致的;
  • 可靠性:一旦服务端成功应用了一个事务,则其引发的改变会一直保留,直到被另一个事务所更改;
  • 实时性:一旦一个事务被成功应用后,Zookeeper 能够保证客户端当即能够读取到这个事务变动后的最新状态的数据。

2、Zookeeper设计目标

Zookeeper 致力于为那些高吞吐的大型分布式系统提供一个高性能、高可用、且具备严格顺序访问控制能力的分布式协调服务。它具备如下四个目标:git

2.1 目标一:简单的数据模型

Zookeeper 经过树形结构来存储数据,它由一系列被称为 ZNode 的数据节点组成,相似于常见的文件系统。不过和常见的文件系统不一样,Zookeeper 将数据全量存储在内存中,以此来实现高吞吐,减小访问延迟。github

2.2 目标二:构建集群

能够由一组 Zookeeper 服务构成 Zookeeper 集群,集群中每台机器都会单独在内存中维护自身的状态,而且每台机器之间都保持着通信,只要集群中有半数机器可以正常工做,那么整个集群就能够正常提供服务。服务器

2.3 目标三:顺序访问

对于来自客户端的每一个更新请求,Zookeeper 都会分配一个全局惟一的递增 ID,这个 ID 反映了全部事务请求的前后顺序。网络

2.4 目标四:高性能高可用

ZooKeeper 将数据存全量储在内存中以保持高性能,并经过服务集群来实现高可用,因为 Zookeeper 的全部更新和删除都是基于事务的,因此其在读多写少的应用场景中有着很高的性能表现。session

3、核心概念

3.1 集群角色

Zookeeper 集群中的机器分为如下三种角色:数据结构

  • Leader :为客户端提供读写服务,并维护集群状态,它是由集群选举所产生的;
  • Follower :为客户端提供读写服务,并按期向 Leader 汇报本身的节点状态。同时也参与写操做“过半写成功”的策略和 Leader 的选举;
  • Observer :为客户端提供读写服务,并按期向 Leader 汇报本身的节点状态,但不参与写操做“过半写成功”的策略和 Leader 的选举,所以 Observer 能够在不影响写性能的状况下提高集群的读性能。

3.2 会话

Zookeeper 客户端经过 TCP 长链接链接到服务集群,会话 (Session) 从第一次链接开始就已经创建,以后经过心跳检测机制来保持有效的会话状态。经过这个链接,客户端能够发送请求并接收响应,同时也能够接收到 Watch 事件的通知。架构

关于会话中另一个核心的概念是 sessionTimeOut(会话超时时间),当因为网络故障或者客户端主动断开等缘由,致使链接断开,此时只要在会话超时时间以内从新创建链接,则以前建立的会话依然有效。负载均衡

3.3 数据节点

Zookeeper 数据模型是由一系列基本数据单元 Znode(数据节点) 组成的节点树,其中根节点为 /。每一个节点上都会保存本身的数据和节点信息。Zookeeper 中节点能够分为两大类:框架

  • 持久节点 :节点一旦建立,除非被主动删除,不然一直存在;
  • 临时节点 :一旦建立该节点的客户端会话失效,则全部该客户端建立的临时节点都会被删除。

临时节点和持久节点均可以添加一个特殊的属性:SEQUENTIAL,表明该节点是否具备递增属性。若是指定该属性,那么在这个节点建立时,Zookeeper 会自动在其节点名称后面追加一个由父节点维护的递增数字。

3.4 节点信息

每一个 ZNode 节点在存储数据的同时,都会维护一个叫作 Stat 的数据结构,里面存储了关于该节点的所有状态信息。以下:

状态属性 说明
czxid 数据节点建立时的事务 ID
ctime 数据节点建立时的时间
mzxid 数据节点最后一次更新时的事务 ID
mtime 数据节点最后一次更新时的时间
pzxid 数据节点的子节点最后一次被修改时的事务 ID
cversion 子节点的更改次数
version 节点数据的更改次数
aversion 节点的 ACL 的更改次数
ephemeralOwner 若是节点是临时节点,则表示建立该节点的会话的 SessionID;若是节点是持久节点,则该属性值为 0
dataLength 数据内容的长度
numChildren 数据节点当前的子节点个数

3.5 Watcher

Zookeeper 中一个经常使用的功能是 Watcher(事件监听器),它容许用户在指定节点上针对感兴趣的事件注册监听,当事件发生时,监听器会被触发,并将事件信息推送到客户端。该机制是 Zookeeper 实现分布式协调服务的重要特性。

3.6 ACL

Zookeeper 采用 ACL(Access Control Lists) 策略来进行权限控制,相似于 UNIX 文件系统的权限控制。它定义了以下五种权限:

  • CREATE:容许建立子节点;
  • READ:容许从节点获取数据并列出其子节点;
  • WRITE:容许为节点设置数据;
  • DELETE:容许删除子节点;
  • ADMIN:容许为节点设置权限。

4、ZAB协议

4.1 ZAB协议与数据一致性

ZAB 协议是 Zookeeper 专门设计的一种支持崩溃恢复的原子广播协议。经过该协议,Zookeepe 基于主从模式的系统架构来保持集群中各个副本之间数据的一致性。具体以下:

Zookeeper 使用一个单一的主进程来接收并处理客户端的全部事务请求,并采用原子广播协议将数据状态的变动以事务 Proposal 的形式广播到全部的副本进程上去。以下图:

具体流程以下:

全部的事务请求必须由惟一的 Leader 服务来处理,Leader 服务将事务请求转换为事务 Proposal,并将该 Proposal 分发给集群中全部的 Follower 服务。若是有半数的 Follower 服务进行了正确的反馈,那么 Leader 就会再次向全部的 Follower 发出 Commit 消息,要求将前一个 Proposal 进行提交。

4.2 ZAB协议的内容

ZAB 协议包括两种基本的模式,分别是崩溃恢复和消息广播:

1. 崩溃恢复

当整个服务框架在启动过程当中,或者当 Leader 服务器出现异常时,ZAB 协议就会进入恢复模式,经过过半选举机制产生新的 Leader,以后其余机器将重新的 Leader 上同步状态,当有过半机器完成状态同步后,就退出恢复模式,进入消息广播模式。

2. 消息广播

ZAB 协议的消息广播过程使用的是原子广播协议。在整个消息的广播过程当中,Leader 服务器会每一个事物请求生成对应的 Proposal,并为其分配一个全局惟一的递增的事务 ID(ZXID),以后再对其进行广播。具体过程以下:

Leader 服务会为每个 Follower 服务器分配一个单独的队列,而后将事务 Proposal 依次放入队列中,并根据 FIFO(先进先出) 的策略进行消息发送。Follower 服务在接收到 Proposal 后,会将其以事务日志的形式写入本地磁盘中,并在写入成功后反馈给 Leader 一个 Ack 响应。当 Leader 接收到超过半数 Follower 的 Ack 响应后,就会广播一个 Commit 消息给全部的 Follower 以通知其进行事务提交,以后 Leader 自身也会完成对事务的提交。而每个 Follower 则在接收到 Commit 消息后,完成事务的提交。

5、Zookeeper的典型应用场景

5.1数据的发布/订阅

数据的发布/订阅系统,一般也用做配置中心。在分布式系统中,你可能有成千上万个服务节点,若是想要对全部服务的某项配置进行更改,因为数据节点过多,你不可逐台进行修改,而应该在设计时采用统一的配置中心。以后发布者只须要将新的配置发送到配置中心,全部服务节点便可自动下载并进行更新,从而实现配置的集中管理和动态更新。

Zookeeper 经过 Watcher 机制能够实现数据的发布和订阅。分布式系统的全部的服务节点能够对某个 ZNode 注册监听,以后只须要将新的配置写入该 ZNode,全部服务节点都会收到该事件。

5.2 命名服务

在分布式系统中,一般须要一个全局惟一的名字,如生成全局惟一的订单号等,Zookeeper 能够经过顺序节点的特性来生成全局惟一 ID,从而能够对分布式系统提供命名服务。

5.3 Master选举

分布式系统一个重要的模式就是主从模式 (Master/Salves),Zookeeper 能够用于该模式下的 Matser 选举。可让全部服务节点去竞争性地建立同一个 ZNode,因为 Zookeeper 不能有路径相同的 ZNode,必然只有一个服务节点可以建立成功,这样该服务节点就能够成为 Master 节点。

5.4 分布式锁

能够经过 Zookeeper 的临时节点和 Watcher 机制来实现分布式锁,这里以排它锁为例进行说明:

分布式系统的全部服务节点能够竞争性地去建立同一个临时 ZNode,因为 Zookeeper 不能有路径相同的 ZNode,必然只有一个服务节点可以建立成功,此时能够认为该节点得到了锁。其余没有得到锁的服务节点经过在该 ZNode 上注册监听,从而当锁释放时再去竞争得到锁。锁的释放状况有如下两种:

  • 当正常执行完业务逻辑后,客户端主动将临时 ZNode 删除,此时锁被释放;
  • 当得到锁的客户端发生宕机时,临时 ZNode 会被自动删除,此时认为锁已经释放。

当锁被释放后,其余服务节点则再次去竞争性地进行建立,但每次都只有一个服务节点可以获取到锁,这就是排他锁。

5.5 集群管理

Zookeeper 还能解决大多数分布式系统中的问题:

  • 如能够经过建立临时节点来创建心跳检测机制。若是分布式系统的某个服务节点宕机了,则其持有的会话会超时,此时该临时节点会被删除,相应的监听事件就会被触发。
  • 分布式系统的每一个服务节点还能够将本身的节点状态写入临时节点,从而完成状态报告或节点工做进度汇报。
  • 经过数据的订阅和发布功能,Zookeeper 还能对分布式系统进行模块的解耦和任务的调度。
  • 经过监听机制,还能对分布式系统的服务节点进行动态上下线,从而实现服务的动态扩容。


参考资料

  1. 倪超 . 从 Paxos 到 Zookeeper——分布式一致性原理与实践 . 电子工业出版社 . 2015-02-01

更多大数据系列文章能够参见 GitHub 开源项目大数据入门指南

相关文章
相关标签/搜索