ZooKeeper

ZooKeeper 概述

分布式应用

分布式应用可以在给定时间(同时)在网络中的多个系统上运行,通过协调它们以快速有效的方式完成特定任务。

分布式应用正在运行的一组系统称为 集群,而在集群中运行的每台机器被称为 节点

分布式应用有两部分, Server(服务器)Client(客户端) 应用程序。服务器应用程序实际上是分布式的,并具有通用接口,以便客户端可以连接到集群中的任何服务器并获得相同的结果。 客户端应用程序是与分布式应用进行交互的工具。

ZooKeeper 是一个分布式协调服务的开源框架。主要用来解决分布式集群中应用系统的一致性的问题,例如怎样避免同时操作同一数据造成脏读的问题。ZooKeeper 本质上是一个分布式的小文件存储系统。提供基于类似于文件系统的目录树方式的数据存储,并且可以对树种 的节点进行有效管理。从而来维护和监控你存储的数据的状态变化。将通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。诸如:统一命名服务(dubbo)、分布式配置管理(solr的配置集中管理)、分布式消息队列(sub/pub)、分布式锁、分布式协调等功能。

个人理解,ZooKeeper 由以下部分组成

  • 使用 zab 协议维护了一整个具有一致数据的集群
  • 规定了数据的结构为层次结构,类似于文件系统
  • 实现了数据变更监听

Zookeeper 的感性认知

Zookeeper 搭建了一个集群,我可以对该集群进行以下操作

  • 读取 /xx/xx 中的数据
  • 新建一个 znode (目录) /xx/a
  • 修改一个 znode 中的数据 /xx/a
  • 监听一个 znode 中数据的改变 /xx/a

Zookeeper 架构图

Zookeeper 集群的结构实际上是 zab 协议的集群结构。

image20210829154007314.png

  • Leader:事务请求(写操作)的唯一调度和处理者,保证集群事务处理的顺序性。对于 create,setData,delete 等有写操作的请求,则需要统一转发给 leader 处理,leader 需要决定编号、执行操作,这个过程称为一个事务。
  • Follower:处理客户端非事务(读操作)请求,因为 zab 协议会保证节点的数据一致,转发事务请求给 Leader 参与集群 Leader 选举投票。
  • Observer:观察者,观察ZooKeeper集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给Leader服务器处理 不会参与任何形式的投票只提供服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力(增加并发请求)。

Zookeeper 的特性

  1. 全局数据一致:每个 server 保存一份相同的数据副本,client 无论连接哪一个 server,获取的数据都是一致。
  2. 可靠性:如果消息被其中一台服务接受,那么将被所有服务器接受。
  3. 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息 a 在消息 b 前发布,则在所有 server 上消息 a 在消息 b 前被发布,偏序是指如果一个消息 b 在消息 a 后被同一个发送者发布,a 必须将排在 b 前面
  4. 数据更新原子性:数据更新要么成功要么失败
  5. 实时性:ZooKeeper 保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息

根据 CAP 定理,Zookeeper 满足了分区容错性与数据一致性,则没有高可用性,当出现分区等情况时,整个系统会一直等到分区消除,

ZooKeeper 的好处

  • 简单的分布式协调过程
  • 同步 - 服务器进程之间的相互排斥和协作
  • 有序的消息
  • 序列化
  • 可靠性
  • 原子性

Zookeeper 基础

层次命名空间 ( Hierarchical namespace)

下图描述了用于内存表示的 ZooKeeper 文件系统的树结构。ZooKeeper 节点称为 znode 。每个 znode 由一个名称标识,并用路径 / 序列分隔。

这里的 znode 是一个抽象的概念,实际上,在 zookeeper 集群中,每个主机的数据都是一致的,而这些 znode 组成的树就是这些主机中存的数据 。为了避免与分布式系统中的 节点 混淆,之后统一使用 znode 。

  • 首先由一个由 / 分割的 znode,有两个逻辑命名空间 config 和 woekers
  • config 命名空间用于集中式配置管理,workers 命名空间用于命名
  • config 命名空间下,每个 znode 最多可存储 1 MB 的数据 。

image20210829202349686.png

