zookeeper专栏

上一篇

主目录

下一篇



目录

  • 1 文件系统
  • 2 监听机制
  • 3 应用场景
  • 3.1 命名服务
  • 3.2 配置管理
  • 3.3 集群管理
  • 3.4 分布式锁
  • 3.5 队列管理



【前言】


zookeeper提供znode文件系统和监听机制。基于这znode文件系统和监听机制,可以实现命名服务、 配置管理、集群管理、分布式锁和队列管理等不同业务场景下的业务需求。


1 文件系统

ZooKeeper 的命名空间就是 ZooKeeper 应用的文件系统,它和 linux 的文件系统很像,也是树状,这样就可以确定每个路径都是唯一的,对于命名空间的操作必须都是绝对路径操作。与linux文件系统不同的是,linux文件系统有目录和文件的区别,而ZooKeeper统一叫做znode,一个 znode 节点可以包含子 znode,同时也可以包含数据。所以总结说来,znode 即是文件夹又是文件的概念,所以在 ZooKeeper 这里面就不叫文件文件也不叫文件夹,叫znode,每个znode有唯一的路径标识,既能存储数据,也能创建子znode。但是 znode 只适合存储非常小量的数据,不能超过 1M,最好小于 1K。

zookeeper log文件 snapshot文件能删除吗_客户端


下面是关于 Znode 的介绍(非常重要):

  1. Znode 有两种类型:

短暂(ephemeral)(断开连接自己删除)
持久(persistent) (断开连接不删除)

  1. Znode 有四种形式的目录节点(默认是 persistent )

类型

介绍

PERSISTENT

持久化 znode 节点,一旦创建这个 znode 点存储的数据不会主动消失,除非是客户端主动的 delete

PERSISTENT_SEQUENTIAL

自动增加顺序编号的 znode 节点,比如 ClientA 去 zk service 上建立一个 znode 名字叫做/zk/conf,指定了这种类型的节点后 zk 会创 建 /zk/conf0000000000 , ClientB 再 去 创 建 就 是 创 建/zk/conf0000000001,ClientC 是创建/zk/conf0000000002,以后任意 Client 来创建这个 znode 都会得到一个比当前 zk 命名空间最大 znode 编号+1 的 znode,也就说任意一个 Client 去创建 znode都是保证得到的 znode 是递增的,而且是唯一的

EPHEMERAL

临时 znode 节点,Client 连接到 zk service 的时候会建立一个session,之后用这个 zk 连接实例创建该类型的 znode,一旦 Client关闭了 zk 的连接,服务器就会清除 session,然后这个 session建立的 znode 节点都会从命名空间消失。总结就是,这个类型的znode 的生命周期是和 Client 建立的连接一样的。比如 ClientA创建了一个 EPHEMERAL 的/zk/conf0000000011 的 znode 节点,一旦 ClientA 的 zk 连接关闭,这个 znode 节点就会消失。整个 zk service 命名空间里就会删除这个 znode 节点

EPHEMERAL_SEQUENTIAL

临时自动编号节点,znode 节点编号会自动增加,但是会随session 消失而消失

  1. 创建 znode 时设置顺序标识,znode 名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护
  2. 在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序
  3. EPHEMERAL 类型的节点不能有子节点
  4. 客户端可以在 znode 上设置监听器

2 监听机制

客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目录节点增加删除)时,ZooKeeper 会通知客户端。监听机制保证 ZooKeeper 保存的任何的数据的任何改变都能快速的响应到监听了该节点的应用程序监听器的工作机制,其实是在客户端会专门创建一个监听线程,在客户端本机的一个端口上等待zk 集群发送过来事件
客户端会在zk集群注册监听某个znode的某个事件(数据改变、节点删除、子目录节点增加删除),这个事件的发生会触发该监听器的响应。

用来监听watch的方法api有三种:exit(),getData(),getChildren()
触发事件的类型有五种:create znode,create child,delete znode,delete child,setData znode

zookeeper log文件 snapshot文件能删除吗_文件系统_02


上表中

  • 监听某节点znode,其子节点的setData不会触发事件
  • getChildren方法能够监听到三个事件:create child时的NodeChildrenChanged、delete znode时的NodeDeleted、delete child时的NodeChildrenChanged
  • delete znode触发的事件NodeDeleted能够被三个监听方法响应:exit(),getData(),getChildren()

