关于java:入门ZooKeeper-相关概念总结

6次阅读

共计 8418 个字符,预计需要花费 22 分钟才能阅读完成。

1. 前言

置信大家对 ZooKeeper 应该不算生疏。然而你真的理解 ZooKeeper 到底有啥用不?如果他人 / 面试官让你给他讲讲对于 ZooKeeper 的意识,你能答复到什么境地呢?

拿我本人来说吧!我自己已经应用 Dubbo 来做分布式我的项目的时候,应用了 ZooKeeper 作为注册核心。为了保障分布式系统可能同步拜访某个资源,我还应用 ZooKeeper 做过分布式锁。另外,我在学习 Kafka 的时候,晓得 Kafka 很多性能的实现依赖了 ZooKeeper。

前几天,总结我的项目教训的时候,我忽然问本人 ZooKeeper 到底是个什么货色?想了半天,脑海中只是简略的能浮现出几句话:

  1. ZooKeeper 能够被用作注册核心、分布式锁;
  2. ZooKeeper 是 Hadoop 生态系统的一员;
  3. 构建 ZooKeeper 集群的时候,应用的服务器最好是奇数台。

由此可见,我对于 ZooKeeper 的了解仅仅是停留在了外表。

所以,通过本文,心愿带大家略微具体的理解一下 ZooKeeper。如果没有学过 ZooKeeper,那么本文将会是你进入 ZooKeeper 大门的垫脚砖。如果你曾经接触过 ZooKeeper,那么本文将带你回顾一下 ZooKeeper 的一些根底概念。

另外,本文不光会波及到 ZooKeeper 的一些概念,前面的文章会介绍到 ZooKeeper 常见命令的应用以及应用 Apache Curator 作为 ZooKeeper 的客户端。

如果文章有任何须要改善和欠缺的中央,欢送在评论区指出,共同进步!

2. ZooKeeper 介绍

2.1. ZooKeeper 由来

正式介绍 ZooKeeper 之前,咱们先来看看 ZooKeeper 的由来,还挺有意思的。

上面这段内容摘自《从 Paxos 到 ZooKeeper》第四章第一节,举荐大家浏览一下:

ZooKeeper 最早起源于雅虎研究院的一个钻研小组。在过后,钻研人员发现,在雅虎外部很多大型零碎根本都须要依赖一个相似的零碎来进行分布式协调,然而这些零碎往往都存在分布式单点问题。所以,雅虎的开发人员就试图开发一个通用的无单点问题的分布式协调框架,以便让开发人员将精力集中在解决业务逻辑上。

对于“ZooKeeper”这个我的项目的名字,其实也有一段趣闻。在立项初期,思考到之前外部很多我的项目都是应用动物的名字来命名的(例如驰名的 Pig 我的项目), 雅虎的工程师心愿给这个我的项目也取一个动物的名字。时任研究院的首席科学家 RaghuRamakrishnan 开玩笑地说:“在这样上来,咱们这儿就变成动物园了!”此话一出,大家纷纷表示就叫动物园管理员吧一一一因为各个以动物命名的分布式组件放在一起,雅虎的整个分布式系统看上去就像一个大型的动物园了,而 ZooKeeper 正好要用来进行分布式环境的协调一一于是,ZooKeeper 的名字也就由此诞生了。

2.2. ZooKeeper 概览

ZooKeeper 是一个开源的 分布式协调服务,它的设计指标是将那些简单且容易出错的分布式一致性服务封装起来,形成一个高效牢靠的原语集,并以一系列简略易用的接口提供给用户应用。

原语: 操作系统或计算机网络用语领域。是由若干条指令组成的,用于实现肯定性能的一个过程。具备不可分割性·即原语的执行必须是间断的,在执行过程中不容许被中断。

ZooKeeper 为咱们提供了高可用、高性能、稳固的分布式数据一致性解决方案,通常被用于实现诸如数据公布 / 订阅、负载平衡、命名服务、分布式协调 / 告诉、集群治理、Master 选举、分布式锁和分布式队列等性能。

另外,ZooKeeper 将数据保留在内存中,性能是十分棒的。在“读”多于“写”的应用程序中尤其地高性能,因为“写”会导致所有的服务器间同步状态。(“读”多于“写”是协调服务的典型场景)。

