• Zookeeper分布式协调中间件快速入门


    1.Zookeeper 是什么?

    官⽅⽹址:https://zookeeper.apache.org/

    • ZooKeeper是一个集中的服务,用于维护配置信息、命名、提供分布式同步和提供组服务。
    • ZooKeeper主要用来解决 分布式应用 中经常遇到的一些 数据管理 功能。

    2.ZooKeeper 核心概念

    2.1 文件系统的数据模型

    ZooKeeper 维护一个 类似文件系统的树型的 数据模型。

    每个⼦⽬录项都被称作为 node(⽬录节点),和⽂件系统类似,我们能够⾃由的增加、删除 node,在⼀个node下增加、删除⼦node。

    ⑴ 创建节点:

    [zk: localhost:2181(CONNECTED) 0] create /app1
    Created /app1
    [zk: localhost:2181(CONNECTED) 1] create /app2
    Created /app2
    [zk: localhost:2181(CONNECTED) 2] create /app1/node1
    Created /app1/node1
    [zk: localhost:2181(CONNECTED) 3] create /app1/node2
    Created /app1/node2
    [zk: localhost:2181(CONNECTED) 4] create /app1/node3
    Created /app1/node3
    

    ⑵ 递归的查看所有节点:

    [zk: localhost:2181(CONNECTED) 5] ls -R /
    /
    /app1
    /app2
    /zookeeper
    /app1/node1
    /app1/node2
    /app1/node3
    /zookeeper/config
    /zookeeper/quota
    

    2.2 目录节点类型

    目前有 6 种类型的 node:(3.5.x版本以前只有前⾯四种):

    ⑴ 持久化 目录节点(Persistent Node)

    • 特点:客户端与zookeeper断开连接后,该节点依旧存在;只要不⼿动删除该节点,他将永远存在。
    [zk: localhost:2181(CONNECTED) 6] create /persistent
    Created /persistent
    

    ⑵ 持久化 顺序编号 目录节点 (Persistent Sequential Node)

    • 具有 持久化 目录节点 的特点;
    • Zookeeper 给该节点名称进⾏顺序编号
    [zk: localhost:2181(CONNECTED) 7] create -s /persistent/seq
    Created /persistent/seq0000000001
    [zk: localhost:2181(CONNECTED) 8] create -s /persistent/seq
    Created /persistent/seq0000000002
    [zk: localhost:2181(CONNECTED) 9] create -s /persistent/seq
    Created /persistent/seq0000000003
    

    注意,这个 0000000001 是十进制的。

    ⑶ 临时 目录节点 (Ephemeral Node)

    • 特点:客户端与zookeeper断开连接后,该节点被删除;
    [zk: localhost:2181(CONNECTED) 10] create -e /ephemeral
    Created /ephemeral
    

    注意临时 目录节点 不能创建 子结点:

    [zk: localhost:2181(CONNECTED) 11] create /ephemeral/child
    Ephemerals cannot have children: /ephemeral/child
    [zk: localhost:2181(CONNECTED) 12] create -e /ephemeral/child
    Ephemerals cannot have children: /ephemeral/child
    [zk: localhost:2181(CONNECTED) 13] create -s /ephemeral/child
    Ephemerals cannot have children: /ephemeral/child
    [zk: localhost:2181(CONNECTED) 14] create -e -s /ephemeral/child
    Ephemerals cannot have children: /ephemeral/child
    

    在 临时 目录节点上创建各种类型的子结点都失败了!

    退出客户端,再重启客户端,并查看目录节点:

    [zk: localhost:2181(CONNECTED) 15] quit
    root@bbeb695a7013:/apache-zookeeper-3.5.9-bin/bin# zkCli.sh
    [zk: localhost:2181(CONNECTED) 0] ls /
    

    我们发现,/ephemeral 目录节点消失了,这正符合 临时 目录节点 的特点。

    ⑷ 临时 顺序编号 目录节点 (Ephemeral Sequential Node)

    • 具有 临时 目录节点 的特点;
    • 是Zookeeper给该节点名称进⾏顺序编号

    ① 在 容器节点 下创建 临时顺序编号目录节点

    [zk: localhost:2181(CONNECTED) 2] create -c /container
    Created /container
    [zk: localhost:2181(CONNECTED) 3] create -e -s /container/
    Created /container/0000000000
    [zk: localhost:2181(CONNECTED) 4] create -e -s /container/
    Created /container/0000000001
    [zk: localhost:2181(CONNECTED) 5] quit
    

    这还挺方便的,退出的时候,所有临时结点连同容器结点一同消失了。

    ② 在 持久化顺序节点 下创建 临时顺序编号目录节点

    [zk: localhost:2181(CONNECTED) 0] create -s /a
    Created /a0000000010
    [zk: localhost:2181(CONNECTED) 4] create -s -e /a0000000010/
    Created /a0000000010/0000000000
    

    多级编号目录节点,可能会有用吧。

    ⑸ 容器 节点 (Container Node,3.5.3 版本新增)

    • 如果Container节点下⾯没有⼦节点,则Container节点在未来会被Zookeeper⾃动清除,定时任务默认60s 检查⼀次
    create -c /container
    

    注意
    容器节点主要⽤来容纳字节点,

    • 如果没有给其创建⼦节点,容器节点表现和持久化节点⼀样;
    • 如果给容器节点创建了⼦节点,后续⼜把⼦节点清空,容器节点也会被zookeeper删除。

    ⑹ 定时过期 节点 (TTL Node,3.5.3 版本新增)

    • 默认禁⽤,只能通过系统配置 zookeeper.extendedTypesEnabled=true 开启,不稳定

    2.3 创建结点时的易错点

    ⑴ 无法一次创建多级目录节点

    [zk: localhost:2181(CONNECTED) 0] create /a/b/c
    Node does not exist: /a/b/c
    

    即创建子结点时,父结点必须已经创建好。

    ⑵ 除了创建顺序节点,否则不可以以/作为路径的结尾:

    [zk: localhost:2181(CONNECTED) 8] create /a/
    Path must not end with / character
    

    ⑶ 临时目录节点 不能创建子结点:

    [zk: localhost:2181(CONNECTED) 0] create /ephemeral/child
    Ephemerals cannot have children: /ephemeral/child
    

    ⑷ 目录节点的路径必须以 / 开头:

    [zk: localhost:2181(CONNECTED) 0] create -c container
    Path must start with / character
    

    3. 实战

    3.1 乐观锁

    根据状态数据中的版本号 dataVersion 有并发修改数据实现乐观锁的功能。

    首先,创建一个 /test-node 目录节点:

    [zk: localhost:2181(CONNECTED) 0] create /test-node a
    Created /test-node
    

    然后,用 get -s /test-node 或者 stat /test-node 可以查看状态信息:

    dataVersion 初始值为 0。接着,每次修改 节点数据时,zookeeper 都会递增 dataVersion。

    如果在修改节点数据时指定版本号。那么并发执行时,只有一个请求能修改成功,其他请求都会提示 version No is not valid : /test-node

    4.事件监听机制

    可以带监听参数 -w 的命令有 config [-w], get [-w] path, ls [-w] path, stat [-w] path

    • 针对节点的监听:⼀旦事件触发,对应的注册⽴刻被移除,所以事件监听是⼀次性的

    4.1 监听子目录的变化

    首先,监听子目录的变化,用的是命令 ls [-w] path:

    [zk: localhost:2181(CONNECTED) 0] create /test
    Created /test
    [zk: localhost:2181(CONNECTED) 1] ls -w /test
    []
    [zk: localhost:2181(CONNECTED) 2] create /test/sub1
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/test
    Created /test/sub1
    [zk: localhost:2181(CONNECTED) 3] create /test/sub2
    Created /test/sub2
    
    • ⼀旦事件触发,对应的注册⽴刻被移除,所以事件监听是⼀次性的。所以创建路径为 /test/sub1 的结点时,事件监听被触发,但是创建路径为 /test/sub2 的结点时,就不会再次触发事件监听了;
    [zk: localhost:2181(CONNECTED) 4] ls -w /test
    [sub1, sub2]
    [zk: localhost:2181(CONNECTED) 5] delete /test/sub1
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/test
    
    • 再次注册事件监听,当删除路径为 /test/sub1 的结点时,事件监听又被触发了;
    [zk: localhost:2181(CONNECTED) 0] create /test/abc
    Created /test/abc
    [zk: localhost:2181(CONNECTED) 1] ls -w /test
    [abc, sub2]
    [zk: localhost:2181(CONNECTED) 2] create /test/abc/123
    Created /test/abc/123
    
    • ls -w /test 只能监听 /test 的自身及直接子目录的变化。但是,不能监听子目录的子目录的变化。所以创建目录为 /test/abc/123 的结点不会触发对 /test 子目录的监听事件。

    如果,我们要递归地监听所有的子目录的变化,需要使用 ls -w -R /test 命令:

    [zk: localhost:2181(CONNECTED) 24] create /test
    Created /test
    [zk: localhost:2181(CONNECTED) 25] create /test/abc
    Created /test/abc
    [zk: localhost:2181(CONNECTED) 26] ls -w -R /test
    /test
    /test/abc
    [zk: localhost:2181(CONNECTED) 27] create /test/abc/123
    
    WATCHER::Created /test/abc/123
    
    WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/test/abc
    

    4.2 监听数据的变化

    使用 create path [data] 可以在创建节点时,为节点赋予初始数据。再通过 set path data 来修改路径为 path 的节点的数据。

    [zk: localhost:2181(CONNECTED) 28] create /data a
    Created /data
    [zk: localhost:2181(CONNECTED) 29] get -w /data
    a
    [zk: localhost:2181(CONNECTED) 30] set /data b
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:NodeDataChanged path:/data
    

    我们通过 get -w /data 监听路径为 /data 的节点的数据变化。

    另外,从我目前测试结果来看, stat -w path 也是用来监听数据变化的,不能监听子目录的变化,不能监听ACL权限的变化。

  • 相关阅读:
    写了一个单链表的代码,而且支持反转链表,分组反转链表
    【Redis】redis分布式锁(二)
    【Redis】redis分布式锁(一)
    【Flutter】跟着flutter教程学着写了一个简单的Demo
    【Zookeeper】Zookeeper集群环境搭建
    【TDengine】TDengine初探
    【Shell】一个可以服务拉起、停止和重启的shell脚本
    【Linux】xftp报“找不到匹配的outgoing encryption算法”的错误
    【Linux】Ubuntu如何开启ftp服务器
    【Jenkins】使用Jenkins编译打包后自动部署项目
  • 原文地址:https://www.cnblogs.com/kendoziyu/p/14964122.html
Copyright © 2020-2023  润新知