ZooKeeper是一个开源的分布式协调服务,由雅虎创建,是Google Chubby的开源实现。ZooKeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。
简单来说ZooKeeper 实现了支持订阅通知机制的文件系统。
整体结构
- 节点个数:奇数
- 集群角色:Leader、Follower、Observer
- 正常工作条件:超过半数以上节点存活且通信正常
- 数据备份:各个节点存储全量数据,读性能高
- 数据存储:内存数据库,性能高
- 会话保持:超时时间内重连,上下文可恢复
- 一致性保证:ZAB分布式一致性协议
工作特性
- CP,保证一致性及分区容错性
- 高可靠
一半以上节点正常即可正常工作;leader挂掉可再选主接管 - 高性能
Observer不参与选主及写入投票;所有节点有全量数据支持读操作 - 操作保证原子性
- 同一个客户端的请求严格保证顺序
- 一旦收到ZK响应,便一定生效
- 数据修改并发控制采用乐观锁
- 支持订阅,变化时有异步事件通知,且保证顺序
- 支持权限控制
数据模型
简单来说维护了由节点(Znode)组成的文件系统。
节点类型
永久节点、永久顺序节点、临时节点、临时顺序节点-
节点结构
节点属性(stat)、节点内容(data)、子节点(children)
-
节点操作
增、删、改、查、是否存在
WATCH机制
一个事件包含KeeperState和EventType两部分,分别表示通知状态和事件类型。主要有以下几种组合:
KeeperState
有以下几种状态:
- KeeperState.Expired 客户端和服务器在ticktime的时间周期内,是要发送心跳通知的。这是租约协议的一个实现。客户端发送request,告诉服务器其上一个租约时间,服务器收到这个请求后,告诉客户端其下一个租约时间是哪个时间点。当客户端时间戳达到最后一个租约时间,而没有收到服务器发来的任何新租约时间,即认为自己下线(此后客户端会废弃这次连接,并试图重新建立连接)。这个过期状态就是Expired状态
- KeeperState.Disconnected 就像上面那个状态所述,当客户端断开一个连接(可能是租约期满,也可能是客户端主动断开)这是客户端和服务器的连接就是Disconnected状态
- KeeperState.SyncConnected 一旦客户端和服务器的某一个节点建立连接(注意,虽然集群有多个节点,但是客户端一次连接到一个节点就行了),并完成一次version、zxid的同步,这时的客户端和服务器的连接状态就是SyncConnected
- KeeperState.AuthFailed zookeeper客户端进行连接认证失败时,发生该状态
EventType
主要有以下几种:
- EventType.NodeCreated 当node-x这个节点被创建时,该事件被触发
- EventType.NodeChildrenChanged 当node-x这个节点的直接子节点被创建、被删除、子节点数据发生变更时,该事件被触发。
- EventType.NodeDataChanged 当node-x这个节点的数据发生变更时,该事件被触发
- EventType.NodeDeleted 当node-x这个节点被删除时,该事件被触发。
- EventType.None 当zookeeper客户端的连接状态发生变更时,即KeeperState.Expired、KeeperState.Disconnected、KeeperState.SyncConnected、KeeperState.AuthFailed状态切换时,描述的事件类型为EventType.None
EventType与操作的对应关系如下:
WATCH机制特点
- 推拉结合
服务端只告诉你有事件产生,具体内容需要客户端再查询,降低服务端压力 - 异步通知
需要考虑事件处理过程中,又有事件产生 - 注册一次性
处理完成后需要再次注册 - 保证收到事件顺序正确性
- 支持会话保持,超时时间内断线重连,监测点保持
集群运行方式
单机模式、集群模式、伪集群模式
伪集群模式配置文件如下: