zookeeper入门
一、zookeeper是什么
zookeeper是一个分布式的应用程序协调服务,目的是通过协调应用程序提供给用户简单易用的接口和功能稳定的系统。
Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
1.1 Zookeeper的角色
Leader:接受client请求,也接收其他Server转发的写请求,负责更新系统状态;
Follower:接收client请求,如果是写请求将转发给Leader来更新系统状态,读请求则由Follower的内存数据库直接响应,参与投票和选主;
Observer:接收client请求,如果是写请求将转发给Leader来更新系统状态,读请求则由Follower的内存数据库直接响应,不参与投票和选主,Observer是3.3.3版本以后引入的,主要解决伸缩性问题;
二、zookeeper提供了什么
文件系统
每个子目录例如serviceName被称为znode,和文件系统一样,我们可以自由的增加、删除znode,唯一不同的是znode可以存储数据。有四种类型的znode:持久化目录节点、持久化顺序编号目录节点、临时目录节点、临时顺序编号目录节点。临时目录节点在客户端和zookeeper连接中断后删除。
通知系统
客户端注册、监听它关心的目录节点,当目录节点发生变化(修改、删除、增加/删除子节点)时,zookeeper会通知客户端。
三、zookeeper做了什么
命名服务
其实就是我们常说的注册服务,在zookeeper的文件系统里创建一个目录,即有唯一的path。在我们无法确定上游程序的部署机器时即可与下游程序约定好path,通过path即能互相探索发现。
配置管理
程序是需要配置的,如果程序分散部署到多台机器上,要逐个改变配置就很困难。现在把这些配置放在zookeeper上,保存在zookeeper的某个目录节点上,然后每个相关的应用程序对这个目录节点进行监听,一旦配置信息发生改变,每个应用程序就会收到zookeeper的通知,然后从zookeeper获取新的配置信息应用到系统中。
集群管理
集群管理关注两点:是否有机器退出或者加入,选举master。首先解释一下什么是选举Master,集群管理是指管理多个提供服务的节点,一般集群采用master、slave的结构,一台主机多台备机,主机向外提供服务,备机负责监听主机的状态,一旦主机宕机,备机要迅速替代主机对外提供服务,从备机中选举一台作为主机的过程就是master选举。
对于是否有机器退出或者加入,所有机器在父目录GroupMembers下创建临时目录节点,然后监听父目录中子节点变化的消息,一旦有机器挂掉,那么与zookeeper的连接中断,临时目录就会被删除,其他机器收到通知:某个兄弟目录被删除,说明它宕机了。
对于选举Master,可以通过创建临时顺序目录节点,每次选取编号最小的作为Master即可。
分布式锁
锁服务可以分为两类,一个是保持独占,另一个是控制时序。
对于第一类,我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock 节点就释放出锁。
对于第二类, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除。
队列管理
两种类型的队列:
1、同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
2、队列按照 FIFO 方式进行入队和出队操作。
第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。
第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。
四、zookeeper安装启动
在官网下载tar包:http://zookeeper.apache.org/releases.html
LZ目前下载的是3.4.10版本
五、zookeeper基础cli使用
六、java中使用zk
ZooKeeper有一个绑定Java和C的官方API。Zookeeper社区为大多数语言(.NET,python等)提供非官方API。使用ZooKeeper API,应用程序可以连接,交互,操作数据,协调,最后断开与ZooKeeper集合的连接。
ZooKeeper API具有丰富的功能,以简单和安全的方式获得ZooKeeper集合的所有功能。ZooKeeper API提供同步和异步方法。
客户端应该遵循以步骤,与ZooKeeper集合进行清晰和干净的交互。
连接到ZooKeeper集合。ZooKeeper集合为客户端分配会话ID。
定期向服务器发送心跳。否则,ZooKeeper集合将清理过期会话ID,客户端需要重新连接。
只要会话ID处于活动状态,就可以获取/设置znode。
所有任务完成后,断开与ZooKeeper集合的连接。如果客户端长时间不活动,则ZooKeeper集合将自动断开客户端。
代码实践
依赖:
java代码:
运行起来后打开zk Cli命令行对节点进行修改:
可以看到java程序打印输出:
Watcher事件类型:
None(-1) 客户端连接状态发生改变时,会受到none事件
NodeCreated(1) 创建节点事件
NodeDeleted(2) 删除节点事件
NodeDataChanged(3) 节点数据发生变更
NodeChildrenChanged(4) 子节点被创建、被删除会发生事件触发
七、相关问题
客户端的注册监听和zk的通知使用什么协议?
客户端的连接注册使用非阻塞IO通信,相关代码:
为什么写数据的时候需要投票?
是为了保证数据一致性。
Zookeeper如何保证CAP和取舍的?
Zookeeper保证了CP即数据一致性和容错性,舍弃了A可用性,在极端情况下,可能不能保证能正确返回结果,需要客户端再次请求。Zookeeper使用zab来保证其系统自身的高可用和数据一致性的。
Last updated