备战大三实习篇之 Zookeeper

Posted JF Coder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了备战大三实习篇之 Zookeeper相关的知识,希望对你有一定的参考价值。

ZooKeeper 提供了什么?

  1. 文件系统
  2. 通知机制

Zookeeper 文件系统

Zookeeper 提供一个多层级的节点命名空间(节点称为 znode)。与文件系统不同的是,这些节点都可以设置 关联的数据,而文件系统中只有文件节点可以存放数据而目录节点不行。Zookeeper 为了保证高吞吐和低延 迟,在内存中维护了这个树状的目录结构,这种特性使得 Zookeeper 不能用于存放大量的数据,每个节点的存 放数据上限为 1M。

四种类型的 znode

  1. PERSISTENT-持久化目录节点 客户端与 zookeeper 断开连接后,该节点依旧存在

  2. PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点 客户端与 zookeeper 断开连接后,该节点依旧存在,只是 Zookeeper 给该节点名称进行顺序编号

  3. EPHEMERAL-临时目录节点 客户端与 zookeeper 断开连接后,该节点被删除

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

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

Zonde通过路径引用,如同Unix中的文件路径。路径必须是绝对的,因此他们必须由斜杠字符来开头。除此以外,他们必须是唯一的,也就是说每一个路径只有一个表示,因此这些路径不能改变。在ZooKeeper中,路径由Unicode字符串组成,并且有一些限制。字符串"/zookeeper"用以保存管理信息,比如关键配额信息。

Zookeeper 通知机制

client 端会对某个 znode 建立一个 watcher 事件,当该 znode 发生变化时,这些 client 会收到 zk 的通知, 然后 client 可以根据 znode 变化来做出业务上的改变等。

Zookeeper 做了什么?

  1. 命名服务

命名服务是指通过指定的名字来获取资源或者服务的地址,利用 zk 创建一个全局的路径,即是唯一的路径,这
个路径就可以作为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。

  1. 配置管理

程序分布式的部署在不同的机器上,将程序的配置信息放在 zk 的 znode 下,当有配置发生改变时,也就是 znode
发生变化时,可以通过改变 zk 中某个目录节点的内容,利用 watcher 通知给各个客户端,从而更改配 置。

  1. 集群管理

所谓集群管理无在乎两点:是否有服务器退出和加入、选举 master。对于第一点,所有服务器约定在父目录下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有服务器挂掉,该服务器与 zookeeper 的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个 兄弟目录被删除,于是,所有服务器都知道:它上线了。
新服务器加入也是类似,所有服务器收到通知:新服务器目录加入,highcount 又有了,对于第二点,我们稍微改变一下,所有服务器创建临时顺序编号目录节点,每次选取编号最小的服务器作为 master 就好。

  1. 分布式锁

有了 zookeeper 的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控 制时序。 对于第一类,我们将zookeeper 上的一个 znode 看作是一把锁,通过 createznode 的方式来实现。所有客户 端都去创建/distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的 distribute_lock
节点就释放出锁。
对于第二类, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选 master 一样,编号最小的获得锁,用完删除,依次方便。

  1. 队列管理

两种类型的队列:

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

  2. 队列按照 FIFO 方式进行入队和出队操作。 第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。 第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。在特定的目录下创建 PERSISTENT_SEQUENTIAL
    节点,创建成功时 Watcher 通知等待的队列,队列删除序列号最小的节点用以 消费。此场景下 Zookeeper 的 znode用于消息存储,znode 存储的数据就是消息队列中的消息内容, SEQUENTIAL序列号就是消息的编号,按序取出即可。由于创建的节点是持久化的,所以不必担心队列消息的 丢失问题。

Zookeeper 工作原理

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

zookeeper 是如何选取主 leader 的?

当 leader 崩溃或者 leader 失去大多数的 follower,这时 zk 进入恢复模式,恢复模式需要重新选举出一个新的 leader,让所有的 Server 都恢复到一个正确的状态。Zk 的选举算法有两种:一种是基于 basic paxos 实现 的,另外一种是基于 fast paxos 算法实现的。系统默认的选举算法为 fast paxos。

zookeeper watch 机制

Watch 机制官方声明:一个 Watch 事件是一个一次性的触发器,当被设置了 Watch 的数据发生了改变的时 候,则服务器将这个改变发送给设置了 Watch 的客户端,以便通知它们。

Zookeeper 机制的特点:

  1. 一次性触发数据发生改变时,一个 watcher event 会被发送到 client,但是 client 只会收到一次这样的信 息。

  2. watcher event 异步发送 watcher 的通知事件从 server 发送到 client 是异步的,这就存在一个问题,不同 的客户端和服务器之间通过 socket 进行通信,由于网络延迟或其他因素导致客户端在不通的时刻监听到事件, 由于 Zookeeper 本身提供了 ordering guarantee,即客户端监听事件后,才会感知它所监视 znode 发生了 变化。所以我们使用 Zookeeper 不能期望能够监控到节点每次的变化。Zookeeper 只能保证最终的一致性, 而无法保证强一致性。

  3. 数据监视 Zookeeper 有数据监视和子数据监视 getdata() and exists()设置数据监视,getchildren()设置了 子节点监视。

  4. 注册 watcher getData、exists、getChildren

  5. 触发 watcher create、delete、setData

  6. setData()会触发 znode 上设置的 data watch(如果 set 成功的话)。一个成功的 create() 操作会触发被 创建的 znode 上的数据 watch,以及其父节点上的 child watch。而一个成功的 delete()操作将会同时触发一 个 znode 的 data watch 和 child watch(因为这样就没有子节点了),同时也会触发其父节点的 child watch。

  7. 当一个客户端连接到一个新的服务器上时,watch 将会被以任意会话事件触发。当与一个服务器失去连接的 时候,是无法接收到 watch 的。而当 client 重新连接时,如果需要的话,所有先前注册过的 watch,都会被重 新注册。通常这是完全透明的。只有在一个特殊情况下,watch 可能会丢失:对于一个未创建的 znode 的 exist watch,如果在客户端断开连接期间被创建了,并且随后在客户端连接上之前又删除了,这种情况下,这 个 watch 事件可能会被丢失。

  8. Watch 是轻量级的,其实就是本地 JVM 的 Callback,服务器端只是存了是否有设置了 Watcher 的布尔类 型

Zookeeper分布式锁

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

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

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

zookeeper实现分布式锁的原理就是多个节点同时在一个指定的节点下面创建临时会话顺序节点,谁创建的节点序号最小,谁就获得了锁,并且其他节点就会监听序号比自己小的节点,一旦序号比自己小的节点被删除了,其他节点就会得到相应的事件,然后查看自己是否为序号最小的节点,如果是,则获取锁

一键三连收藏


以上是关于备战大三实习篇之 Zookeeper的主要内容,如果未能解决你的问题,请参考以下文章

备战大三实习篇之 Zookeeper

大三萌新,给自己制定两个月的暑期实习准备计划!

大三萌新,给自己制定两个月的暑期实习准备计划!

秋招备战计划第一弹今天就开始备战秋招

秋招备战计划第一弹今天就开始备战秋招

双非大三,无实习经历,如何以 hard 模式逆袭字节跳动