Zookeeper是开源的分布式协调服务,提供了分布式数据一致性的解决方案。node
Zookeeper 可用做配置中心和分布式锁服务,在 Dubbo、Kafka、Spark等分布式集群上获得普遍应用。算法
Zookeeper的数据模型为树状结构,树的节点被称做ZNode。安全
Zookeeper使用路径来惟一标识ZNode,相似于Unix文件系统中的绝对路径。路径必须以/
开头,由Unicode字符串组成,如/myapp/master/0
。网络
每个ZNode维护着三部分数据:app
每一个节点都有独立的访问控制列表(Access Control List, ACL), 来控制用户对本节点的访问权限。分布式
每个ZNode都维护着三个版本号:设计
全部的写操做都会使相应的版本号增长。写操做必须指定要更新的ZNode的版本号,版本号不一致会致使写入失败。code
Zxidblog
全部对Zookeeper状态的改变都会产生一个Zxid(ZooKeeper Transaction Id),Zxid全局有序。队列
Zxid为标识事件发生的前后顺序: 即事件A发生早于事件B,那么事件A的Zxid定小于事件B的Zxid。
每一个ZNode维护两个Zxid:
Zxid是一个64位的数字, 高32位表示Zookeeper集群leader, 低32位表示逻辑顺序。每次leader改变后, 新产生的Zxid高32位都会改变。
节点类型
Zookeeper中的节点分为两种:
Zookeeper 能够建立顺序子节点,即建立子节点时在路径结尾添加一个自增的32位 id, 该id在该节点的父节点下是惟一的。
Zookeeper 全部的读操做getData(), getChildren()和 exists()均可以设置 Watch 触发器。
Watch 触发器是一次性的,当触发器通知了一次状态变化后消失,不会通知状态的再次变化。
Zookeeper 与客户端之间经过 Tcp Socket 进行通讯, Zookeeper 会主动将时间通知客户端。
Zookeeper 保证客户端只有首先收到了Watch通知后,才会感知到它所设置监视的znode发生了变化。
Zookeeper 支持三种类型的watch:
ZooKeeper 是具备较高一致性的分布式协调服务,它提供如下保证:
Zookeeper 使用数据副本和崩溃恢复机制保证数据安全和集群高可用性。
Zookeeper 使用基于 Paxos 算法的 ZAB协议(Zookeeper Atomic Broadcast)进行写操做,保证集群数据的一致性。
咱们能够将系统中通用配置信息写入 ZNode 中,客户端启动时从 Zookeeper 获取配置数据并监视配置节点的变化,当配置发生改变 Zookeeper 会通知全部的客户端获取最新数据,从而实如今线更新配置。
适合使用Zookeeper维护的配置一般:
当服务启动时,服务提供者能够在Zookeeper的相应路径下建立临时节点,并在节点中写入服务配置信息。服务关闭(崩溃)时,临时节点自动删除。
客户端启动时从 ZooKeeper 读取服务提供者信息从而实现自动的服务发布/移除功能。
Zookeeper 的临时节点能够维护客户端持有锁的状态,加锁失败的客户端可使用 Watch 机制监视锁的释放状况,实现阻塞等待加锁。
Zookeeper 的顺序节点能够实现一个简单的队列,能够利用此特性实现公平锁。客户端在锁节点下建立顺序子节点,持有最小子节点的客户端成功加锁,加锁失败的客户端 Watch 前一个顺序子节点,从而实现先到先得的公平锁机制。
ZooKeeper 的顺序节点能够生成全局惟一ID, 咱们能够利用该ID为服务命名。相对于UUID, 该名称较短且能够保证毫不重复。
与分布式公平锁应用相似,ZooKeeper 能够维护集群 Master。
集群中全部能够成为 Master 的进程都在 Zookeeper 中的指定路径下建立顺序子节点,持有最小子节点的进程成为Master。
集群中全部进程都 Watch 指定路径下节点的状况,一旦发生变化则从新读取最小子节点的持有者做为Master。
脑裂问题
传统集群实现方案是运行一个备用Master节点,备用Master节点按期向主Master节点发送ping请求,若能及时收到主Master的ack响应则认为正常。
若Ack响应超时,备用Master则会取代原主Master成为新的集群主Master节点。
若响应超时由于主Master故障致使,备用Master成为新的主节点彻底正常。
若超时由于主备 Master 节点间 ping-ack 网络故障致使,那么主Master工做正常,而备用Master却误认为主Master崩溃而进行取代,那么集群中可能出现多个Master共存的故障(即脑裂故障)。
若使用 Zookeeper 维护 Master 信息,不管是由于主Master故障仍是通讯问题致使最小子节点被删除,备用Master持有的节点都会成为最小子节点。
此时,全部客户端都会受到通知并得知 Master 变动,保证集群中只有一个 Master。
当崩溃的Master恢复后,它将成为新的备用Master加入集群。
ZooKeeper 没法避免通讯故障致使误判 Master 状态,可是能够保证在任何状况下集群中只有一个 Master 节点。