ZooKeeper 集群的数据同步

1. 前言

在 Zookeeper 的集群模式一节中,我们学习过了 Zookeeper 的每个 Follower 节点都可以对外提供服务,而且为了保证整个 Zookeeper 集群的数据一致,Zookeeper 集群的服务之间还会进行数据同步。那么这个数据同步的过程是如何实现的呢?接下来我们就对 Zookeeper 集群的数据同步机制进行详细的讲解。

2. ZAB 的消息广播模式

Zookeeper 为了保证 Zookeeper 集群的数据一致性,使用了 ZAB 协议,在正常工作模式下,ZAB 协议会使用消息广播模式来让 Leader 来对事务性消息进行广播,而且只能有一个 Leader 进行广播。接下来我们就来讲解这个消息广播模式是如何工作的。

2.1 消息广播的数据同步

在我们使用 Zookeeper 客户端向 Zookeeper 集群的某一个 Follower 发送事务请求时,也就是对 Znode 节点的增删改操作时,这个Follower 节点并不会自己去处理这个事务请求,而是会把这个请求转发给 Leader 节点,让 Leader 节点来处理事务请求。

事务请求

Leader 节点接收到 Follower 转发过来的请求,会生成与事务请求相对应的 Proposal 事务提案,并为这个 Proposal 事务提案分配全局唯一的单调递增的事务ID,也就是 ZXID,然后把 Proposal 事务提案发送到集群中所有的 Follower 节点。

如果 Leader 节点接收到了多个 Follower 节点转发的请求,Leader 节点会根据 Proposal 事务提案的 ZXID 的先后顺序来对 Follower 节点进行广播。

Proposal 事务提案

Follower 节点接收到 Proposal 事务提案后,会把接收到的 Proposal 事务提案以事务日志的方式写入本地磁盘中,成功后会向 Leader 节点返回 Ack 确认信息,确定自己能够执行该事务。在这一步骤中, Follower 向 Leader 发送反馈,确认 Follower 节点能够执行该事务,但不会去提交该事务请求。

 发送反馈

Leader 节点接收到半数以上的 Follower 节点返回的 Ack 确认信息后,就会向所有的 Follower 节点广播 Commit 消息,通知 Follower 节点提交事务请求,同时 Leader 节点自己也会提交该事务请求。接收到 Commit 消息的 Follower 节点就会开始进行事务提交。

事务提交

当 Follower 节点完成事务的提交后,Leader 节点就会把该 Follower 节点加入可用的 Follower 列表中,该Follower 节点就可以对外提供服务了。

除了 Follow 节点需要进行数据同步外,Zookeeper 集群还有一种叫做 Observer 的节点会进行数据同步,那么我们接下来简单介绍一下 Observer 节点。

3. Observer

Observer 节点是 Zookeeper 3.3.0 版本新增的 Zookeeper 集群的角色,Observer 作为观察者在 Zookeeper 集群中观察 Zookeeper 集群的最新的数据变化,然后从 Leader 节点获取最新变化的数据并同步到自身,然后再向外提供服务。

Observer 节点可以独立的处理 Zookeeper 客户端的非事务请求,也就是查询请求。如果接收到 Zookeeper 客户端的事务请求,Observer 节点会把请求转发给 Leader 节点,但不会接收到 Leader 节点的 Proposal 事务提案,避免影响 Zookeeper 集群处理事务请求的效率。这是 Observer 节点与 Follower 节点的区别之一。

Observer 节点与 Follower 节点的区别之二,Observer 节点不会参与 Zookeeper 集群的 Leader 选举,避免太多候选者而降低 Zookeeper 集群选举 Leader 的效率。

简单的介绍了 Observer 节点是什么,以及 Observer 节点和 Follower 节点的区别,接下来我们讲解 Observer 节点是如何实现与 Leader 节点进行数据同步的。

3.1 Observer 的数据同步

增加 Observer 节点的主要作用是用来提高 Zookeeper 集群的非事务请求的效率,我们可以在 zoo.cfg 配置文件中添加如下配置:

# 声明此服务为 Observer 节点
peerType=observer

在 zoo.cfg 中配置 Zookeeper 服务列表时需要添加 observer 标识:

# 添加 observer 标识,声明 server.1 为 Observer 节点
server.1:192.168.0.77:2181:3181:observer

我们启动 Zookeeper 服务时,会加载配置文件的 peerType 属性来识别该服务是否为 Observer 节点,如果是 Observer 节点,就会使用 ObserverZooKeeperServer 类来实例化该 Observer 节点。

由于 Observer 节点不接收 Leader 节点广播的 Proposal 事务提案,也就不能在这一步获取 Proposal 事务提案中的事务请求,那么 Observer 节点如何获得事务请求的信息呢?答案是 Observer 节点会从 INFORM 消息中获取已提交的事务信息。

INFORM 消息是 Leader 节点在自身的事务提交成功后向 Observer 节点发出的消息,通知 Observer 更新数据。Observer 接收到 Leader 节点发出的 INFORM 消息后,从 INFORM 消息中获取 Leader 节点已经提交的事务,就可以对自身的数据进行更新了,而且不需要向Leader 节点发送反馈信息。

INFORM 消息

4. 总结

在本节内容中,我们学习了 Zookeeper ZAB 协议的消息广播模式,以及在消息广播模式中 Zookeeper 集群的各个节点的数据同步过程,还有 Observer 节点的特点以及 Observer 节点的数据同步。以下是本节内容总结:

  1. Zookeeper ZAB 协议的消息广播模式。
  2. 消息广播模式下的数据同步过程。
  3. Observer 节点的特点。
  4. Observer 节点与 Leader 节点的数据同步。