Java 基础面试题【分布式】三 ZAB 协议
ZAB 协议
简述 ZAB 协议
ZAB 协议是为分布式协调服务 Zookeeper 专门设计的一种支持崩溃恢复的原子广播协议,实现分布式 数据一致性所有客户端的请求都是写入到 Leader 进程中,然后,由 Leader 同步到其他节点,称为 Follower。在 集群数据同步的过程中,如果出现 Follower 节点崩溃或者 Leader 进程崩溃时,都会通过 Zab 协议来 保证数据一致性 ZAB 协议包括两种基本的模式:崩溃恢复和消息广播。
崩溃恢复
初始化集群,刚刚启动的时候
Leader 崩溃,因为故障宕机
Leader 失去了半数的机器支持,与集群中超过一半的节点断连
此时开启新一轮 Leader 选举,选举产生的 Leader 会与过半的 Follower 进行同步,使数据一致,当与 过半的机器同步完成后,就退出恢复模式, 然后进入消息广播模式整个 ZooKeeper 集群的一致性保证就是在上面两个状态之前切换,当 Leader 服务正常时,就是正常 的消息广播模式;当 Leader 不可用时,则进入崩溃恢复模式,崩溃恢复阶段会进行数据同步,完成以 后,重新进入消息广播阶段。Zxid 是 Zab 协议的一个事务编号,Zxid 是一个 64 位的数字,其中低 32 位是一个简单的单调递增计数 器,针对客户端每一个事务请求,计数器加 1;而高 32 位则代表 Leader 周期年代的编号。 Leader 周期( epoch),可以理解为当前集群所处的年代或者周期,每当有一个新的 Leader 选举出 现时,就会从这个 Leader 服务器上取出其本地日志中最大事务的 Zxid,并从中读取 epoch 值,然后 加 1,以此作为新的周期 ID。高 32 位代表了每代 Leader 的唯一性,低 32 位则代表了每代 Leader 中 事务的唯一性。
消息广播
集群中所有的事务请求都由 Leader 节点来处理,其他服务器为 Follower,Leader 将客户端的事务请 求转换为事务 Proposal,并且将 Proposal 分发给集群中其他所有的 Follower。完成广播之后,Leader 等待 Follwer 反馈,当有过半数的 Follower 反馈信息后,Leader 将再次向集 群内 Follower 广播 Commit 信息,Commit 信息就是确认将之前的 Proposal 提交。Leader 节点的写入是一个两步操作,第一步是广播事务操作,第二步是广播提交操作,其中过半数指 的是反馈的节点数 >=N/2+1,N 是全部的 Follower 节点数量。
zab 节点的三种状态
following:服从 leader 的命令
leading:负责协调事务
election/looking:选举状态
zk 的数据模型和节点类型
数据模型:
树形结构
zk 维护的数据主要有:客户端的会话(session)状态及数据节点(dataNode)信息。zk 在内存中构造了个 DataTree 的数据结构,维护着 path 到 dataNode 的映射以及 dataNode 间的树状层 级关系。为了提高读取性能,集群中每个服务节点都是将数据全量存储在内存中。所以,zk 最适于读多 写少且轻量级数据的应用场景。数据仅存储在内存是很不安全的,zk 采用事务日志文件及快照文件的方案来落盘数据,保障数据在不丢 失的情况下能快速恢复。
树中的每个节点被称为— Znode
Znode 兼具文件和目录两种特点。可以做路径标识,也可以存储数据,并可以具有子 Znode。具有 增、删、改、查等操作。Znode 具有原子性操作,读操作将获取与节点相关的所有数据,写操作也将 替换掉节点的所有数据。 另外,每一个节点都拥有自己的 ACL(访问控制列 表),这个列表规定了用户的权限,即限定了特定用户 对目标节点可以执行的操作 Znode 存储数据大小有限制。每个 Znode 的数据大小至多 1M,常规使用中应该远小于此值。Znode 通过路径引用,如同 Unix 中的文件路径。路径必须是绝对的,因此他们必须由斜杠字符来开 头。除此以外,他们必须是唯一的,也就是说每一个路径只有一个表示,因此这些路径不能改变。在 ZooKeeper 中,路径由 Unicode 字符串组成,并且有一些限制。字符串"/zookeeper"用以保存管理信 息,比如关键配额信息。
节点类型
持久节点:一旦创建、该数据节点会一直存储在 zk 服务器上、即使创建该节点的客户端与服务端的会话 关闭了、该节点也不会被删除
临时节点:当创建该节点的客户端会话因超时或发生异常而关闭时、该节点也相应的在 zk 上被删除 。
有序节点:不是一种单独种类的节点、而是在持久节点和临时节点的基础上、增加了一个节点有序的性 质 。
zk 的命名服务、配置管理、集群管理
命名服务:
通过指定的名字来获取资源或者服务地址。Zookeeper 可以创建一个全局唯一的路径,这个路径就可以作为一个名字。被命名的实体可以是集群中的机器,服务的地址,或者是远程的对象等。一些分布式服务框架(RPC、RMI)中的服务地址列表,通过使用命名服务,客户端应用能够根据特定的名字来获取资源的实体、服务地址和提供者信息等。
配置管理:
实际项目开发中,经常使用.properties 或者 xml 需要配置很多信息,如数据库连接信息、fps 地址端口等等。程序分布式部署时,如果把程序的这些配置信息保存在 zk 的 znode 节点下,当你要修改配置,即 znode 会发生变化时,可以通过改变 zk 中某个目录节点的内容,利用 watcher 通知给各个客户端,从而更改配置。
集群管理:
集群管理包括集群监控和集群控制,就是监控集群机器状态,剔除机器和加入机器。zookeeper 可以方便集群机器的管理,它可以实时监控 znode 节点的变化,一旦发现有机器挂了,该机器就会与 zk 断开连接,对应的临时目录节点会被删除,其他所有机器都收到通知。新机器加入也是类似。
讲下 Zookeeper watch 机制
客户端可以通过在 znode 上设置 watch,实现实时监听 znode 的变化 Watch 事件是一个一次性的触发器
,当被设置了 Watch 的数据发生了改变的时候,则服务器将这个改变发送给设置了 Watch 的客户端
父节点的创建,修改,删除都会触发 Watcher 事件。
子节点的创建,删除会触发 Watcher 事件。
特点:
一次性:一旦被触发就会移除,再次使用需要重新注册,因为每次变动都需要通知所有客户端,一次性可以减轻压力,3.6.0 默认持久递归,可以触发多次轻量:只通知发生了事件,不会告知事件内容,减轻服务器和带宽压力
Watcher 机制包括三个角色:
客户端线程
、客户端的WatchManager
以及ZooKeeper服务器
客户端向 ZooKeeper 服务器注册一个 Watcher 监听,
把这个监听信息存储到客户端的 WatchManager 中
当 ZooKeeper 中的节点发生变化时,会通知客户端,客户端会调用相应 Watcher 对象中的回调方法。watch 回调是串行同步的
作为注册中兴 zk 和 eureka 的区别
zk:CP 设计(强一致性),目标是一个分布式的协调系统,用于进行资源的统一管理。当节点 crash 后,需要进行 leader 的选举,在这个期间内,zk 服务是不可用的。
eureka:AP 设计(高可用),目标是一个服务注册发现系统,专门用于微服务的服务发现注册。
Eureka 各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而 Eureka 的客户端在向某个 Eureka 注册时如果发现连接失败,会自动切换至其他节点,只要有一台 Eureka 还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)同时当 eureka 的服务端发现 85%以上的服务都没有心跳的话,它就会认为自己的网络出了问题,就不会从服务列表中删除这些失去心跳的服务,同时 eureka 的客户端也会缓存服务信息。eureka 对于服务注册发现来说是非常好的选择。
如有问题,欢迎加微信交流:w714771310,备注- 技术交流 。或关注微信公众号【码上遇见你】。
版权声明: 本文为 InfoQ 作者【派大星】的原创文章。
原文链接:【http://xie.infoq.cn/article/c8e66a18f48ffb74cf37125cb】。
本文遵守【CC BY-NC-ND】协议,转载请保留原文出处及本版权声明。
评论