zoukankan      html  css  js  c++  java
  • 8.4.Zookeeper结构和命令

    1. Zookeeper结构

    1.1.ZooKeeper数据模型Znode

      ZooKeeper拥有一个层次化的目录结构,命名符合常规文件系统规范

      ZooKeeper树中的每个节点被称为—Znode,和文件系统的目录树一样,ZooKeeper树中的每个节点都有一个唯一的路径标识

      节点Znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点)

      客户端应用可以在节点上设置监视器

               

      图中的每个节点称为一个 Znode。 每个 Znode 由 3 部分组成

      ① stat:此为状态信息, 描述该 Znode 的版本, 权限等信息    ② data:与该 Znode 关联的数据    ③ children:该 Znode 下的子节点   

    ZooKeeper节点属性

    通过前面的介绍,我们可以了解到,一个节点自身拥有表示其状态的许多重要属性,如下图所示。

     

    ZooKeeper节点类型

    1、Znode有两种类型:节点的类型在创建时即被确定,并且不能改变。

      临时节点(ephemeral)(断开连接自己删除)该节点的生命周期依赖于创建它们的会话。一旦会话(Session)结束,临时节点将被自动删除,当然可以也

    可以手动删除。虽然每个临时的Znode都会绑定到一个客户端会话,但他们对所有的客户端还是可见的。另外,ZooKeeper的临时节点不允许拥有子节点。

      久节点(persistent)(断开连接不删除)该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除。

    2、Znode 还有一个序列化的特性,如果创建的时候指定的话,该 Znode 的名字后面会自动追加一个不断增加的序列号。序列号对于此节点的父节点来说是唯一

    的,这样便会记录每个子节点创建的先后顺序。它的格式为“%10d”(10 位数字,没有数值的数位用 0 补充,例如“0000000001”)

     

      这样便会存在四种类型的 Znode 节点,分别对应:

      PERSISTENT:永久节点

      EPHEMERAL:临时节点

      PERSISTENT_SEQUENTIAL:永久节点、序列化

      EPHEMERAL_SEQUENTIAL:临时节点、序列化

    2. Zookeeper命令行客户端操作

      启动Zookeeper服务之后,输入以下命令,连接到Zookeeper服务:zkCli.sh -server localhost:2183(连接到自己的zookeeper服务)

                                      zkCli.sh -server shizhan2:2183(连接到其他的zookeeper服务)

      连接成功之后,系统会输出Zookeeper的相关环境及配置信息,并在屏幕输出“welcome to Zookeeper!”等信息。输入help之后,屏幕

    会输出可用的Zookeeper命令,如下图所示

      

      输入connect zhizhan2:2183可以连接到其他zookeeper服务(默认端口是2181,我修改为2183了)

    2.1  使用Zookeeper命令的简单操作步骤

      (1) 使用ls命令查看当前Zookeeper中所包含的内容:ls /

    [zk: localhost:2183(CONNECTED) 1] ls /
    [zookeeper]
    [zk: localhost:2183(CONNECTED) 2] 

      (2) 创建一个新的Znode节点"zk",以及与它关联的字符串,执行命令:create /zk "myData"(默认持久节点)

    [zk: localhost:2183(CONNECTED) 2] create /zk "myData"
    Created /zk

      (3) 再次使用ls命令来查看现在Zookeeper的中所包含的内容:ls /

    [zk: localhost:2183(CONNECTED) 3] ls /
    [zk, zookeeper]

      (4) 使用get命令来确认第二步中所创建的Znode是否包含我们创建的字符串,执行命令:get /zk

    [zk: localhost:2183(CONNECTED) 4] get /zk
    "myData"
    cZxid = 0x100000008
    ctime = Tue Jun 05 19:02:42 CST 2018
    mZxid = 0x100000008
    mtime = Tue Jun 05 19:02:42 CST 2018
    pZxid = 0x100000008
    cversion = 0
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 8
    numChildren = 0

    #监听这个节点的数据变化,当另外一个客户端改变/zk,它会打出下面的

    [zk: localhost:2181(CONNECTED) 4] get /zk watch

    #WATCHER::

    #WatchedEvent state:SyncConnected type:NodeDataChanged path:/zk  

      (5) 接下来通过set命令来对zk所关联的字符串进行设置,执行命令:set /zk "zb"

    [zk: localhost:2183(CONNECTED) 5] set /zk "zb"
    cZxid = 0x500000006
    ctime = Fri Oct 17 03:54:20 PDT 2014
    mZxid = 0x500000007
    mtime = Fri Oct 17 03:55:50 PDT 2014
    pZxid = 0x500000006
    cversion = 0
    dataVersion = 1
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 9
    numChildren = 0

      (7) 下面我们将刚才创建的Znode删除,执行命令:delete /zk

    [zk: localhost:2183(CONNECTED) 7] delete /zk

      (8)删除节点:rmr(删除下面的所有子节点,递归删除),执行命令:rmr /zk

    [zk: localhost:2183(CONNECTED) 7] rmr /zk

    2.2 Zookeeper的API的简单使用  

      Zookeeper API共包含五个包,分别为:  

    (1)org.apache.zookeeper
    (2)org.apache.zookeeper.data
    (3)org.apache.zookeeper.server
    (4)org.apache.zookeeper.server.quorum
    (5)org.apache.zookeeper.server.upgrade

      1.org.apache.zookeeper.Zookeeper 是客户端入口主类,负责建立zookeeper 集群的会话,并提供方法进行操作。

      如果要使用Zookeeper服务,应用程序首先必须创建一个Zookeeper实例,这时就需要使用此类。一旦客户端和Zookeeper服务建立起了连接,

    Zookeeper系统将会给次连接会话分配一个ID值,并且客户端将会周期性的向服务器端发送心跳来维持会话连接。只要连接有效,客户端就可以使

    用Zookeeper API来做相应处理了

      Zookeeper类提供了如下图所示的几类主要方法:

    功能

    描述

    create

    在本地目录树中创建一个节点

    delete

    删除一个节点

    exists

    测试本地是否存在目标节点

    get/set data

    从目标节点上读取 / 写数据

    get/set ACL

    获取 / 设置目标节点访问控制列表信息

    get children

    检索一个子节点上的列表

    sync

    等待要被传送的数据

      2.org.apache.zookeeper.Watcher

      Watcher 接口表示一个标准的事件处理器,其定义了事件通知相关的逻辑,包含 KeeperState 和 EventType 两个枚举类,分别代表了通知状态和事件类型,

    同时定义了事件的回调方法:process(WatchedEvent event)

      process 方法是 Watcher 接口中的一个回调方法,当 ZooKeeper 向客户端发送一个 Watcher 事件通知时,客户端就会对相应的 process 方法进行回调,

    从而实现对事件的处理。 

    if (event.getState() == KeeperState.SyncConnected) {
          latch.countDown();
    }
    
     // 发生了waitPath的删除事件
    if (event.getType() == EventType.NodeDeleted && event.getPath().equals(waitPath)) {
          doSomething();
    }

    2.3 Zookeeper JAVA API的使用(Demo增删改查程序)

    import java.io.IOException;
    import java.util.List;
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooDefs.Ids;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.data.Stat;
    
    public class SimpleZkClient {
         static ZooKeeper zkClient = null;
        
        // 会话超时时间,设置为与系统默认时间一致
        private static final int sessionTimeout = 30000;
        private static final String connectString = "shizhan2:2183,shizhan3:2183,shizhan5:2183";
        
        public static void main(String[] args) throws Exception {
            try {
                zkClient  = new ZooKeeper(connectString, sessionTimeout, new Watcher(){
                    @Override
                    // 收到事件通知后的回调函数(应该是我们自己的事件处理逻辑),这是一次性通知
                    public void process(WatchedEvent event) {
                 //事件类型:event.getType() 事件发生的路径:event.getPath() 通知状态:event.getState() System.out.println(event.getType()
    +"-----------"+event.getPath()); try { //循环监听,对节点进行监听true zkClient.getChildren("/", true); } catch (Exception e) { } } }); } catch (IOException e) { e.printStackTrace(); } //创建节点到zk中 参数1:要创建的节点的路径 参数2:节点数据 参数3:节点的权限 参数4:节点的类型 //上传的数据可以是任何类型,但都要转成byte[] System.out.println("=========创建节点==========="); zkClient.create("/eclipse7", "hellozk111".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); //获取znode的数据 byte[] data = zkClient.getData("/eclipse7", false, null); System.out.println("=========查看创建的节点==========="+new String(data)); //判断znode是否存在 Stat stat = zkClient.exists("/eclipse4", false); System.out.println("=========判断节点是否存在==========="+ stat==null?"not exist":"exist"); //获取子节点 List<String> children = zkClient.getChildren("/", true); for (String child : children) { System.out.println(child); } Thread.sleep(Long.MAX_VALUE); //删除znode //参数2:指定要删除的版本,-1表示删除所有版本 zkClient.delete("/eclipse2", -1); zkClient.setData("/app1", "imissyou angelababy".getBytes(), -1); byte[] da = zkClient.getData("/app1", false, null); System.out.println(new String(data)); } }

      

      

                              

      

      

      

      

      

     

  • 相关阅读:
    exec系列函数和system函数
    fork函数相关总结
    文件的内核结构file和dup实现重定向
    进程基本概述
    fcntl 函数与文件锁
    文件的属性
    目录的操作
    文件的读取写入
    文件的打开关闭
    浅谈原始套接字 SOCK_RAW 的内幕及其应用(port scan, packet sniffer, syn flood, icmp flood)
  • 原文地址:https://www.cnblogs.com/yaboya/p/9139003.html
Copyright © 2011-2022 走看看