zoukankan      html  css  js  c++  java
  • zookeeper 知识点汇总

    Zookeeper 是什么

    zookeeper 是软件世界里的管理者,被用来 提供分布式环境的协调服务。zookeeper 是 yahoo 公司使用 java 语言开发的,是 Hadoop 项目中的子项目,基于 Google 的 Chubby 的开源实现,在 Hadoop,Hbase,Kafka 等技术中充当核心组件的角色。

    它的设计目标就是 将那些复杂并且容易出错的分布式一致性服务加以封装,构成高效且可靠的服务,并为用户提供一系列简单易用的接口

    Zookeeper 是一个经典的 分布式数据一致性 解决方案,分布式应用程序可以基于它实现

    • 数据的发布和订阅
    • 负载均衡
    • 命名服务
    • 分布式协调与通知
    • 集群管理
    • 领导选举
    • 分布式锁
    • 分布式队列

    zookeeper 一般都以 集群的方式 对外提供服务,一个集群包含多个节点,每个节点都对应一台 Zookeeper 服务器,所有的节点共同对外提供服务。具体包括以下五大特性:

    1. 顺序性
    2. 原子性
    3. 一致性
    4. 可靠性
    5. 实时性

    Zookeeper 树状模型

    Zookeeper 内部拥有树状的内存模型,与文件系统非常类似。

    • 在 Zookeeper 中将这些目录与文件统称为 ZNode
    • 每个 ZNode 都有对应的路径及其包含的数据
    • ZNode 可由 Zookeeper 客户端来创建
    • 当客户端与服务端建立连接后,服务端将为客户端创建一个 Session (会话),客户端对 ZNode 的所有操作均在这个会话中来完成

    树状模型图如下所示

    ZNode 包含 4 类节点

    • persistent 持久节点
    • persistent sequential 持久性顺序节点
    • ephemeral 临时性节点
    • ephemeral sequential 临时性顺序节点

    Zookeeper 集群结构

    Zookeeper 设计了一个轻量级的协议 Zab (ZooKeeper Atomic Broadcast, Zookeeper 广播协议)。Zab 协议分为两个阶段:

    • Leader Election 领导选举

      Zookeeper 集群启动时,会选出一台节点为 Leader,而其他节点均为 Follower。当 Leader 出现故障时,会自动选举出新的 Leader 节点,并让所有节点恢复到一个正常的状态。选举结束后,会进入 原子广播阶段。

    • Atomic Broadcase 原子广播

      该阶段会同步 Leader 节点与 Follower 节点之间的数据,确保 Leader 与 Follower 节点具有相同的状态。所有的写操作都会发送到 Leader 节点,并通过广播的方式同步到 Follower 节点。

    一个 Zookeeper 集群通常由一组节点组成,一般情况下 3 ~ 5 个就可以组成可用的 Zookeeper 集群。

    每个节点都会在内存中维护当前的服务器状态,并在每个节点之间都会保持通信,目的就是告诉其他节点“自己还活着”。我们一般会提供奇数个节点比较节省资源。此外, Zookeeper 客户端可以选择集群中任意一个节点来建立连接,而一旦客户端与某个节点之间断开联系,客户端会自动连接到集群的其他节点。

    如何使用 ZooKeeper

    zookeeper 官方地址:http://zookeeper.apache.org/

    zookeeper 使用 java 语言开发,使用前需要先安装 jdk。下文是在 linux 环境下运行 zookeeper 的指导。

    运行 Zookeeper

    步骤1 修改 ZooKeeper 配置文件

    Zookeeper 默认提供了一份名为 zoo_sample.cfg 的示例配置文件,需要复制一下,并将其重命名为 zoo.cfg 。配置文件的重要配置项如下

    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/tmp/zookeeper
    clientPort=2181
    

    详细解释下以上配置项

    • tickTime 滴答时间,用于配置 Zookeeper 中最小时间单元的长度。单位为 ms。默认值是 3000 ms。
    • initLimit 用于配置 Leader 节点等待 Follower 节点启动并完成数据同步的时间, 默认值是 10 ,也就是 10 * tickTime
    • syncLimit 用来配置 Leader 节点与 Follower 节点之间心跳检测的最大延时时间,默认值是 5,也就是 5 * tickTime
    • dataDir 用来配置 Zookeeper 服务器存储快照文件的目录,不建议将其指定到 /tmp 目录下,因为该目录下的所有文件可能被自动删除。在 Zookeeper 环境中,将生成一个名为 myid 的文件,用来存放 zk 集群节点的 ID。
    • clientPort 用于配置当前 zk 服务器对外暴露的接口

    步骤 2, 启动 Zookeeper 服务器

    启动 Zookeeper 服务器非常简单,只需执行 Zookeeper 提供的脚本程序即可。

     bin/zkServer.sh start
    

    执行上面脚本,默认会在后台启动 Zookeeper 服务器。

    zkServer.sh 可以传入以下参数

    • start
    • start-foreground
    • stop
    • restart
    • status
    • upgrade
    • print-cmd

    步骤 3, 验证 Zookeeper 服务是否有效

    bin/zkServer.sh status
    

    还可以使用 telnet 命令来验证 ZooKeeper 服务是否有效

    telnet 127.0.0.1 2181
    

    zookeeper 当前处于 standard alone 模式下,一般情况下我们使用单机模式作为开发环境,而使用集群模式作为生产环境。

    搭建 Zookeeper 集群环境

    在本地搭建一个伪集群模式的 Zookeeper 集群环境(3 个节点)

    修改 Zookeeper 配置文件

    配置如下

    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/usr/local/app-data/zookeeper/data
    dataLogDir=/usr/local/zookeeper-3.4.6/logs
    clientPort=2181
    server.0=127.0.0.1:2888:3888
    server.1=127.0.0.1:2889:3889
    server.2=127.0.0.1:2890:3890
    

    与单机模式的区别就在于添加了一组 server 配置,表示集群中包含的三个节点,需要注意的是 server 配置需要满足一定的格式:

    server.<id>=<ip>:<port1>:<port2>
    
    • id 表示节点编号,表示该节点在集群中的唯一编号,取值在 0 ~ 255 之间。
      • 必须在 dataDir 目录下创建一个名为 myid 的文件,其内容是该节点的编号
    • ip 表示节点所在的 IP 地址,本机为 127.0.0.1 或者是 localhost
    • port1 表示 Leader 节点与 Follower 节点心跳检测与数据同步时使用的接口
    • port2 表示在领导选举过程中,用于投票通信的端口

    启动 ZooKeeper 集群

    与单机模式的启动方法相同,只需一次启动所有的 ZooKeeper 节点即可启动整个集群

    验证 Zookeeper 集群环境是否有效

    和 standard alone 模式一样,也可以通过 zkServer.sh 脚本与 telnet 命令来查看每个节点的状态,此时会看到 Mode:leader 或者 Mode:follower 的信息,表示该节点是 Leader 还是 Follower。

    ZooKeeper 提供了一系列脚本程序,全部存放在 bin 目录下,如

    • zkServer.sh 用于启动 Zookeeper 服务器
    • zkCli.sh 用于连接 ZooKeeper 服务器的命令行客户端
    • zkCleanup.sh 用于清理 ZooKeeper 的历史数据,包括
      • 事务日志文件
      • 快照数据文件
    • zkEnv.sh 用于设置 ZooKeeper 的环境变量

    连接 zookeeper

    使用 zkCli 连接 Zookeeper

    连接 ZooKeeper 只需要执行以下脚本:

    bin/zkCli.sh
    

    如果想要连接远程的 ZooKeeper, 则在 zkCli.sh 脚本中添加 -server 选项

    bin/zkCli.sh -server <ip>:<port>
    

    连接成功后,就可以输入相关的命令来操作 zookeeper 了。当输入 help 命令后,将输出 zookeeper 相关客户端命令的使用帮助。

    ZooKeeper -server host:port cmd args
            stat path [watch]
            set path data [version]
            ls path [watch]
            delquota [-n|-b] path
            ls2 path [watch]
            setAcl path acl
            setquota -n|-b val path
            history
            redo cmdno
            printwatches on|off
            delete path [version]
            sync path
            listquota path
            rmr path
            get path [watch]
            create [-s] [-e] path data acl
            addauth scheme auth
            quit
            getAcl path
            close
            connect host:port
    

    列出子节点

    命令格式如下

    ls path [watch]
    

    ls 命令中可设置一个 watch 参数,用于指定客户端监视器,在 zooKeeper 中被称为 Watcher, Watcher 用于监控节点的状态变化,默认情况下可不带有任何 Watcher。

    [zk: localhost:2181(CONNECTED) 0] ls /
    [zookeeper]
    

    默认情况下,根目录中有一个名为 zookeeper 的子节点,它作为 Zookeeper 的保留节点,我们一般不使用它。

    此外,还可以使用 ls2 命令以更加详细的方式列出节点名称及其相关属性,命令格式如下

    ls2 path [watch]
    

    ls2 命令会输出当前节点的基本信息

    [zk: localhost:2181(CONNECTED) 2] ls2 /
    [zookeeper]
    cZxid = 0x0
    ctime = Thu Jan 01 08:00:00 CST 1970
    mZxid = 0x0
    mtime = Thu Jan 01 08:00:00 CST 1970
    pZxid = 0x0
    cversion = -1
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 0
    numChildren = 1
    

    在输出信息中包含了大量的统计属性:

    • cZxid 表示创建节点时的事务 ID (每个客户端请求都会形成一个事务)
    • ctime 表示创建节点的时间
    • mZxid 表示最后一次修改节点时的事务 ID
    • mtime 表示最后一次修改节点的时间
    • pZxid 表示最后一次修改父节点时的事务 ID
    • cversion 子节点的版本号
    • dataVersion 节点包含数据的版本号
    • aclVersion 表示节点的 ACL 权限版本号
    • ephemeralOwner 临时节点的会话 ID
    • dataLength 表示节点包含数据内容的长度
    • numChildren 当前节点的子节点数

    判断节点是否存在

    [zk: localhost:2181(CONNECTED) 8] stat /foo
    Node does not exist: /foo
    

    创建节点

    使用 create 命令创建节点,命令格式如下

     create [-s] [-e] path data acl
    

    其中

    • -s 用于指定该节点是否为顺序节点,即 Sequential 节点

    • -e 选项:用于指定该节点是否为临时节点,即 Ephemeral 节点

    • acl 用于权限控制, Zookeeper 内部提供了一个强大的 ACL 访问控制列表,默认情况下不做任何权限控制

      [zk: localhost:2181(CONNECTED) 13] create -e /foo hello
      Created /foo
      

    获取节点数据

    使用 get 命令获取节点数据,命令格式如下

    get path [watch]
    

    可以通过以下命令获取 /foo 节点包含的数据

    [zk: localhost:2181(CONNECTED) 14] get /foo
    hello
    cZxid = 0xa
    ctime = Wed Jan 02 15:27:44 CST 2019
    mZxid = 0xa
    mtime = Wed Jan 02 15:27:44 CST 2019
    pZxid = 0xa
    cversion = 0
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x1680d4a324f0002
    dataLength = 5
    numChildren = 0
    

    更新节点数据

    使用 set 命令更新节点数据,命令格式如下

    set path data [version]
    

    在更新节点数据时,可指定 version 参数,表示节点包含数据的版本号。如果不指定 version 参数,则表示更新节点数据的最新版本。

    删除节点

    使用 delete 命令删除节点,命令格式如下

    delete path [version]
    

    当节点没有任何子节点时,才能删除成功,否则将给出 "node not empty" 的提示,但可以通过以下命令一次删除该节点及其所有的子节点。

    rmr path
    

    使用 Node.js Client 连接 Zookeeper

    Node.js 连接 Zookeeper 中比较好用的客户端是 node-zookeeper-client

    首先通过 NPM 来安装这个模块。

    npm install node-zookeeper-client
    

    先用一段代码来展示连接 Zookeeper, 后面再基于该代码,将 nodejs 针对 zookeeper 客户端的操作执行一遍。

    var zookeeper = require('node-zookeeper-client')
    
    var CONNECTION_STRING = 'localhost:2181'
    
    var OPTIONS = {
      sessionTimeout: 5000
    }
    
    var zk = zookeeper.createClient(CONNECTION_STRING, OPTIONS)
    
    zk.on('connected', function() {
      console.log(zk);
      zk.close();
    });
    
    zk.connect();
    

    如果 zk 可以正常输出,说明可成功连接 Zookeeper 服务器并建立了正常的会话, 下面所有的操作都在该会话中进行。Node.js 客户端仅提供了异步方式,我们不能通过同步方式来调用。

    node-zookeeper-client 的官方文档地址为: https://www.npmjs.com/package/node-zookeeper-client

    可执行的常见操作包括:

    • 列出子节点
    • 判断节点是否存在
    • 创建节点
    • 获取节点数据
    • 更新节点数据
    • 删除节点

    参考

    • 《架构探险—轻量级微服务架构》
  • 相关阅读:
    as
    留言板
    HEOI2020游记
    min_25筛学习笔记
    计算几何初步
    「狗屁不会」exlucas
    GCD of Sequence
    做题记录
    一些奇怪的坑+好东西
    关于我
  • 原文地址:https://www.cnblogs.com/reycg-blog/p/10208585.html
Copyright © 2011-2022 走看看