前言作为一名运维人员,有时候我们会经常搭建一些中间件供开发者使用。因为我们不是用户,可能对这些中间件不是很熟悉,但是我们需要对中间件进行维护。不能只搭建,还必须了解中间件的工作原理,这样才能在出现问题的时候更好的解决问题。在我所在的公司,zookeeper是我们运维人员搭建和维护的,开发人员使用的。刚开始接触zookeeper的时候,我试图通过搜索引擎来了解zookeeper,但是看了很多文章还是看不懂zookeeper,于是就去系统的学习了zookeeper。在这里我将所学的关于zookeeper的知识结合应用场景,希望对想了解zookeeper的朋友有所帮助。一、什么是zookeeperZooKeeper是一个分布式的、开源的分布式应用协调服务,是Google的Chubby的开源实现,是Hadoop和Hbase的重要组成部分。它是一种为分布式应用程序提供一致服务的软件。其功能包括:统一命名服务、统一配置管理、统一集群管理、分布式锁、软负载均衡等。2、zookeeper的工作机制要了解zookeeper的工作机制,首先要了解文件系统和通知机制zookeeper的,因为zookeeper的功能都是由他们实现的。2.1zookeeper文件系统zookeeper文件系统类似于linux文件系统。整体可以看成一棵树,每个节点称为一个ZNode。但是与linux文件系统不同的是,zookeeper文件系统的每个节点都可以存储Data,每个ZNode默认可以存储1MB的数据,每个ZNode可以通过其路径唯一标识。Zookeeper的ZNode有四种类型,通知机制配合这四种ZNode类型实现Zookeeper的各种功能。2.2ZNode类型1.PERSISTENT-持久目录节点客户端与zookeeper断开连接,节点仍然存在2.PERSISTENT_SEQUENTIAL-持久序列号目录节点客户端与zookeeper断开连接,节点仍然存在,仅Zookeeper按顺序编号节点名,以及序号是由父节点维护的单调递增定时器。3、EPHEMERAL-临时目录节点客户端与zookeeper断开连接后,该节点被删除。4.EPHEMERAL_SEQUENTIAL-临时序号目录节点客户端与zookeeper断开连接,节点被删除,但是zookeeper给节点名序号,序号是父节点维护的一个单调递增的定时器。2.3zookeeper通知机制客户端会对某个znode设置监听事件。当znode发生变化时,这些客户端会收到zk通知,然后客户端可以根据znode的变化做出相应的响应。2.4Zookeeper的工作机制Zookeeper是从设计模式的角度来理解的。它是一个基于观察者模式设计的分布式服务管理框架。它负责存储和管理大家关心的数据,然后接受观察者的注册。一旦这些数据的状态发生变化,zookeeper有责任通知那些已经在zookeeper上注册的观察者做出相应的响应。3.Zookeeper的特点Zookeeper集群由一个领导者(Leader)和多个追随者(Follower)组成。只要集群中一半以上的节点存活,Zookeeper集群就可以正常工作。全局数据一致性:每个服务器都保存一份相同的数据无论客户端连接到哪个服务器,数据的顺序都是一致的:来自同一个客户端的更新请求按照发送的顺序依次执行。排序是zookeeper中一个非常重要的特性。所有更新都是全局排序的,每个更新都有一个唯一的时间戳。这个时间戳称为zxid(ZookeeperTransactionId)。读请求只会相对于更新有序,即读请求的返回结果会包含zookeeper最新的zxid数据更新原子性:数据更新要么成功要么失败实时:一定时间内range,Client可以读取到最新的数据4.Zookeeper应用场景4.1统一命名服务统一命名服务只需要zookeeper的文件系统就可以实现。命名服务是指通过指定的名称获取资源或服务的地址。使用zookeeper,我们可以创建唯一标识路径。这个路径可以作为名字,指向集群中的集群,提供服务的地址,或者远程对象等。这条路就像一个仓库。这个仓库的地址是唯一的。这些仓库里存放着一些东西。来到这个仓库,我们就可以拿到仓库里的东西了。4.2统一配置管理在分布式环境中,同步配置文件是很常见的。一般要求一个集群中所有节点的配置信息一致,比如kafka集群。配置文件修改后,希望能快速同步到各个节点。这种情况下可以使用zookeeper进行统一的配置管理。我们把程序的配置信息放在zk的znode下。当配置发生变化时,即znode发生变化时,我们可以通过改变zk中某个目录节点的内容,使用watcher通知各个客户端来改变配置。.4.3集群管理在分布式环境中,需要掌握集群中各个节点的状态。我们使用zookeeper进行集群管理,检测机器是否加入或退出,也可以用来选举集群的master。检测某台机器是否退出,我们需要在集群中的所有机器上约定在父目录下创建一个临时目录节点,然后监听父目录节点的子节点的变化。如果一台机器挂了,这台机器和zookeeper的连接断开,它创建的临时目录节点被删除,同时通知所有其他机器:这台机器已经离开集群。检测机器是否加入是一个类似的过程。为了实现master的选举,我们做了一点改动。所有机器创建临时的顺序编号的目录节点,每次选择编号最小的机器作为master。4.4分布式锁Zookeeper一般有两种实现分布式锁的方式。一是保持独占,一是控制时序。保持独占性的方式是这样实现的:我们把zookeeper上的一个znode看成一把锁,通过createznode来实现。所有客户端创建一个/distribute_lock节点,创建成功的客户端最终拥有锁。删除自己创建的distribute_lock节点后释放锁。这种方式不适合客户端数量多的情况,因为当一个客户端拥有第一把锁的时候,所有的客户端都要监听这个节点,节点的释放也会通知所有的客户端,所以才会有Herding。控制时序的方式是这样实现的:这样,/distribute_lock是预先存在的,所有客户端在其下创建临时的顺序编号的目录节点,编号最小的获得锁,没有的客户端acquirethelockmonitors比自己多的前一个节点小,因为节点是有顺序的,所以很容易找到前一个节点。当听说前一个节点删除节点释放锁时,客户端就会获得锁。这种方法避免了所有客户端都需要监听一个节点以及通知所有客户端节点删除的需要。本文重点讲解什么是zookeeper,它可以用来做什么,以及如何做这些事情。另外,zookeeper的选举机制和listener原理是学习zookeeper的重要知识。这里暂时不展开,有空再补充。参考:zookeeper官网上硅谷Zookeeper教程(zookeeper框架精讲)Zookeeper面试23连问,这些你都知道吗?
