分布式学习手记04 - ZooKeeper 及 ZAB 协议简介

1 分钟读完

ZooKeeper 是由雅虎创建的开源分布式协调服务,源于谷歌 Chubby,使用 ZAB (ZooKeeper Atomic Broadcast) 协议。

简介

ZooKeeper 是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

设计目标

ZooKeeper 致力于提供一个高性能、高可用、具有严格的顺序访问控制能力的分布式协调服务。

  • 目标 1 简单的数据模型

    通过一个共享的、树形结构的名字空间进行协调,并将全量数据存储在内存里,以此提高服务器吞吐、减少延迟;

  • 目标 2 可以构建集群

    过半的节点正常工作,集群就可以正常提供服务,保证高可用;

  • 目标 3 顺序访问

    使用全局唯一的递增编号,达到顺序访问控制,实现复杂的同步原语;

  • 目标 4 高性能

    尤其适用读操作为主的应用场景。

概念名词

ZooKeeper 的几个核心概念

  • 集群角色

    Leader - 为客户端提供读和写服务;

    Follwer - 参与写操作的 “过半写成功” 策略,提供读服务,参与 Leader 的选举过程;

    Observer - 提供读服务。

  • Session

    客户端会话,客户端和服务器端会创建一个 TCP 长连接,通过该连接,客户端可以通过心跳检测与服务器保持有效的会话,向其发送请求并接受响应。

  • ZNode

    数据模型中的数据单元,ZooKeeper 的数据模型是一棵树 (ZNode Tree),由 / 进行分割的路径就是一个 ZNode。每个 ZNode 上会保存自己的数据内容及相关属性信息。

  • 版本

    对应于每个 ZNode,ZooKeeper 都会为其维护一个叫 Stat 的数据结构,Stat 中记录该 ZNode 的三个数据版本:

    version - 当前 ZNode 的版本;

    cversion - 当前 ZNode 子节点的版本;

    aversion - 当前 ZNode 的 ACL 版本。

  • Watcher

    事件监听器,ZooKeeper 允许用户在指定节点上注册一些 Watcher,并在特殊事件触发时,由 ZooKeeper 服务端将事件通知推送给目标客户端。

  • ACL

    ZooKeeper 采用 ACL (Access Control Lists) 策略进行权限控制,包括 CREATE、READ、WRITE、DELETE、ADMIN 五种权限。

ZAB 协议

ZooKeeper Atomic Broadcast 是特别为 ZooKeeper 设计的崩溃可恢复的原子消息广播算法。

模式

ZAB 协议包括崩溃恢复和消息广播两种模式:

  • 崩溃恢复

    当整个服务框架启动时,或当 Leader 节点发生故障,ZAB 协议就会进入崩溃恢复模式:选举新的 Leader,当集群中超过半数机器与新 Leader 完成状态同步(数据同步),ZAB 协议就退出崩溃恢复,进入消息广播模式;

  • 消息广播

    原子广播的过程类似二阶段提交:针对客户端的事务请求,Leader 节点为其生成对应的事务提议 (Proposal) ,并将其发送给集群中其余所有机器,再收集选票,决定是否进行事务提交。此外,广播协议基于具有 FIFO 特性的 TCP 协议进行网络通信,从而保证消息接收与发送的顺序性。

算法描述

ZAB 协议包括消息广播和崩溃恢复两个过程,细分为三个阶段:发现 -> 同步 -> 广播。

参与协议的每一个分布式进程,会循环执行这三个阶段,一个循环称为一个主进程周期。

== 阶段 1 - 发现

发现阶段即 Leader 选举过程,在多个分布式进程中选举出主进程。

1.1 Follower 将自己最后接受的事务主进程周期 epoch 值发送给准 Leader L

  • 事务标识包括两个部分:主进程周期 epoch(高 32 位) + 主进程周期内的事务计数 counter(低 32 位,从 0 递增)

1.2 接收到超过半数 Follower 的 epoch 消息后,L 生成新的 epochnew ,发送给这些 Follower;

  • epochnew 是 L 收到的所有 epoch 中最大值加一

1.3 Follower 收到 L 发送的 epochnew ,更新自己的 epoch 值并向 L 反馈 Ack 消息;

  • 这个 Ack 消息包含当前 Follower 的 epochnew 和该 Follower 的历史事务提议集合 I

== 阶段 2 - 同步

2.1 L 将 epochnew 和 I 打包成 NewLeader(e,I) 消息发送给所有 Follower;

2.2 Follwer 接收到 NewLeader(e,I) 消息后:若 epochnew 和该 Follower 本地的 epoch 不匹配,则该 Follower 无法参与本轮同步,进入下一轮循环;若能匹配,则 Follower 执行事务的应用操作,完成后向 L 发送反馈;

2.3 L 接收到过半 Follower 对 NewLeader(e,I) 的反馈后,向所有 Follower 发送 Commit 消息;

2.4 Follower 收到 Lnew 的 Commit 消息后,依次处理并提交所有前期事务集合;

== 阶段 3 - 广播

完成数据同步后,崩溃恢复阶段结束,ZAB 协议开始接收客户端新的事务请求,进行消息广播流程

3.1 Lnew 接收到客户端新的事务请求后,生成对应的事务 Proposal,向所有 Follower 发送提案;

3.2 Follower 根据先后次序处理收到的提案,向 Lnew 发送反馈 Ack;

3.3 Lnew 收到过半 Follower 对事务的 Ack 消息,发送 Commit 给所有 Follower,要求它们进行事务的提交;

3.4 Follower 收到 Lnew 的 Commit 消息后,提交该事务。

运行状态

整个框架运行过程中,每一个进程可能处于三种状态之一

  • LOOKING - Leader 选举阶段

    框架启动阶段,所有进程的初始化状态;或 Leader 崩溃时,Follower 会转换到该状态。处于 LOOKING 状态的进程都会试图选举一个新的 Leader。

  • FOLLOWING - Follower 节点和 Leader 保持同步状态

    产生新的 Leader 后,Follower 处于该状态,与唯一的 Leader 保持同步。

  • LEADING - Leader 服务器作为主进程领导状态

    选举完成后,新的 Leader 处于该状态。

分类:

更新时间: