第二章 分布式服务框架Zookeeper
1. Zookeeper概述
Zookeeper 发布/订阅模式的分布式框架主要是用来解决分布式应用中经常遇到的一些数据管理问题,提高分布式,高可用的服务,协调能力。
ZooKeeper的主要功能:
- 统一配置管理
- 统一命名服务
- 分布式锁
- 集群管理
安全模式下Zookeeper依赖Kerberos和LdapServer进行安全认证,非安全模式下则不依赖于Kerberos和LdapServer。
Zookeeper作为底层组件被广泛上层组件使用并依赖,如Kafka,HDFS,HBase,Storm等。
2. Zookeeper体系架构
-
Zookeeper集群由一组Server节点组成,一个Leader其他都是Follower
当客户端Client 连接到 ZooKeeper 集群,并且执行写请求时, 这些请求会被发送到 Leader 节点上,然后 Leader节点上数据变更会同步到集群中其他的 Follower 节点。
-
集群启动时选举出Leader
当一个Leader 节点发生故障失效时, 失败故障是快速响应的,消息层负责重新选择一个 Leader,继续作为协调服务集群的中心,处理客户端写请求,并将 ZooKeeper 协调系统的数据变更同步(广播)到其他的 Follower 节点
-
自定义原子消息协议,保证各节点数据一致性
ZooKeeperAtomic Broadcast (Zab协议),Follower基于这种消息协议能够保证本地的 ZooKeeper 数据与 Leader 节点同步, 然后基于本地的存储来独立地对外提供服务。
-
Leader节点接受到数据变更请求后,先写磁盘再写内存
首先将变更写入本地磁盘,以作恢复之用。当所有 的写请求持久化到磁盘以后, 才会将变更应用到内存中。
2.1 Zookeeper容灾能力
- Zookeeper选举时,某实例超过半数以上的投票,即变为Leader
- 2x+1 个节点与 2x+2 个节点的容灾能力相同( 3 个与 4 个相同, 5 个与 6 个相同 … )
- 考虑到选举以及完成写操作的速度与节点数的相关性,我们建议 ZooKeeper 部署奇数个节点。
2.2 Zookeeper关键特性
- 最终一致性
无论哪个Server,对外展示的均是同一视图 - 实时性
保证客户端在一个时间间隔范围内获得服务器的更新信息,或服务器失效的信息 - 可靠性
一条消息被一个Server接收,它将被所有的Server接收 - 等待无关性
慢的或失效的Client不会干预快的Client的请求,每个Client都能有效地等待 - 原子性
更新只要成功或失败,没有中间状态 - 顺序一致性
客户端发送的更新会根据发送顺序应用
2.3 Zookeeper读特性
读操作可以在任意节点完成。
2.4 Zookeeper写特性
- 同读请求一样, 客户端可以向任一 server 提出写请求。
- server 将这一请求发送给 leader 。
- leader获取写请求后, 会向所有节点发送这条写请求信息, 询问是否能够执行这次写操作。
- follower 节点根据自身情况给出反馈信息 ACK 应答消息,leader 根据反馈信息,若获取到的可以执行写操作的数量大于实例总数的一半,则认为本次写操作可执行。
- leader 将结果反馈给各 follower , 并完成写操作, 各 follower 节点同步 leader 的数据
3. Zookeeper应用
3.1 统一配置管理
- 目标:把A System.yml、B System.yml、C
System.yml相同的配置项抽取出来成一份公用的配置common.yml,并且即便common.yml改了,也不需要系统A、B、C重启。 - 做法:我们可以将common.yml这份配置放在ZooKeeper的Znode节点中,系统A、B、C监听着这个Znode节点有无变更,如果变更了,及时响应。
3.2 统一命名服务
比如说,现在我有一个域名www.java.com,但我这个域名下有多台机器:
- 192.168.1.1
- 192.168.1.2
- 192.168.1.3
- 192.168.1.4
其他应用访问www.java.com即可访问到我的机器,而不是通过IP去访问。
3.3 分布式锁
系统A、B、C都去访问/locks节点
访问的时候会创建带顺序号的临时/短暂(EPHEMERAL_SEQUENTIAL)节点,比如,系统A创建了id_000000节点,系统B创建了id_000002节点,系统C创建了id_000001节点。
接着,拿到/locks节点下的所有子节点(id_000000,id_000001,id_000002),判断自己创建的是不是最小的那个节点
- 如果是,则拿到锁
- 释放锁:执行完操作后,把创建的节点给删掉
- 如果不是,则监听比自己要小1的节点变化
3.4 集群状态
以三个系统A、B、C为例,在ZooKeeper中创建临时节点:
-
只要系统A挂了,那/groupMember/A这个节点就会删除,通过监听groupMember下的子节点,系统B和C就能够感知到系统A已经挂了。(新增也是同理)
-
除了能够感知节点的上下线变化,ZooKeeper还可以实现动态选举Master的功能。(如果集群是主从架构模式下)
-
原理也很简单,如果想要实现动态选举Master的功能,Znode节点的类型是带顺序号的临时节点(EPHEMERAL_SEQUENTIAL)就好了。
-
Zookeeper会每次选举最小编号的作为Master,如果Master挂了,自然对应的Znode节点就会删除。然后让新的最小编号作为Master,这样就可以实现动态选举的功能了。