2.3. ZooKeeper 特点

  • 程序一致性: 从同一客户端发动的事务申请,最终将会严格地依照程序被利用到 ZooKeeper 中去。
  • 原子性: 所有事务申请的处理结果在整个集群中所有机器上的利用状况是统一的,也就是说,要么整个集群中所有的机器都胜利利用了某一个事务,要么都没有利用。
  • 繁多零碎映像: 无论客户端连到哪一个 ZooKeeper 服务器上,其看到的服务端数据模型都是统一的。
  • 可靠性: 一旦一次更改申请被利用,更改的后果就会被长久化,直到被下一次更改笼罩。

2.4. ZooKeeper 典型利用场景

ZooKeeper 概览中,咱们介绍到应用其通常被用于实现诸如数据公布 / 订阅、负载平衡、命名服务、分布式协调 / 告诉、集群治理、Master 选举、分布式锁和分布式队列等性能。

上面选 3 个典型的利用场景来专门说说:

  1. 分布式锁:通过创立惟一节点取得分布式锁,当取得锁的一方执行完相干代码或者是挂掉之后就开释锁。
  2. 命名服务:能够通过 ZooKeeper 的程序节点生成全局惟一 ID
  3. 数据公布 / 订阅:通过 Watcher 机制 能够很不便地实现数据公布 / 订阅。当你将数据公布到 ZooKeeper 被监听的节点上,其余机器可通过监听 ZooKeeper 上节点的变动来实现配置的动静更新。

实际上,这些性能的实现根本都得益于 ZooKeeper 能够保留数据的性能,然而 ZooKeeper 不适宜保留大量数据,这一点须要留神。

2.5. 有哪些驰名的开源我的项目用到了 ZooKeeper?

  1. Kafka : ZooKeeper 次要为 Kafka 提供 Broker 和 Topic 的注册以及多个 Partition 的负载平衡等性能。
  2. Hbase : ZooKeeper 为 Hbase 提供确保整个集群只有一个 Master 以及保留和提供 regionserver 状态信息(是否在线)等性能。
  3. Hadoop : ZooKeeper 为 Namenode 提供高可用反对。

3. ZooKeeper 重要概念解读

破音:拿出小本本,上面的内容十分重要哦!

3.1. Data model(数据模型)

ZooKeeper 数据模型采纳层次化的多叉树形构造,每个节点上都能够存储数据,这些数据能够是数字、字符串或者是二级制序列。并且。每个节点还能够领有 N 个子节点,最上层是根节点以“/”来代表。每个数据节点在 ZooKeeper 中被称为 znode,它是 ZooKeeper 中数据的最小单元。并且,每个 znode 都一个惟一的门路标识。

强调一句:ZooKeeper 次要是用来协调服务的,而不是用来存储业务数据的,所以不要放比拟大的数据在 znode 上,ZooKeeper 给出的下限是每个结点的数据大小最大是 1M。

从下图能够更直观地看出:ZooKeeper 节点门路标识形式和 Unix 文件系统门路十分类似,都是由一系列应用斜杠 ”/” 进行宰割的门路示意,开发人员能够向这个节点中写人数据,也能够在节点上面创立子节点。这些操作咱们前面都会介绍到。

3.2. znode(数据节点)

介绍了 ZooKeeper 树形数据模型之后,咱们晓得每个数据节点在 ZooKeeper 中被称为 znode,它是 ZooKeeper 中数据的最小单元。你要寄存的数据就放在下面,是你应用 ZooKeeper 过程中常常须要接触到的一个概念。

3.2.1. znode 4 种类型

咱们通常是将 znode 分为 4 大类:

  • 长久(PERSISTENT)节点:一旦创立就始终存在即便 ZooKeeper 集群宕机,直到将其删除。
  • 长期(EPHEMERAL)节点 :长期节点的生命周期是与 客户端会话(session) 绑定的,会话隐没则节点隐没 。并且, 长期节点只能做叶子节点,不能创立子节点。
  • 长久程序(PERSISTENT_SEQUENTIAL)节点:除了具备长久(PERSISTENT)节点的个性之外,子节点的名称还具备程序性。比方 /node1/app0000000001/node1/app0000000002
  • 长期程序(EPHEMERAL_SEQUENTIAL)节点:除了具备长期(EPHEMERAL)节点的个性之外,子节点的名称还具备程序性。

