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)提供的功能进行操作。部分高级功能或特定版本的特性可能未在此处涵盖,建议查阅官方文档或使用时的命令帮助信息以获取最准确的信息。

相关推荐
Data跳动2 小时前
Spark内存都消耗在哪里了?
大数据·分布式·spark
Java程序之猿4 小时前
微服务分布式(一、项目初始化)
分布式·微服务·架构
来一杯龙舌兰4 小时前
【RabbitMQ】RabbitMQ保证消息不丢失的N种策略的思想总结
分布式·rabbitmq·ruby·持久化·ack·消息确认
Karoku0665 小时前
【k8s集群应用】kubeadm1.20高可用部署(3master)
运维·docker·云原生·容器·kubernetes
节点。csn6 小时前
Hadoop yarn安装
大数据·hadoop·分布式
NiNg_1_2347 小时前
基于Hadoop的数据清洗
大数据·hadoop·分布式
隔着天花板看星星8 小时前
Spark-Streaming集成Kafka
大数据·分布式·中间件·spark·kafka
探索云原生10 小时前
在 K8S 中创建 Pod 是如何使用到 GPU 的: nvidia device plugin 源码分析
ai·云原生·kubernetes·go·gpu
启明真纳10 小时前
elasticache备份
运维·elasticsearch·云原生·kubernetes
技术路上的苦行僧13 小时前
分布式专题(8)之MongoDB存储原理&多文档事务详解
数据库·分布式·mongodb