Zookeeper 是一个开源的分布应用程序协调服务,来自于Google 一个开源的实现,是Hadoop 和HBase 的重要组件。Zookeeper 可以为分布式应用提供一致性服务,功能包括:配置服务、名字服务、分布式同步、组服务等等。Zookeeper 的目标是封装好复杂易出错的关键服务,将简单易用的接口和性能高效,功能稳定的系统提供给用户。Zookeeper 包含一个简单的原语集,提供Java 和C接口。
Zookeeper 应用场景——匹配管理
分布式环境下,配置文件管理和同步是一个常见的问题:
1.一个集群中,所有节点的配置信息时一致的,比如Hadoop
2.对配置文件修改后,希望能够快速同步到各个节点中
Zookeeper应用场景——统一的命名服务
分布式环境下,经常需要对应用/服务进行统一命名,便于识别不同服务:类似于域名与IP 之间对应关系,域名容易记住;通过名称来获取资源或者服务器的地址,提供者等信息。
按照层次结构组织服务/应用名称:可将服务名称以及地址信息写到Zookeeper 上,客户端通过Zookeeper 获取可用服务列表类。
配置管理可交由Zookeeper 实现:可将配置信息写入Zookeeper 的一个Znode 上,各个节点监听这个Znode ,一旦Znode 中的数据被修改Zookeeper 将通知各个节点
Zookeeper 的主要概念介绍
zookeeper 中的角色主要由以下三类:
角色 | | 描述(机器数为奇数个) |
Leader | | 主要负责进行投票的发起和决议,更新系统状态 |
Learner | Follower | Follower接收客户请求并客户端返回结果,在选举过程中参与投票 |
Observer | OBserver 接收客户端连接,将写请求转发给Leader节点,Observer不参与投票过程,只同步Leader 的状态,Observer 的目的在于扩展系统,提高读取速度 | |
Client | | 访问请求发起方 |
系统模型如下:
Zookeeper 的设计目标包括:
1.最终一致性:Client 不论连接到哪个Server ,展示给它的都是同一个视图,这是Zookeeper 最重要的特性。
2.可靠性:如果某个消息被一台服务器接收,那么它将被集群中所有的服务器接。
3.实时性:Zookeeper 保证客户端将在一个时间范围内获得服务器的更新或者服务器失效的信息。
4.等待无关(wait-free):慢的或者失效的Client 不得不干预的Client 的请求。
5.原子性:更新只能成功或者失败,没有中间状态。
6.顺序性:包括全局有序和偏序两种:全局有序指的是如果在一台服务器上消息a在消息b 前发布,则在所有Server 上消息a 都将在消息b 前被发布;偏序是指如果一个消息b 在消息a后被同一个发送者发布,a 必将排在b 前面。
每个Server 在内的存储了一个数据,Zookeeper 启动时,将从实例中选举一个Leader
Leader 负责处理数据更新等操作
一个更新操作成功,当且仅当大多数Server 在内存中成功修改数据
zookeeper 的工作原理
zookeeper 的核心是原子广播,这个机制保证了各个Server 之间的同步。实现这个机制的协议叫做zab 协议。zab 协议有两种模式,它们分别是恢复模式和广播模式。当服务器启动或者在领导者奔溃后,zab 就进入恢复模式,当领导者被选举出来,且大多数Server 完成了和Leader 的状态同步之后,恢复模式就结束了。状态同步保证了Leader 和Server 具有相同的系统状态。
为了保证事务的顺序一致性,Zookeeper 采用了递增的事物id 号(zxid)来标识事务。所有的提议都在被提出来的时候加上zxid,实现中zxid 是一个64 位数据,它的高32位是epoch,用来标识Leader 关系是否改变,每当一个Leader 被选举出来时,它都会有一个新的epoch,用于标识当前属于当前Leader 的时期,zxid 的低32位用于递增计数。
每个Server 在工作过程中的三种状态:
1.LOOKING:当前Server 不知道Leader 是谁,正在搜寻
2.LEADER:当前Server 即为选举出来的Leader
3.FOLLOWER:Leader 已经选举出来,当前Server 与之同步
选举流程:
当Leader 奔溃或者Leader 失去大多数的Follower 时,Zookeeper 就可以进入恢复模式,恢复模式需要重新选举出来一个新的Leader,以使所有的Server 都恢复到一个正确的状态。Zookeeper 的选举规则有两种状态:一种是basic paxos 实现;另一个是basic paxos 流程
1.选举线程由当前发起选举的Server 线程担任,其主要功能是对投票结果进行统计,并选举出推荐的Server
2.选举线程收到所有Server 发起一次询问
3.选举线程收到回复后,验证是否是自己发起的询问,然后获取对方的id ,并存储到当前询问对象列表中,最后获取对方提议的Leader 的相关信息,并将这些信息设置为下一次要投票的Server
4.在收到Server 回复后,选举线程会计算出zxid 最大的那个Server ,并将该Server 的相关信息设置为下一次要投票的Server
5.选举线程将当前zxid 最大的Server 设置为当前要推荐的Leader ,如果此时有Server 获得n/2+1 的票数,则将设置为当前推荐Leader 为获胜为Server ,否则继续这个过程,直到leader 被选举出来。
通过basic paxos 流程分析可以得出:要使得Leader 获得多数Server 的支持,则Server 总数必须为奇数n/2+1的票数,且存活的Server 的数目不得少于n+1。每个Server 启动后都会重复以上流程。
在恢复模式下,如果从刚奔溃状态恢复的或者刚启动的Server 还会从磁盘快照中恢复数据和会话信息,Zookeeper 会记得事务日志并定期进行快照,以方便在故障时进行状态恢复。
同步流程
选举完Leader 以后,Zookeeper 就进入状态同步过程;
1.Leader 等待Server 连接
2.Follower 连接Leader ,将最大的zxid 发送给Leader
3.Leader 根据Follower 的zxid 确定同步点
4.完成同步后通知Follower 已经成为updated 状态
5.Follower 收到updated 消息后,就可以重新接受Client 的请求进行服务