一文带你理解zookeeper

前言

作为一名运维人员,有时经常会搭建一些中间件提供给开发人员使用,因为不是使用方,我们可能不是很熟悉这些中间件,但是我们需要维护中间件,总不能只是会搭建,肯定也要了解中间件的工作原理,这样才能在出现问题的时候更好的解决问题。在我所处的公司里,zookeeper就是由我们运维人员搭建及维护,由开发人员使用。一开始接触zookeeper,我尝试通过搜索引擎去了解zookeeper,但是看了不少文章还是理解不了zookeeper,所以就去系统学习了一下zookeeper。这里我会把我学习到zookeeper的知识结合应用场景来展开,希望能帮到想了解zookeeper的小伙伴。

1.zookeeper是什么

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:统一命名服务、统一配置管理、统一集群管理、分布式锁、软负载均衡等。

2.zookeeper的工作机制

要弄清楚zookeeper的工作机制,首先我们要了解zookeeper的文件系统和通知机制,因为zookeeper的功能都是靠它们实现的。

2.1 zookeeper文件系统

zookeeper的文件系统类似linux的文件系统,整体可以看作是一棵树,每个节点称作一个ZNode,但不同于linux文件系统的是,zookeeper的文件系统每个节点都能存储数据,每一个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。zookeeper的ZNode有四种类型,通知机制配合这四种ZNode类型实现zookeeper的各种功能。
image.png

2.2 ZNode类型

1、PERSISTENT-持久化目录节点
客户端与zookeeper断开连接后,该节点依旧存在
2、PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号,顺序编号是一个单调递增的计时器,由父节点维护。
3、EPHEMERAL-临时目录节点
客户端与zookeeper断开连接后,该节点被删除
4、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号,顺序编号是一个单调递增的计时器,由父节点维护。

2.3 zookeeper通知机制

client端会对某个znode建立一个监听事件,当该znode发生变化时,这些client会收到zk的通知,然后client可以根据znode变化来做出相应的反应。

2.4 zookeeper工作机制

zookeeper从设计模式角度来理解,是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,zookeeper就负责通知已经在zookeeper上注册的那些观察者做出相应的反应。

3.zookeeper特点

  1. zookeeper集群由一个领导者(Leader),多个跟随者(Follower)组成
  2. 集群中只要有半数以上节点存活,Zookeeper集群就能正常工作
  3. 全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的
  4. 有序性:来自同一个Client的更新请求按其发送顺序依次执行。有序性是zookeeper中非常重要的一个特性,所有的更新都是全局有序的,每个更新都有一个唯一的时间戳,这个时间戳称为zxid(Zookeeper Transaction Id)。而读请求只会相对于更新有序,也就是读请求的返回结果中会带有这个zookeeper最新的zxid
  5. 数据更新原子性:一次数据更新要么成功,要么失败
  6. 实时性:在一定时间范围内,Client能读到最新的数据

4.zookeeper应用场景

4.1 统一命名服务

统一命名服务只需要zookeeper的文件系统即可实现。命名服务是指通过指定的名字来获取资源或者服务的地址,利用zookeeper我们可以创建出唯一标识路径,这个路径就可以作为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。这个路径就好比是一个仓库,这个仓库的地址是唯一的,这些仓库里面存了一些东西,当我们来到这个仓库,我们就能取到仓库里的东西。

4.2 统一配置管理

在分布式的环境下,配置文件同步是非常常见的,一般要求一个集群中,所有节点的配置信息是一致的,比如kafka集群。对配置文件修改后,希望能够快速同步到各个节点上。这种情况下,就可以用zookeeper来做统一配置管理。
我们将程序的配置信息放在zk的znode下,当有配置发生改变时,也就是znode发生变化时,可以通过改变zk中某个目录节点的内容,利用watcher通知给各个客户端,从而更改配置。
image.png

4.3 集群管理

在分布式环境中,掌握集群中每个节点的状态是有必要的,我们用zookeeper做集群管理可以实现检测是否有机器加入或者退出,还可以用来选举集群的master。
要实现检测是否有机器退出,我们要在集群中的所有机器约定在父目录下创建临时目录节点,然后监听父目录节点的子节点变化情况。如果有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他的机器都将收到通知:这台机器离开了集群。检测是否有机器加入也是类似的过程。选举master的实现,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就可以了。
image.png

4.4 分布式锁

zookeeper实现分布式锁一般有两种方式。一种是保持独占,一种是控制时序。
保持独占的方式是这样实现的:我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock 节点就释放出锁。这种方式不适用于客户端数量很大的情况,因为当一个客户端拥有第一把锁之后,所有的客户端都要去监听节点,节点的释放也会通知所有的客户端,这样会出现羊群效应。
控制时序的方式是这样实现的:在这种方式下,/distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,编号最小的获得锁,没有获得锁的客户端监听编号比自己小的前一个节点,因为节点是顺序的,很容易找到自己的前一个节点,当监听到前一个节点删除节点释放锁,该客户端就会获得锁。这种方式避免了所有客户端需要监听一个节点和节点删除需要通知所有客户端的情况。

后话

这篇文章侧重解释zookeeper是什么,可以用来做什么,以及是怎么做到这些事情的。另外,zookeeper的选举机制和监听器原理都是学习zookeeper的重要知识,我这里暂时不展开了,有时间再补上。

参考:
zookeeper官网
尚硅谷Zookeeper教程(zookeeper框架精讲)
Zookeeper面试23连问,这些你都会吗?

阅读 140

推荐阅读