3.2.2. znode 数据结构

每个 znode 由 2 局部组成:

  • stat:状态信息
  • data:节点寄存的数据的具体内容

如下所示,我通过 get 命令来获取 根目录下的 dubbo 节点的内容。(get 命令在上面会介绍到)。

[zk: 127.0.0.1:2181(CONNECTED) 6] get /dubbo
# 该数据节点关联的数据内容为空
null
# 上面是该数据节点的一些状态信息,其实就是 Stat 对象的格式化输入
cZxid = 0x2
ctime = Tue Nov 27 11:05:34 CST 2018
mZxid = 0x2
mtime = Tue Nov 27 11:05:34 CST 2018
pZxid = 0x3
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1

Stat 类中蕴含了一个数据节点的所有状态信息的字段,包含事务 ID-cZxid、节点创立工夫 -ctime 和子节点个数 -numChildren 等等。

上面咱们来看一下每个 znode 状态信息到底代表的是什么吧!(上面的内容来源于《从 Paxos 到 ZooKeeper 分布式一致性原理与实际》,因为 Guide 的确也不是特地分明,要学会参考资料的嘛!):

znode 状态信息 解释
cZxid create ZXID,即该数据节点被创立时的事务 id
ctime create time,即该节点的创立工夫
mZxid modified ZXID,即该节点最终一次更新时的事务 id
mtime modified time,即该节点最初一次的更新工夫
pZxid 该节点的子节点列表最初一次批改时的事务 id,只有子节点列表变更才会更新 pZxid,子节点内容变更不会更新
cversion 子节点版本号,以后节点的子节点每次变动时值减少 1
dataVersion 数据节点内容版本号,节点创立时为 0,每更新一次节点内容 (不论内容有无变动) 该版本号的值减少 1
aclVersion 节点的 ACL 版本号,示意该节点 ACL 信息变更次数
ephemeralOwner 创立该长期节点的会话的 sessionId;如果以后节点为长久节点,则 ephemeralOwner=0
dataLength 数据节点内容长度
numChildren 以后节点的子节点个数

3.3. 版本(version)

在后面咱们曾经提到,对应于每个 znode,ZooKeeper 都会为其保护一个叫作 Stat 的数据结构,Stat 中记录了这个 znode 的三个相干的版本:

  • dataVersion:以后 znode 节点的版本号
  • cversion:以后 znode 子节点的版本
  • aclVersion:以后 znode 的 ACL 的版本。

3.4. ACL(权限管制)

ZooKeeper 采纳 ACL(AccessControlLists)策略来进行权限管制,相似于 UNIX 文件系统的权限管制。

对于 znode 操作的权限,ZooKeeper 提供了以下 5 种:

  • CREATE : 能创立子节点
  • READ:能获取节点数据和列出其子节点
  • WRITE : 能设置 / 更新节点数据
  • DELETE : 能删除子节点
  • ADMIN : 能设置节点 ACL 的权限

其中尤其须要留神的是,CREATEDELETE 这两种权限都是针对 子节点 的权限管制。

对于身份认证,提供了以下几种形式:

  • world:默认形式,所有用户都可无条件拜访。
  • auth : 不应用任何 id,代表任何已认证的用户。
  • digest : 用户名: 明码认证形式:username:password
  • ip : 对指定 ip 进行限度。

3.5. Watcher(事件监听器)

Watcher(事件监听器),是 ZooKeeper 中的一个很重要的个性。ZooKeeper 容许用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候,ZooKeeper 服务端会将事件告诉到感兴趣的客户端下来,该机制是 ZooKeeper 实现分布式协调服务的重要个性。

破音:十分有用的一个个性,都能出小本本记好了,前面用到 ZooKeeper 根本离不开 Watcher(事件监听器)机制。

3.6. 会话(Session)

Session 能够看作是 ZooKeeper 服务器与客户端的之间的一个 TCP 长连贯,通过这个连贯,客户端可能通过心跳检测与服务器放弃无效的会话,也可能向 ZooKeeper 服务器发送申请并承受响应,同时还可能通过该连贯接管来自服务器的 Watcher 事件告诉。