注意:监听只生效一次,如何做到循环监听?
在响应监听的process()方法中注册继续注册该同类型的监听

【监听工作原理】

ZooKeeper 的 Watcher 机制主要包括客户端线程、客户端WatcherManager、Zookeeper 服务器三部分。客户端在向 ZooKeeper 服务器注册的同时,会将 Watcher 对象存储在客户端的WatcherManager 当中。当 ZooKeeper 服务器触发 Watcher 事件后,会向客户端发送通知,客户端线程从 WatcherManager 中取出对应的 Watcher 对象来执行回调逻辑

zookeeper log文件 snapshot文件能删除吗_文件系统_03

监听使用方法:

/**
*  sessionID
   内部还有一个 WatchMaager  监听器管理器
*/
ZooKeeper zk = new ZooKeeper();
/**
*   哪个会话添加的监听
*   添加的监听是作用于在哪个znode节点上
*   该监听监听的事件是:NodeChildrenChanged
*/
List<String>  childNodeList = zk.getChildren("/zk", new Watcher(){
	/**
	*   当前这个process方法如果要响应一个监听,那么这个监听是当前这个会话创建的
	    这个监听到底是哪个znode上的什么事件??
		type = event.getEventType();
		path = event.getPath();
	    WatchedEvent event 就是zookeeper系统在意识到系统内的某个节点发了什么对应的变化之后就会给客户端发送的监听的通知
	*/
	public process(WatchedEvent event){
		type = event.getEventType();
		path = event.getPath();
		if(zk.getChildren().size = 5){
			startGame();
		}
		// 这个方法的内部就是 对应的监听的事件被响应了之后需要做的业务逻辑的代码编写的地方
	}
});
// 如果有其他的客户端触发了当前的这次会话所添加的某某监听,zookeeper系统就会发送对应的监听的通知到对应的客户端
//基于观察者设计模式实现的

3 应用场景

3.1 命名服务

命名服务是分布式系统中较为常见的一类场景,分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等,通过命名服务,客户端可以根据指定名字来获取资源的实体、服务地址和提供者的信息。Zookeeper 也可帮助应用系统通过资源引用的方式来实现对资源的定位和使用,广义上的命名服务的资源定位都不是真正意义上的实体资源,在分布式环境中,上层应用仅仅需要一个全局唯一的名字。Zookeeper 可以实现一套分布式全局唯一 ID 的分配机制。

zookeeper log文件 snapshot文件能删除吗_数据_04

3.2 配置管理

程序总是需要配置的,如果程序分散部署在多台机器上,要逐个改变配置就变得困难。现在把这些配置全部放到 ZooKeeper 上去,保存在 ZooKeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到ZooKeeper 的通知,然后从 ZooKeeper 获取新的配置信息应用到系统中就好

zookeeper log文件 snapshot文件能删除吗_文件系统_05

3.3 集群管理

集群管理包括两点:是否有机器退出和加入选举 master

对于第一点,所有机器约定在父目录 GroupMembers 下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 ZooKeeper 的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:有兄弟挂了。新机器加入也是类似,所有机器收到通知:新兄弟目录加入,又多了个新兄弟。

对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为 master 就好。当然,这只是其中的一种策略而已,选举策略完全可以由管理员自己制定。

zookeeper log文件 snapshot文件能删除吗_数据_06

3.4 分布式锁

有了 ZooKeeper 的一致性文件系统,锁的问题变得容易。
锁服务可以分为两三类

一个是写锁,对写加锁,保持独占,或者叫做排它锁,独占锁
一个是读锁,对读加锁,可共享访问,释放锁之后才可进行事务操作,也叫共享锁
一个是控制时序,叫时序锁

  • 对于写锁,我们将 ZooKeeper 上的一个 znode 看作是一把锁,通过 createznode 的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的 distribute_lock 节点就释放出锁
  • 对于读锁, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选 master 一样,编号最小的获得锁,用完删除,依次有序

3.5 队列管理

两种类型的队列:

1、同步队列:当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
2、先进先出队列:队列按照 FIFO方式进行入队和出队操作。

第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。

第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。

同步队列的流程图:

zookeeper log文件 snapshot文件能删除吗_数据_07