Zookeeper 及 相关概念简介

一、简介

​ ZooKeeper 是一个开源的分布式协调服务,由雅虎创建并贡献给 Apache 软件基金会,现已成为 Apache 顶级项目之一。ZooKeeper 主要用于解决分布式应用中常见的数据管理、状态同步、集群协调等问题,为大型分布式系统提供高效且可靠的协同机制。

Zookeeper 是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。

二、特点和功能

ZooKeeper 的主要特点和功能简介:

  1. 数据模型与一致性保证: ZooKeeper 提供一个类似于文件系统的树形数据结构(命名空间),节点称为"ZNode",每个 ZNode 可以存储少量的数据(通常几 KB 到几十 KB)。ZooKeeper 保证在分布式环境中对 ZNode 的读写操作具有强一致性,即更新成功后所有后续的读请求都能看到最新的值,遵循 CP(Consistency, Partition-tolerance)原则。
  2. 分布式协调服务 : ZooKeeper 提供多种原语(Primitive)来实现分布式协作,如:
    • 分布式锁:通过临时节点和节点监听机制实现互斥锁、读写锁等。
    • 领导者选举:多个节点竞争成为集群的领导者,其他节点作为追随者。例如,在分布式系统中选择一个主节点进行任务分配或数据处理。
    • 配置管理与服务发现:存储、分发和动态更新集群的配置信息,或者作为服务注册中心,使得客户端能够发现并连接到可用的服务实例。
    • 组成员管理:跟踪集群中节点的加入、离开情况,支持心跳检测和会话管理。
  3. 原子性与有序性: ZooKeeper 提供原子性的读写操作,保证更新要么全部完成,要么不发生。此外,客户端观察到的操作顺序与全局一致,即所有客户端看到的操作序列是完全相同的。
  4. Watches 机制: ZooKeeper 支持客户端对 ZNode 的数据变化或子节点列表变化设置监视器(Watch)。当监控的事件发生时,ZooKeeper 会向客户端发送通知。Watches 是一次性的触发器,即触发后需要重新设置。这种机制使得分布式系统中的节点能够实时感知到状态变化,实现高效的事件驱动编程。
  5. 高可用性与容错性: ZooKeeper 集群通常由奇数个节点构成,采用 ZAB(ZooKeeper Atomic Broadcast)协议保证在部分节点故障的情况下仍能正常服务。ZAB 协议确保了数据的一致性和系统的恢复能力,即使在 Leader节点失败时也能快速选举出新的 Leader,并使集群恢复到一致状态。

三、Zookeeper数据结构

  • ZooKeeper 数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树,每个节点称做一个 ZNode。
  • 每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode 都可以通过其路径唯一标识。

ZooKeeper 的数据结构是一种层次化的命名空间,类似于传统的文件系统,但具有特定的特性和用途。以下是 ZooKeeper 数据结构的主要特点和组成部分:

命名空间(Namespace)

  • 路径表示 :ZooKeeper 中的每个数据节点(ZNode)通过路径进行唯一标识,路径由一系列由斜杠(/)分隔的路径元素组成。例如,/app/config/server1 表示一个名为 server1 的 ZNode,位于 /app/config 这个父节点下。
  • 层级结构:如同文件系统的目录树,ZooKeeper 的命名空间支持无限层级的嵌套。这种结构使得数据可以根据逻辑关系组织成层次分明的树状结构。

ZNode(数据节点)

  • 数据存储:每个 ZNode 存储一个小型的、字节形式的数据块。虽然实际限制可能随版本和配置有所不同,通常建议每个 ZNode 存储的数据不超过 1 MiB,以保持系统高效运行。ZNode 存储的数据可以是配置信息、状态标志、临时状态等。
  • 元数据 :除了用户数据外,每个 ZNode 还包含一些元数据,如:
    • 版本号(version):每次对 ZNode 的数据或元数据进行修改时,版本号都会递增,用于实现乐观锁控制。
    • 时间戳(ctime, mtime):分别记录节点创建时间和最近一次修改时间。
    • ACL(Access Control List):定义了哪些用户或角色对 ZNode 具有何种访问权限。
    • 临时节点标记:ZNode 可以是持久的(persistent)或临时的(ephemeral)。临时节点在创建它的会话结束时会被自动删除,常用于表示会话相关状态。