Session 有一个属性叫做:sessionTimeoutsessionTimeout 代表会话的超时工夫。当因为服务器压力太大、网络故障或是客户端被动断开连接等各种起因导致客户端连贯断开时,只有在 sessionTimeout 规定的工夫内可能从新连贯上集群中任意一台服务器,那么之前创立的会话依然无效。

另外,在为客户端创立会话之前,服务端首先会为每个客户端都调配一个 sessionID。因为 sessionID是 ZooKeeper 会话的一个重要标识,许多与会话相干的运行机制都是基于这个 sessionID 的,因而,无论是哪台服务器为客户端调配的 sessionID,都务必保障全局惟一。

4. ZooKeeper 集群

为了保障高可用,最好是以集群状态来部署 ZooKeeper,这样只有集群中大部分机器是可用的(可能容忍肯定的机器故障),那么 ZooKeeper 自身依然是可用的。通常 3 台服务器就能够形成一个 ZooKeeper 集群了。ZooKeeper 官网提供的架构图就是一个 ZooKeeper 集群整体对外提供服务。

上图中每一个 Server 代表一个装置 ZooKeeper 服务的服务器。组成 ZooKeeper 服务的服务器都会在内存中保护以后的服务器状态,并且每台服务器之间都相互放弃着通信。集群间通过 ZAB 协定(ZooKeeper Atomic Broadcast)来保持数据的一致性。

最典型集群模式:Master/Slave 模式(主备模式)。在这种模式中,通常 Master 服务器作为主服务器提供写服务,其余的 Slave 服务器从服务器通过异步复制的形式获取 Master 服务器最新的数据提供读服务。

4.1. ZooKeeper 集群角色

然而,在 ZooKeeper 中没有抉择传统的 Master/Slave 概念,而是引入了 Leader、Follower 和 Observer 三种角色。如下图所示

ZooKeeper 集群中的所有机器通过一个 Leader 选举过程 来选定一台称为“Leader”的机器,Leader 既能够为客户端提供写服务又能提供读服务。除了 Leader 外,FollowerObserver 都只能提供读服务。Follower 和 Observer 惟一的区别在于 Observer 机器不参加 Leader 的选举过程,也不参加写操作的“过半写胜利”策略,因而 Observer 机器能够在不影响写性能的状况下晋升集群的读性能。

角色 阐明
Leader 为客户端提供读和写的服务,负责投票的发动和决定,更新零碎状态。
Follower 为客户端提供读服务,如果是写服务则转发给 Leader。在选举过程中参加投票。
Observer 为客户端提供读服务器,如果是写服务则转发给 Leader。不参加选举过程中的投票,也不参加“过半写胜利”策略。在不影响写性能的状况下晋升集群的读性能。此角色于 ZooKeeper3.3 系列新增的角色。

当 Leader 服务器呈现网络中断、解体退出与重启等异常情况时,就会进入 Leader 选举过程,这个过程会选举产生新的 Leader 服务器。

这个过程大抵是这样的:

  1. Leader election(选举阶段):节点在一开始都处于选举阶段,只有有一个节点失去超半数节点的票数,它就能够入选准 leader。
  2. Discovery(发现阶段):在这个阶段,followers 跟准 leader 进行通信,同步 followers 最近接管的事务提议。
  3. Synchronization(同步阶段) : 同步阶段次要是利用 leader 前一阶段取得的最新提议历史,同步集群中所有的正本。同步实现之后 准 leader 才会成为真正的 leader。
  4. Broadcast(播送阶段) : 到了这个阶段,ZooKeeper 集群能力正式对外提供事务服务,并且 leader 能够进行音讯播送。同时如果有新的节点退出,还须要对新节点进行同步。

4.2. ZooKeeper 集群中的服务器状态

  • LOOKING:寻找 Leader。
  • LEADING:Leader 状态,对应的节点为 Leader。
  • FOLLOWING:Follower 状态,对应的节点为 Follower。
  • OBSERVING:Observer 状态,对应节点为 Observer,该节点不参加 Leader 选举。

4.3. ZooKeeper 集群为啥最好奇数台?

