Zookeeper 的数据模型

1. 前言

开始学习 Zookeeper 的第一步,我们首先来学习 Zookeeper 的数据模型。那么我们为什么要先学习 Zookeeper 的数据模型呢?Zookeeper 的数据模型又是什么样的呢?Zookeeper 的数据模型又有什么样的特点呢?接下来我们就带着这几个问题开始 Zookeeper 的数据模型学习之旅。

2. Zookeeper 数据模型的结构

Zookeeper 数据模型的结构是基于节点的,我们把这种节点叫做 Znode ,具体结构我们来看下图:
Zookeeper 数据模型的结构
我们可以看见,这种结构和数据结构中的树类似,也和文件系统的目录类似。我们知道文件系统的引用是非常方便的,那么我们想引用 Zookeeper 某个节点,那么我们该如何引用呢?
我们可以通过路径引用的方式来访问 Znode 节点:

/电脑/戴尔
/手机/华为

我们来说明一下书写规则:第 1 个 / 为根节点,电脑 为根节点的子节点,第 2 个 / 是对下一个子节点的引用,后面跟上哪个节点的名称,就是对哪个节点的引用。

Tips: 我们对节点的引用,必须书写全路径,也就是说必须要从根节点开始。在 Zookeeper 底层的实现中,把 Znode 的绝对路径作为 key ,Znode 本身作为 value 来保存的。使用绝对路径来查询也提高了 Zookeeper 的性能。

介绍完 Zookeeper 数据模型的结构,也了解了如何引用 Znode 节点,接下来我们对 Znode 节点进行详细的讲解。

3. Znode 的元素组成

我们先来了解 Znode 节点中由哪些元素组成,请看下图:
Znode 的元素组成
我们可以看到,Znode 节点中由 4 种元素组成,接下来我们来分别介绍一下每个元素具体是什么。
Znode 节点元素介绍:

  • data : Znode 存储的数据信息,这里的数据指用户保存的数据;
  • ACL : 对节点进行权限控制,记录了哪些用户或者哪些 IP 地址可以访问本节点;
  • child : 当前节点的子节点引用,通过这个节点来找到它的子节点;
  • stat : 包含 Znode 的各种元数据,比如事务 ID、版本号、时间戳、大小等 Znode 本身的数据。

Tips: Znode 的 data 元素存储的信息最大不能超过 1MB 。太大的数据会影响 Zookeeper 的同步性能。

在了解了 Znode 的元素组成,每个元素的具体作用之后,我们接下来学习 Znode 节点有哪些类型,以及他们的特点。

4. Znode 的类型

本节我们来学习 Znode 的类型以及它们各自的特点。Znode 的类型分为一下 4 种:

  • 持久节点: 持久节点是 Zookeeper 的默认节点,持久节点被创建后会一直存在,除非进行手动删除;
  • 持久顺序节点: 持久顺序节点是在持久节点的基础上,增加了顺序性。也就是说,持久顺序节点被创建时,会根据创建的时间进行编号,根据编号我们就可以判断它们的顺序;
  • 临时节点: 临时节点与持久节点的特点相反,临时节点被创建之后,如果与创建它的客户端断开连接,临时节点就会被销毁;
  • 临时顺序节点: 临时顺序节点就是在临时节点的基础上,增加了顺序性。

学习了 Znode 节点的类型以及它们的特点,那么我们可以利用节点的特点做什么事情呢?接下来我们来了解节点的应用。

5. Znode 的应用

根据节点的类型以及它们的特点,我们可以实现以下功能:

  1. 我们可以使用临时节点来实现服务注册与发现。在某个服务注册到 ZooKeeper 时,我们可以让这个这个服务创建一个临时节点,并把它的访问信息交给到 Zookeeper 维护。当这个服务与 Zookeeper 断开连接时,这个临时节点就会被销毁,这时 Zookeeper 发现这个服务离线了,就会移除它的访问地址,避免出现 404 的情况。我们也可以手动删除某个临时节点让相对应的服务下线;

  2. 当我们有大量的服务时,一旦配置信息需要修改,会消耗我们大量的时间去每个服务中修改,而且还有可能会出错,这种情况我们就可以使用持久节点来保存全局的配置信息。当某个服务注册到 ZooKeeper 时,可以去保存配置信息的节点读取配置信息。当我们修改配置时,Zookeeper 会通知这些服务,服务就会重新去读取配置信息;

  3. 我们可以使用临时顺序节点来实现分布式锁。当多个服务同时对一个资源进行修改时,会出现数据错误,所以我们要避免这种情况。我们这里采取的方式就是为这个资源加锁,想要获取这个资源的服务会创建一个临时顺序节点,根据它的顺序判断这个临时顺序节点是否为第一个,如果是第一个则成功获得锁,这时这个服务就可以对这个资源进行修改了。完成操作后或者这个服务断线了都会删除这个节点,也就是释放了锁。后面的服务会根据它创建的临时顺序节点的顺序来依次对资源进行操作。

根据 Znode 特点的来实现的应用还有很多,后面的文章我们再详细介绍。了解了节点的一些应用,那么我们该如何对节点进行操作呢?接下来我们就来介绍 Znode 节点的操作命令。

6. Znode 节点的操作

使用 Zookeeper 客户端,我们可以通过以下命令来操作 Znode 节点。

  • 创建节点: create

    # 创建一个持久节点
    create /persistent_node
    # 创建一个持久的顺序节点
    create -s /persistent_sequential_node
    # 创建一个临时节点
    create -e /ephemeral_node
    # 创建一个临时的顺序节点
    create -s -e /ephemeral_sequential_node
    
  • 删除节点: delete

    delete /config/topics/test
    
  • 获得一个节点的数据: get

    get /persistent_node
    
  • 设置一个节点的数据: set

    set /brokers myNewData
    
  • 获取子节点: ls

    # 获取根节点下的子节点
    ls /
    # 根节点下的子节点有 zk-watcher-2,zookeeper
    [zk-watcher-2, zookeeper]
    

Tips: 我们在使用这些命令操作节点时,后面的节点必须是全路径引用。

7. 总结

经过上面的讲解,我们知道了很多功能的实现都是基于 Zookeeper 的结构以及 Znode 的类型和它们的特点,所以学习 Zookeeper 的数据模型还是很有必要的。现在我们来对本节的内容进行总结:

  • Zookeeper 数据模型的结构为树形节点。
  • Znode 的元素组成有 4 种:data(用户数据)、ACL(权限信息)、child(子节点引用)、stat(元数据)。
  • Znode 的类型有 4 种:持久节点、持久顺序节点、临时节点、临时顺序节点。
  • 我们可以根据 Znode 的特点来实现各种功能,比如服务注册与发现、配置中心、分布式锁等。
  • Zookeeper 客户端操作节点的常用命令。