节点类型

在 ZooKeeper 中,主要存在以下四种类型的 ZNode(数据节点):

  1. 持久节点(Persistent Node)

    • 标识:无特殊标记
    • 特征:一旦创建,除非被客户端明确地删除,否则会一直存在于 ZooKeeper 集群中。即使创建该节点的客户端会话结束,持久节点也不会被自动删除。
    • 用途:用于存储需要长期保留且不受客户端会话生命周期影响的数据,如系统配置、静态资源映射、固定角色分配等。
  2. 临时节点(Ephemeral Node)

    • 标识ephemeral
    • 特征:与创建它的客户端会话绑定。当客户端会话结束(如客户端主动关闭连接、网络中断或会话超时)时,临时节点会被自动删除。临时节点不能拥有子节点。
    • 用途:表示与客户端会话相关的瞬时状态,如客户端在线状态、临时资源分配、会话关联的锁等。临时节点的生命周期与客户端会话一致,有助于实现会话失效时资源的自动清理。
  3. 顺序节点(Sequential Node)

    • 标识sequential
    • 特征:在创建节点时,ZooKeeper 会在节点名称后面自动追加一个递增的数字后缀,确保节点名称在整个集群中是唯一的。顺序节点可以是持久节点(Persistent Sequential Node)或临时节点(Ephemeral Sequential Node)。
    • 用途:用于生成全局唯一的序列号,适用于分布式环境中需要唯一标识的任务、消息、租约等场景。顺序节点还可以用于实现基于节点创建顺序的公平锁、队列等数据结构。
  4. 带过期时间的节点(TTL-based Node)

    • 标识PERSISTENT_SEQUENTIAL_WITH_TTL 或类似的表述,具体取决于 ZooKeeper 版本和 API 实现。
    • 特征:除了具备持久节点或临时节点的基本属性外,这类节点还设置了过期时间(Time-to-Live, TTL)。在指定的时间间隔过后,如果节点未被显式更新或删除,ZooKeeper 会自动删除该节点。
    • 用途:用于存储具有有效期的临时或持久数据,如定时清理的临时资源、定时任务的注册信息、具有生存周期的会话关联状态等。过期时间机制可以减轻系统中需要定期清理过期数据的负担。

这四种类型的 ZNode 结合使用,可以满足分布式系统中多样化的数据管理需求,如状态存储、资源分配、协调控制、定时清理等。根据实际应用场景选择合适的节点类型,有助于优化系统设计和提升协调效率。请注意,不同 ZooKeeper 版本或实现可能对节点类型的支持有所差异,具体功能应参考所使用的 ZooKeeper 文档或 API 参考。

四、Watch(监视器)

ZooKeeper 提供了一种强大的事件监听机制------Watch(监视器),允许客户端订阅特定节点的变化事件。当订阅的事件发生时,ZooKeeper 服务端会向相应的客户端发送通知。Watch 事件监听是 ZooKeeper 实现分布式协调、状态同步等核心功能的关键手段之一。

类型与触发条件

ZooKeeper 支持两种类型的 Watch 事件:

  1. 数据变更 Watch(Data Watches)

    当客户端对某个 ZNode 设置数据变更 Watch 后,如果该 ZNode 的数据内容发生任何更改(包括创建、更新、删除),ZooKeeper 会向客户端发送一个通知。注意,数据变更 Watch 是一次性触发器,即触发后需要客户端重新设置才能继续监听后续变化。

  2. 子节点列表变更 Watch(Child Watches)

    如果客户端对某个 ZNode 设置子节点列表变更 Watch,当该 ZNode 的子节点集发生变化(新增、删除子节点)时,ZooKeeper 会发送通知。同样,子节点列表变更 Watch 也是一次性触发器。