ZooKeeper 集群在宕掉几个 ZooKeeper 服务器之后,如果剩下的 ZooKeeper 服务器个数大于宕掉的个数的话整个 ZooKeeper 才仍然可用。如果咱们的集群中有 n 台 ZooKeeper 服务器,那么也就是剩下的服务数必须大于 n/2。先说一下论断,2n 和 2n-1 的容忍度是一样的,都是 n-1,大家能够先本人认真想一想,这应该是一个很简略的数学问题了。比方如果咱们有 3 台,那么最大容许宕掉 1 台 ZooKeeper 服务器,如果咱们有 4 台的的时候也同样只容许宕掉 1 台。如果咱们有 5 台,那么最大容许宕掉 2 台 ZooKeeper 服务器,如果咱们有 6 台的的时候也同样只容许宕掉 2 台。

综上,何必减少那一个不必要的 ZooKeeper 呢?

5. ZAB 协定和 Paxos 算法

Paxos 算法应该能够说是 ZooKeeper 的灵魂了。然而,ZooKeeper 并没有齐全采纳 Paxos 算法,而是应用 ZAB 协定作为其保证数据一致性的外围算法。另外,在 ZooKeeper 的官网文档中也指出,ZAB 协定并不像 Paxos 算法那样,是一种通用的分布式一致性算法,它是一种特地为 Zookeeper 设计的解体可复原的原子音讯播送算法。

5.1. ZAB 协定介绍

ZAB(ZooKeeper Atomic Broadcast 原子播送)协定是为分布式协调服务 ZooKeeper 专门设计的一种反对解体复原的原子播送协定。在 ZooKeeper 中,次要依赖 ZAB 协定来实现分布式数据一致性,基于该协定,ZooKeeper 实现了一种主备模式的零碎架构来放弃集群中各个正本之间的数据一致性。

5.2. ZAB 协定两种根本的模式:解体复原和音讯播送

ZAB 协定包含两种根本的模式,别离是

  • 解体复原 :当整个服务框架在启动过程中,或是当 Leader 服务器呈现网络中断、解体退出与重启等异常情况时,ZAB 协定就会进入恢复模式并选举产生新的 Leader 服务器。当选举产生了新的 Leader 服务器,同时集群中曾经有过半的机器与该 Leader 服务器实现了状态同步之后,ZAB 协定就会退出恢复模式。其中, 所谓的状态同步是指数据同步,用来保障集群中存在过半的机器可能和 Leader 服务器的数据状态保持一致
  • 音讯播送 当集群中曾经有过半的 Follower 服务器实现了和 Leader 服务器的状态同步,那么整个服务框架就能够进入音讯播送模式了。 当一台同样恪守 ZAB 协定的服务器启动后退出到集群中时,如果此时集群中曾经存在一个 Leader 服务器在负责进行音讯播送,那么新退出的服务器就会盲目地进入数据恢复模式:找到 Leader 所在的服务器,并与其进行数据同步,而后一起参加到音讯播送流程中去。

对于 ZAB 协定 &Paxos 算法 须要讲和了解的货色太多了,具体能够看上面这两篇文章:

  • 图解 Paxos 一致性协定
  • Zookeeper ZAB 协定剖析

6. 总结

  1. ZooKeeper 自身就是一个分布式程序(只有半数以上节点存活,ZooKeeper 就能失常服务)。
  2. 为了保障高可用,最好是以集群状态来部署 ZooKeeper,这样只有集群中大部分机器是可用的(可能容忍肯定的机器故障),那么 ZooKeeper 自身依然是可用的。
  3. ZooKeeper 将数据保留在内存中,这也就保障了 高吞吐量和低提早(然而内存限度了可能存储的容量不太大,此限度也是放弃 znode 中存储的数据量较小的进一步起因)。
  4. ZooKeeper 是高性能的。在“读”多于“写”的应用程序中尤其地显著,因为“写”会导致所有的服务器间同步状态。(“读”多于“写”是协调服务的典型场景。)
  5. ZooKeeper 有长期节点的概念。当创立长期节点的客户端会话始终放弃流动,刹时节点就始终存在。而当会话终结时,刹时节点被删除。长久节点是指一旦这个 znode 被创立了,除非被动进行 znode 的移除操作,否则这个 znode 将始终保留在 ZooKeeper 上。
  6. ZooKeeper 底层其实只提供了两个性能:① 治理(存储、读取)用户程序提交的数据;② 为用户程序提供数据节点监听服务。

7. 参考

  1. 《从 Paxos 到 ZooKeeper 分布式一致性原理与实际》
正文完
 0