ZooKeeper 学习笔记

Zookeeper是一个分布式协调服务,其核心特点是强一致性。集群中的角色包括Leader、Follower和Observer。ZAB协议保证了事务的原子性广播和崩溃恢复。ZNode是数据节点,有持久和临时节点类型,每个节点有版本号用于乐观锁。Leader选举基于ZXID,确保高可用性。Zookeeper被应用于选举Master和实现分布式锁等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Zookeeper基本概念

集群角色

  • Leader
    提供读写服务
  • Follower
    提供读服务。在Leader不存的时候进行Leader选举。如果接收到客户端的事务操作则转发给Leader。
  • Observer
    不参与Leader选举,也不参与写操作的“过半写成功”策略。因此Observer可以在不影响写性能的情况下提升集群的读性能。

会话

在客户端和服务端第一次建立TCP连接之后会建立会话。服务器会维护一个客户端会话时间,在这个时间内会话就有效。

数据节点

ZNode

  • 持久节点
  • 临时节点

版本

每个ZNode都会有一个Stat结构存储三个数据版本

  • Version:当前Znode版本
  • CVersion:当前Znode子节点的版本
  • AVersion:当前ZNode的ACL版本

ZAB协议

Zookeeper Atomic Broadcast : Zookeeper原子消息广播协议

ZAB协议是为分布式协调服务Zoopkeeper专门设计的一种支持崩溃恢复的原子广播协议。

核心

事务请求由Leader服务器处理,其他服务器为Follower服务器,Leader服务器将一个客户端事务请求转换为一个事务Proposal(提议),并将这个Proposal分发给集群中所有的Follower,一旦超过半数的Follower服务器进行了正确的反馈后,那么Leader再向所有的Follower服务器分发Commit消息,要求其将前一个Proposal进行提交。

两种基本模式

消息广播

Leader会为每个事务请求生成对应的Proposal来进行广播,Leader会为这个这个Proposal分配一个全局单调递增的唯一ID,即ZXID(事务ID)。Leader还会给每一个Follower分配一个单独的队列,然后将需要广播的事务Proposal放到队列中去,并且根据FIFO进行发送消息。

Follower接收到Proposal之后会以事务日志的方式写入到本地磁盘,然后返回给Leader一个ACK。

Leader接收到超过半数的ACK之后,给所有的Follower发送Commit消息,进行提交。

奔溃恢复

在Leader奔溃之后,选举出的新Leader是急集群中所有机器ZXID最大的。

ZXID是一个64位的数字,低32位是单调递增的计数器,高32位代表Leader周期epoch的编号。

三个阶段

上面的两种基本模式可以细分成三个阶段。

阶段一:发现

选举Leader,准Leader会选取整个集群中包含ZXID最大的Follower所执行的事务集作为初始事务集

阶段二:同步

Leader将初始事务集同步给所有Follower(两阶段提交)

阶段三:广播

Leader将从客户端收到的事务请求生成对应的事务Proposal,并发送给Follower进行同步(两阶段提交)

服务器状态

Looking:Leader选举阶段

Following:Follower服务器和Leader保持同步状态

Leading:Leader服务器作为主进程领导状态

Zookeeper技术内幕

系统模型

节点特性
节点类型
  • 持久几点
  • 持久顺序节点
  • 临时节点
  • 临时顺序节点

顺序节点:每个父节点会为它的第一级子节点维护一份顺序,用于记录创建的先后顺序,在创建节点的过程中可以自动为节点加一个数字的后缀(递增,上限是整型的最大值)

版本

每个ZNode都会有一个Stat结构存储三个数据版本

  • Version:当前Znode版本
  • CVersion:当前Znode子节点的版本
  • AVersion:当前ZNode的ACL版本

Version用于乐观锁。

Watch机制

Watch机制主要包括客户端线程、客户端WatchManager和Zookeeper服务器三部分。

客户端在向Zookeeper服务器注册Watcher的同时会将Watch对象存储在客户端的WatchManager中,当Zookeeper触发Watcher事件后,会向客户端发送通知,客户端线程会从WatcherManager中取出对应的Watcher对象来执行回调逻辑。

  1. 客户端注册

  2. 服务端处理事件
    在对指定的节点进行数据更新的时候,会调用注册时存储的Map,查看需要给哪些客户端发送Watch事件。发送完之后就会把这个客户端信息从Map中删除。所以一次Watch监听是一次性的,如果需要持续监听的话需要客户端反复注册。

  3. 客户端处理事件回调
    Wather事件很简单,只有执行的节点和事件类型,通知转态等,并没有具体的变更内容,需要客户端执行一次查询操作才能获取变更内容。

Leader选举

选举原则
  1. 每个服务器第一轮投票都是投给自己
  2. ZXID比较大的优先作为Leader
  3. 可以变更投票;当收到比自己投票大的ZXID的投票消息的时候,会将自己的投票变更为这个较大ZXID服务器的投票。
  4. 获取超过半数投票的服务器成为Leader

数据存储

为了提高性能,Zookeeper的数据都是存储在内存中。

为了支持持久化,Zookeeper会把内存里的快照数据持久化到硬盘,可通过配置snapCount来控制,进行了多少次事务日志记录之后进行一个数据快照(不是完全按照这个配置的值来,会有一定的随机性)。

异步线程进行数据快照。

Zoopkeeper典型应用场景

选举Master

**原理:**利用Zookeeper的强一致的特性,在分布式高并发的情况下节点的创建能够保证全局唯一性,即Zookeepr可以保证客户端无法重复创建一个已经存在的节点。那么最终只会有一个客户端创建节点成功,创建成功的客户端成为Master。

创建的节点是临时节点,通过会话维持这个节点。没有创建成功的节点通过Watch机制监听这个节点,当Master宕机了,会话结束,监听的节点再来争夺创建新的几点,创建成功的节点为新的Master。

分布式锁

和选举Master差不多

问题:

  1. ZK是CP模型么

  2. 同一时刻,不同的客户端有可能读取到的数据不一致么?
    我理解是有可能的,因为ZAB协议只要求过半数的Follower回复了ACK就返回成功了,所以这个时候读没有ACK的Follower的时候会读到旧数据。
    ZK应该不保证强一致性,只保证了在一定时间内达成一致。

  3. Leader选举过程中系统是不可用的么?
    是不可用的

  4. follower是怎么同步Leader数据的,比如新加入集群的Follower

    发现,同步,广播

  5. ZK有持久化机制么?如果数据全部在内存里,如果全部机器重启了怎么办?
    有快照机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值