设置 Watch

客户端可以通过以下方式设置 Watch:

  • 使用 ZooKeeper API

    在使用 ZooKeeper 客户端库(如 Java 的 org.apache.zookeeper.ZooKeeper 类)编写程序时,可以在相应方法中指定是否设置 Watch。例如,getData() 方法可以设置数据变更 Watch,getChildren() 方法可以设置子节点列表变更 Watch。

  • 使用 ZooKeeper 命令行工具

    在 ZooKeeper 命令行客户端(如 zkCli.sh)中,通过在命令中添加 watch 参数来设置 Watch。例如,get path watch 会在获取数据的同时设置数据变更 Watch,ls path watch 会在列出子节点的同时设置子节点列表变更 Watch。

事件通知与处理

当触发 Watch 的事件发生时,ZooKeeper 服务端会通过客户端与服务端之间已建立的连接,向客户端发送一个 Watch 事件通知。通知包含以下信息:

  • 事件类型

    指明触发的具体事件类型,如 NodeDataChanged(数据变更)、NodeDeleted(节点删除)、NodeChildrenChanged(子节点列表变更)等。

  • 节点路径

    发生事件的 ZNode 的完整路径。

  • 状态码

    通常表示事件通知的成功与否,以及可能的错误代码。

客户端在接收到 Watch 事件通知后,通常会调用预定义的回调函数(使用 ZooKeeper API 时)或在命令行中显示通知(使用命令行工具时),以便应用程序及时响应事件并采取相应的行动。

注意事项

  • 一次性触发

    Watch 是一次性触发器,这意味着一旦触发事件并发送通知后,该 Watch 就会自动移除。若想继续监听同一事件,客户端需在接收到通知后重新设置 Watch。

  • 异步通知

    Watch 事件通知是异步发送的,不保证立即送达。客户端在设置 Watch 后,不应假设事件会立即触发或通知会立即到达。

  • 客户端会话状态

    如果客户端会话由于网络问题、超时等原因中断,所有与该会话关联的 Watch 将被移除,客户端需要在重新建立会话后重新设置 Watch。

  • 性能考虑

    大规模集群中大量使用 Watch 可能会影响 ZooKeeper 服务端的性能。在设计系统时应合理规划 Watch 的使用,避免过度依赖或滥用。

应用场景

Watch 事件监听广泛应用于分布式系统中的各种场景,如:

  • 配置变更通知

    当存储在 ZooKeeper 中的配置数据发生变化时,客户端可以立即得到通知并应用新的配置。

  • 服务发现

    客户端监听服务注册节点的子节点列表变化,实时掌握服务实例的上线、下线情况。

  • 分布式锁与同步

    客户端通过监听锁节点的状态变化来实现锁的获取与释放,或者通过监听同步点的变化实现分布式流程的协调。

  • 集群管理与监控

    监控集群中节点的状态变化,及时发现异常并作出响应。

总之,ZooKeeper 的 Watch 事件监听机制为分布式系统提供了实时、灵活的事件驱动能力,极大地简化了状态同步、协调控制等复杂问题的实现,是 ZooKeeper 作为分布式协调服务的核心特性之一。

五、客户端常用命令

ZooKeeper 客户端提供了丰富的命令来与 ZooKeeper 集群进行交互,以下是一些常用的客户端命令及其用途:

连接与会话管理

  1. 连接服务器

    bash 复制代码
    ./zkCli.sh [-server host:port] [options]
    • -server host:port:指定要连接的 ZooKeeper 服务器地址和端口。如果省略,可能会使用默认配置或尝试连接本地服务器。
    • options:可选参数,如设置超时时间(-timeout)、启用只读模式(-readonly)等。
  2. 列出当前连接的服务器信息

    bash 复制代码
    stat
  3. 退出客户端

    bash 复制代码
    quit

