前言
zookeeper就是一个分布式应用协调服务,提供一组简单的 API,使得开发人员可以实现通用的协作任务,例如选举主节点,管理组内成员的关系,管理元数据等,同时 ZooKeeper 的服务组件运行在一组专用的服务器之上,也保证了高容错性和可扩展性。
使用场景
- 分布式锁
- ZK配置中心
- 服务注册和发现
不适用场景
ZooKeeper 不适合用作海量的数据存储,对于需要海量的应用数据的情况,可以使用数据库和分布式文件系统。
所以在设计应用时,最佳实践是把应用数据和协同数据独立分开。
数据结构
ZooKeeper 采用类似于文件系统的层级树状结构进行管理 Znode,并且暴露操作 API 接口。
znode 的类型分为持久节点、临时节点、有序节点,组合 4 中类型,持久的,临时的,持久有序的,临时有序的。
持久节点只能调用delete删除
临时节点在当创建该节点的客户端崩溃或者关闭了与 ZooKeeper 的连接时,这个节点就会被删除。
有序节点是被分配唯一一个单调递增的整数。
API接口
zookeeper提供了一系列简单api处理自身的文件系统,对于实现什么场景、处理什么工作由开发人员决定。
- create /path data 创建一个名为/path 的 znode 节点,并包含数据 data。
- delete /path 删除名为/path 的 znode。
- exists /path 检查是否存在名为/path 的节点。
- setData /path data
- getData /path
- getChildren /path
架构
ZooKeeper 服务器端运行于两种模式下:独立模式和仲裁模式。
独立服务器只有一个单独的服务器,ZooKeeper 状态无法复制。
而在仲裁模式下,具有一组 ZooKeeper 服务器,称为 ZooKeeper 集合,它们之间可以进行状态的复制,并同时服务客户端的请求。不过服务器集合并不会让客户端等待每个服务器完成数据保存后再继续,而是在满足仲裁数目的服务器保存或者同步了状态就会返回给客户端。
在解决这一分布式数据一致性,ZooKeeper 采用 ZAB(ZooKeeper Atomic Broadcast)的一致性协议,关于 ZAB 协议后面会详细的介绍。
ZooKeeper 客户端在服务器集群中执行任何请求前必须先与服务器建立会话(session),客户端提交给 ZooKeeper 的所有操作均关联在一个会话上。
客户端初始化连接到集合中某个服务器或一个独立的服务器,客户端提供TCP 协议与服务器进行连接并通信,但当会话无法与当前连接的服务器继续通信时,会话就可能转移到另外一个服务器,ZooKeeper 客户端透明地转移一个会话到不同的服务器。
需要指明的,会话提供了顺序保障,同一个会话中的请求会以 FIFO(先进先出)顺序执行。
监视和通知
ZooKeeper 客户端获得服务器的数据或者变化,不是通过轮询的模式,而是基于通知的机制,客户端向 ZooKeeper 服务器端注册需要接收通知的 znode,通过对 znode 设置监视点来接收通知。
需要强调的是监视点是一个单次触发的操作。
监视点是由读取操作所设置的一次性触发器,每个监视点有一个特定操作来触发,即通过监视点,客户端可以对指定的 znode 节点注册一个通知请求,在发生时就会收到一个单次的通知。监视点只会存在内存,而不会持久化到硬盘,当客户端与服务端的连接断开时,它的所有的监视点会从内存中清除。因为客户端也会维护一份监视点的数据,在重连之后,监视点数据会再次同步到服务端。
客户端
在客户端库中有 2 个主要的类:ZooKeeper 和 ClientCnxn。
写客户端应用程序时通过实例化 ZooKeeper 类来建立一个会话。一旦建立起一个会话,ZooKeeper 就会使用一个会话标识符来关联这个会话。这个会话标识符实际上是有服务端所生产的。
ClientCnxn 类管理连接到 server 的 socket 连接。该类维护一个可连接的 ZooKeeper 的服务列表,并当连接断掉的时候无缝地切换到其他服务器,当重连到一个其他的服务器时会使用同一个会话,客户端也会重置所有的监视点到刚连接的服务器上。
会话
会话(session)是 ZooKeeper 的一个重要的抽象。保证请求有序,临时 znode 节点,监控点都与会话密切相关。因此会话的跟踪机制对 ZooKeeper 来说也是非常重要的。
在独立模式下,单个服务器会跟踪所有的会话,而在仲裁模式下则由群首服务器来跟踪和维护。而追随者服务器仅仅是简单地把客户端连接的会话信息转发到群首服务器。
为了保证会话的存活,服务器需要接收会话的心跳信息。心跳的形式可以是一个新的请求或者显式的 ping 信息。两种情况下,服务器通过更新会话的过期时间来触发会话活跃,在仲裁模式下,群首服务器发送一个 PING 信息给它的追随者们,追随者们返回自从最新一次 PING 消息之后的一个 session 列表。群首服务器每半个 tick 就会发送一个 ping 信息给追随者们。
总结
本文主要对zookeeper的基本架构有个了解,具体内部实现原理详见zookeeper——原理(二)