ZooKeeper
1. ZooKeeper 集群中有哪些角色,分别有什么作用
Leader:
- 发起与提交写请求。所有的跟随者 Follower 与观察者 Observer 节点的写请求都会转交给 Leader执行。Leader接受到一个写请求后,首先会发送给所有的Follower,统计Follower写入成功的数量。当有超过半数的Follower写入成功后,Leader就会认为这个写请求提交成功,通知所有的Follower commit 这个写操作,保证事后哪怕是集群崩溃恢复或者重启,这个写操作也不会丢失。
- 与 Learner 保持心跳。
- 崩溃恢复时负责恢复数据以及同步数据到 Learner。
Follower:
- 与 Leader 保持心跳连接。
- 当 Leader 宕机后,经过投票后成为新的 Leader。Leader 的重新选举是由所有 Follower 内部投票决定的。
- 向 Leader 发送消息与请求。
- 处理 Leader 发来的消息与请求。
Observer:
- 与 Leader 同步数据。
- 不参与 Leader 选举,也没有投票权,同时也不参与写操作的提议过程中。
- 数据没有事务化到硬盘。即 Observer 只会吧数据加载到内存。
- Observer的主要作用是提高 zookeeper 集群的读性能。通过leader的介绍我们知道 zookeeper 的一个写操作是要经过半数以上的 Follower 确认才能够写成功的。那么当 zookeeper 集群中的节点越多时,zookeeper 的写性能就越差。为了在提高 zookeeper 读性能(也就是支持更多的客户端连接)的同时又不影响 zookeeper 的写性能,所以才有了观察者。
2. 说说 ZooKeeper Znode 的特点
- Zookeeper是一个树状结构,维护一个小型的数据节点Znode。
- 数据以key/value的方式存在,目录是数据的key。
- 所有的数据访问都必须以绝对路径的方式显示。
- Znode是层次结构,每个Znode都有一个唯一的路径标识
- 临时节点:创建临时节点,会话结束之后临时节点会被自动删除。
- 临时顺序节点:具有临时节点的特征,但是它会有序列号,在分布式锁中会用到该类型节点。
- 持久节点:节点会一直存在,直到显示删除。主要用于存储配置信息和状态信息等。
- 持久顺序节点 :该节点创建后持久存在,相对于持久节点,它会在节点名称后面自动增加一个10位数字的序
列号,这个计数对于此节点的父节点是唯一。 - 原子性操作:ZooKeeper提供了原子性的写操作,这意味着所有更新操作都是原子性的,要么成功,要么失败,不会出现部分更新的情况。
3. 说说 ZooKeeper 的监听通知机制
监听机制 :
客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目 录节点增加 删除)时,ZooKeeper 会通知客户端。监听机制保证 ZooKeeper 保存的任何的数据的任何改变都能快速的响应到监听了该节点的应用程序。
- 首先要有一个main()线程
- 在main线程中创建 Zookeeper 客户端,这时就会创建两个线程,一个负责网络连接通信(connet),一个负责监听(listener) 。
- 通过connect线程将注册的监听事件发送给Zookeeper。
- 在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。
- Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程。
- listener线程内部调用了process()方法。
通知机制 :
Zookeeper 允许客户端向服务端的某个 Znode 注册一个 Watcher 监听,当服务端的一些指定事件触发了这个 Watcher,服务端会向指定客户端发送一个事件通知来实现分布式的通知功能,然后客户端根据Watcher 通知状态和事件类型做出业务上的改变。
4. 说一下 CAP 原则以及如何选择
CAP 原则是分布式系统设计中的重要原则,它指的是一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)三个特性之间的权衡关系。三者不可兼得。
- 一致性(Consistency):指的是分布式系统中的所有节点,在同一时间具有相同的数据视图。换句话说,一致性要求在数据更新后,所有节点都能够立即读取到最新的数据状态。
- 可用性(Availability):指的是分布式系统在面对用户请求时能够保证正常的响应和服务。即使出现节点故障,系统依然能够继续对外提供服务。
- 分区容错性(Partition Tolerance):分布式系统在任何网络分区故障时,仍然能够对外提供一致性和可用性的服务。
在选择时,要考虑系统的实际情况和需求,根据不同的应⽤场景选择不同的指标进⾏权衡。下⾯是⼀些选择策略:
-
对于要求强⼀致性(C)的系统,需要牺牲可⽤性或分区容错性,因为⼀致性需要所有节点都同步,这会增加延迟和负载。例如,银⾏系统、⽀付系统等需要强⼀致性。
-
对于要求⾼可⽤性(A)的系统,需要牺牲⼀致性或分区容错性。例如,在线电商系统、社交⽹络系统等需要保证⾼可⽤性。
-
对于要求⾼分区容错性(P)的系统,需要牺牲⼀致性或可⽤性。例如,数据中⼼之间的分布式系统,需要保证⽹络分区容错性。
5. ZooKeeper 的选主过程
ZooKeeper的选主其实就是ZAB协议的崩溃恢复模式。
-
当整个集群正在启动时,或者当 Leader 节点出现⽹络中断、崩溃等情况时,ZAB 协议就会进⼊恢复模式并选举产⽣新的 Leader,当 Leader 服务器选举出来后,并且集群中有过半的机器和该 Leader 节点完成数据同步后(同步指的是数据同步,⽤来保证集群中过半的机器能够和Leader 服务器的数据状态保持⼀致),ZAB 协议就会退出恢复模式。
-
当集群中已经有过半的 Follower 节点完成了和 Leader 状态同步以后,那么整个集群就进⼊了消息⼴播模式。这个时候,在 Leader 节点正常⼯作时,启动⼀台新的服务器加⼊到集群,那这个服务器会直接进⼊数据恢复模式,和 Leader节点进⾏数据同步。同步完成后即可正常对外提供⾮事务请求的处理。
-
在整个消息⼴播中,Leader 会将每⼀个事务请求转换成对应的 Proposal 来进⾏⼴播,并且在⼴播事务 Proposal 之前,Leader 服务器会⾸先为这个事务 Proposal 分配⼀个全局单递增的唯⼀ID,称之为事务 ID(即 ZXID),由于 ZAB 协议需要保证每⼀个消息的严格的顺序关系,因此必须将每⼀个 Proposal 按照其 ZXID 的先后顺序进⾏排序和处理。
6. ZooKeeper 如何帮助其他组件选主
ZooKeeper 通过其⼀致性协调服务帮助其他分布式组件选主的主要⽅式有:
- 提供了⼀个统⼀的主节点选举接⼝ - ZooKeeper 提供了⼀个基于Zab协议的Leader选举接⼝,其他组件可以构建⾃⼰的主节点选举过程,⽽将底层的Leader选举和协调⼯作交给ZooKeeper去完成。
- 节点状态维护 - ZooKeeper 会维护每个节点的信息,如存活状态、节点数据等。这些信息可以帮助判断节点是否"活着"从⽽进⾏主节点选举。
- 分布式锁 - ZooKeeper的分布式锁机制可以避免同时多个节点成为主节点的情况产⽣。组件可以利⽤ZooKeeper 的锁服务确保同⼀时刻只有⼀个主节点。
- 触发器机制 - ZooKeeper提供了Watcher机制,当节点状态发⽣改变会触发相关Watcher,可以⽤于通知组件有主节点失效,需要激活新的选举过程。
- 数据发布/订阅 - ZooKeeper可以⽤于主节点将选举结果发布出去,其他节点可以订阅获得通知。
- 所以ZooKeeper为其他分布式组件选主提供了基础协调服务,利⽤这些机制可以更好地实现⾼可靠性的主节点选举和状态协调。
通过Zookeeper的临时节点可以⽤来实现分布式锁,多个客户端分别创建⼀个节点,创建成功即成功获取到了锁,成为主节点,创建失败的客户端们则会监听这个主节点,当主节点失效后,其他节点会收到Watch发来的通知,开始重新夺取锁,成为主节点。这个临时节点只会有⼀个,当服务器断开,⾃动失效。