节点操作

  1. 查看节点信息

    bash 复制代码
    ls [-s] [-w] [-R] path
    • ls:列出指定路径下的子节点。
    • -s:显示节点的统计信息(大小、子节点数量等)。
    • -w:显示节点的 watches信息。
    • -R:递归列出所有子节点及其子节点。
  2. 创建节点

    bash 复制代码
    create [-s] [-e] [-c] [-t ttl] path data [acl]
    • create:创建一个节点。
    • -s-sequential:创建顺序节点,自动在节点名后添加递增的序列号。
    • -e-ephemeral:创建临时节点,与客户端会话关联,会话结束时节点自动删除。
    • -c-container(可能需要特定版本或插件支持):创建容器节点,用于批量管理子节点。
    • -t ttl:(可能需要特定版本或插件支持)设置节点的过期时间(TTL)。
    • path:节点路径。
    • data:节点存储的数据(字符串形式)。
    • acl:可选的访问控制列表(ACL),如 world:anyone:cdrwa
  3. 读取节点数据

    bash 复制代码
    get path [watch]
    • get:获取节点的当前数据。
    • watch:可选参数,设置数据观察者(watcher),当节点数据发生变化时,客户端收到通知。
  4. 更新节点数据

    bash 复制代码
    set path data [version]
    • set:更新节点数据。
    • path:节点路径。
    • data:新的节点数据(字符串形式)。
    • version:可选参数,指定节点版本号,用于乐观锁控制。
  5. 删除节点

    bash 复制代码
    delete path [version]
    • delete:删除指定节点。
    • path:节点路径。
    • version:可选参数,指定节点版本号,用于乐观锁控制。

监听与通知

  1. 设置节点数据观察

    bash 复制代码
    get path [watch]

    如前所述,通过 get 命令并指定 watch 参数,可以设置对节点数据变化的通知。

  2. 设置子节点列表观察

    bash 复制代码
    ls [-w] path

    使用 ls 命令并指定 -w 参数,可以设置对节点子节点列表变化的通知。

访问控制

  1. 查看节点ACL

    bash 复制代码
    getAcl path

    显示指定节点的访问控制列表(ACL)。

  2. 设置节点ACL

    bash 复制代码
    setAcl path acl

    修改指定节点的访问控制列表(ACL)。

其他操作

  1. 检查节点是否存在

    bash 复制代码
    exists path [watch]

    检查指定节点是否存在,可选地设置数据观察者(watcher)。

  2. 重置客户端会话

    bash 复制代码
    session [-password password] [-read [-watches]] | [-write] | [-delete|-create|-multi|-reconfig] | [-setid id]

    用于管理客户端会话,如设置会话密码、切换会话模式(只读/读写)等。

以上列举的是 ZooKeeper 客户端常用的命令,实际使用时请根据具体版本的 ZooKeeper 和客户端工具(如 zkCli.sh)提供的功能进行操作。部分高级功能或特定版本的特性可能未在此处涵盖,建议查阅官方文档或使用时的命令帮助信息以获取最准确的信息。

相关推荐
YDS82911 分钟前
黑马点评 —— 分布式锁详解加源码剖析
java·spring boot·redis·分布式
hashiqimiya26 分钟前
windows的hadoop集群环境直接配
大数据·hadoop·分布式
guoji77886 小时前
ChatGPT镜像站实战:从零设计高可用分布式任务调度系统
分布式·chatgpt
csdn_aspnet7 小时前
GitOps宣言:Kubernetes配置的版本化革命
云原生·容器·kubernetes·gitops
半桶水专家9 小时前
Kafka 4.0.1 KRaft 模式完整部署指南
分布式·kafka·linq
xmlhcxr9 小时前
Docker容器常用操作与私有仓库部署实验笔记
docker·云原生·eureka
白胡子10 小时前
Kubernetes NFS 接入方案
云原生
huohuopro13 小时前
HBase 伪分布式环境安装指南
数据库·分布式·hbase
河码匠13 小时前
Kubernetes YAML 详解之网络服务二( Ingress、IngressClasses)
云原生·容器·kubernetes