Znode兼具文件和目录两种特点。既像文件一样维护着数据长度、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。每个Znode由三个部分组成:

  • stat:此为状态信息,描述该Znode版本、权限等信息。

  • data:与该Znode关联的数据

  • children:该Znode下的节点

  • 版本号 - 每个 znode 都有版本号,这意味着每当与 znode 相关联的数据发生变化时,其对应的版本号也会增加。当多个 zookeeper 客户端尝试在同一 znode 上执行操作时,版本号的使用就很重要。

  • 操作控制列表(ACL) - ACL 基本上是访问 znode 的认证机制。它管理所有 znode 读取和写入操作。

  • 时间戳 - 时间戳表示创建和修改 znode 所经过的时间。它通常以毫秒为单位。ZooKeeper 使用 “事务ID"(zxid) 标识 znode 的每个更改。Zxid 是唯一的,并且为每个事务保留时间,以便你可以轻松地确定从一个请求到另一个请求所经过的时间。

  • 数据长度 - 存储在znode中的数据总量是数据长度。你最多可以存储1MB的数据。

znode 的类型

  • 持久 (persistent) 节点 - 创建该节点的客户端断开连接后,依然存在,默认节点都是持久节点。
  • 临时 (ephemeral) 节点 - 客户端活跃时,临时节点就是有效的。当客户端与 ZooKeeper 集合断开连接时,临时节点会自动删除。因此,只有临时节点不允许有子节点。如果临时节点被删除,则下一个合适的节点将填充其位置。临时节点在 leader 选举中起着重要作用。
  • 顺序 (sequential) 节点 - 顺序节点可以是持久的或临时的。当一个新的znode被创建为一个顺序节点时,ZooKeeper通过将10位的序列号附加到原始名称来设置znode的路径。例如,如果将具有路径 /myapp 的znode创建为顺序节点,则ZooKeeper会将路径更改为 /myapp0000000001 ,并将下一个序列号设置为0000000002。如果两个顺序节点是同时创建的,那么ZooKeeper不会对每个znode使用相同的数字。顺序节点在锁定和同步中起重要作用。

会话 (Sessions) 与 监视 (Watches)

  • 会话对于 ZooKeeper 的操作非常重要。会话中的请求按FIFO顺序执行。一旦客户端连接到服务器,将建立会话并向客户端分配会话ID

    客户端以特定的时间间隔发送 心跳 以保持会话有效。如果 ZooKeeper 集合在超过服务器开启时指定的期间(会话超时)都没有从客户端接收到心跳,则它会判定客户端死机。

    会话超时通常以毫秒为单位。当会话由于任何原因结束时,在该会话期间创建的临时节点也会被删除。

集群中每个主机都维护了一个队列,一旦客户端连接到 zookeeper 集群,实际上是连接到其中一个节点。该节点会与客户端建立会话并保持。对于客户端的读请求,则直接返回,对于客户端的写请求,则转发给 leader,由 leader 发起数据更新的提案,然后所有节点都同步更新。

  • 监视是一种简单的机制,使客户端收到关于 ZooKeeper 集合中的更改的通知。客户端可以在读取特定 znode 时设置 Watches 。Watches 会向注册的客户端发送任何 znode (客户端注册表)更改的通知。

    Znode 更改是与 znode 相关的数据的修改或 znode 的子项中的更改。只触发一次 watches。如果客户端想要再次通知,则必须通过另一个读取操作来完成。当连接会话过期时,客户端将与服务器断开连接,相关的 watches 也将被删除。

Zookeeper 用处

zookeeper 在底层的作用就是维护一个 树形结构,保证各主机数据一致并提供监听服务,而在业务层面,Zookeeper 可以实现许多功能,如:

  • 命名服务 - 类似于微服务注册中心,将服务名作为 znode 路径,而在数据中心存微服务主机的 ip 端口,则可以进行服务注册与服务发现
  • 配置管理 - 可以存储数据,则可以用来进行配置管理,存放分布式系统中各个服务的配置数据
  • 集群管理 - 管理分布式系统中的集群,提供节点加入与离开功能(没有抽象出微服务的集群)
  • 锁定和同步服务 - 可实现分布式锁 等服务(对某个 znode 的数据进行 cas 操作)
  • 数据注册表 - 高度可靠的数据存储集群。

以下是使用了 zookeeper 的优秀库

  • Apache Hadoop

    Apache Hadoop 是一套用于在由通用硬件构建的大型集群上运行应用程序的框架。简单地说,是一套在分布式系统中运行大数据分析,储存数据等的一系列功能的解决方案。其内部就使用了 zookeeper 进行任务的序列化和同步化。

  • Apache Hbase

    ApacheHbase 是一个开源的,分布式的 NoSQL 数据库。其内部遵循了主从结构,使用了 Zookeeper 实现。

  • Apache Solr

    Apache Solr 是一个快速,容错的分布式搜索引擎 。其广泛使用了 zookeeper 的每个功能。