一、基本依赖

Curator是Netflix公司开源的一个Zookeeper客户端,目前由Apache进行维护。与Zookeeper原生客户端相比,Curator的抽象层次更高,功能也更加丰富,是目前Zookeeper使用范围最广的Java客户端。本篇文章主要讲解其基本使用,项目采用Maven构建,以单元测试的方法进行讲解,相关依赖如下:

<dependencies>
    <!--Curator相关依赖-->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>4.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>4.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.13</version>
    </dependency>
    <!--单元测试相关依赖-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

完整源码见本仓库: https://github.com/heibaiying/BigData-Notes/tree/master/code/Zookeeper/curator

二、客户端相关操作

2.1 创建客户端实例

这里使用@Before在单元测试执行前创建客户端实例,并使用@After在单元测试后关闭客户端连接。

public class BasicOperation {

    private CuratorFramework client = null;
    private static final String zkServerPath = "192.168.0.226:2181";
    private static final String nodePath = "/hadoop/yarn";

    @Before
    public void prepare() {
        // 重试策略
        RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
        client = CuratorFrameworkFactory.builder()
        .connectString(zkServerPath)
        .sessionTimeoutMs(10000).retryPolicy(retryPolicy)
        .namespace("workspace").build();  //指定命名空间后,client的所有路径操作都会以/workspace开头
        client.start();
    }

    @After
    public void destroy() {
        if (client != null) {
            client.close();
        }
    }
}

2.2 重试策略

在连接Zookeeper时,Curator提供了多种重试策略以满足各种需求,所有重试策略均继承自RetryPolicy接口,如下图:

这些重试策略类主要分为以下两类:

  • RetryForever :代表一直重试,直到连接成功;
  • SleepingRetry : 基于一定间隔时间的重试。这里以其子类ExponentialBackoffRetry为例说明,其构造器如下:
/**
 * @param baseSleepTimeMs 重试之间等待的初始时间
 * @param maxRetries 最大重试次数
 * @param maxSleepMs 每次重试间隔的最长睡眠时间(毫秒)
 */
ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs)

2.3 判断服务状态

@Test
public void getStatus() {
    CuratorFrameworkState state = client.getState();
    System.out.println("服务是否已经启动:" + (state == CuratorFrameworkState.STARTED));
}

三、节点增删改查

3.1 创建节点

@Test
public void createNodes() throws Exception {
    byte[] data = "abc".getBytes();
    client.create().creatingParentsIfNeeded()
            .withMode(CreateMode.PERSISTENT)      //节点类型
            .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
            .forPath(nodePath, data);
}

创建时可以指定节点类型,这里的节点类型和Zookeeper原生的一致,全部类型定义在枚举类CreateMode中:

public enum CreateMode {
    // 永久节点
    PERSISTENT (0, false, false),
    //永久有序节点
    PERSISTENT_SEQUENTIAL (2, false, true),
    // 临时节点
    EPHEMERAL (1, true, false),
    // 临时有序节点
    EPHEMERAL_SEQUENTIAL (3, true, true);
    ....
}

2.2 获取节点信息

@Test
public void getNode() throws Exception {
    Stat stat = new Stat();
    byte[] data = client.getData().storingStatIn(stat).forPath(nodePath);
    System.out.println("节点数据:" + new String(data));
    System.out.println("节点信息:" + stat.toString());
}

如上所示,节点信息被封装在Stat类中,其主要属性如下:

public class Stat implements Record {
    private long czxid;
    private long mzxid;
    private long ctime;
    private long mtime;
    private int version;
    private int cversion;
    private int aversion;
    private long ephemeralOwner;
    private int dataLength;
    private int numChildren;
    private long pzxid;
    ...
}

每个属性的含义如下:

状态属性 说明
czxid 数据节点创建时的事务ID
ctime 数据节点创建时的时间
mzxid 数据节点最后一次更新时的事务ID
mtime 数据节点最后一次更新时的时间
pzxid 数据节点的子节点最后一次被修改时的事务ID
cversion 子节点的更改次数
version 节点数据的更改次数
aversion 节点的ACL的更改次数
ephemeralOwner 如果节点是临时节点,则表示创建该节点的会话的SessionID;如果节点是持久节点,则该属性值为0
dataLength 数据内容的长度
numChildren 数据节点当前的子节点个数

2.3 获取子节点列表

@Test
public void getChildrenNodes() throws Exception {
    List<String> childNodes = client.getChildren().forPath("/hadoop");
    for (String s : childNodes) {
        System.out.println(s);
    }
}

2.4 更新节点

更新时可以传入版本号也可以不传入,如果传入则类似于乐观锁机制,只有在版本号正确的时候才会被更新。

@Test
public void updateNode() throws Exception {
    byte[] newData = "defg".getBytes();
    client.setData().withVersion(0)     // 传入版本号,如果版本号错误则拒绝更新操作,并抛出BadVersion异常
            .forPath(nodePath, newData);
}

2.5 删除节点

@Test
public void deleteNodes() throws Exception {
    client.delete()
            .guaranteed()                // 如果删除失败,那么在会继续执行,直到成功
            .deletingChildrenIfNeeded()  // 如果有子节点,则递归删除
            .withVersion(0)              // 传入版本号,如果版本号错误则拒绝删除操作,并抛出BadVersion异常
            .forPath(nodePath);
}

2.6 判断节点是否存在

@Test
public void existNode() throws Exception {
    // 如果节点存在则返回其状态信息如果不存在则为null
    Stat stat = client.checkExists().forPath(nodePath + "aa/bb/cc");
    System.out.println("节点是否存在:" + !(stat == null));
}

三、监听事件

3.1 创建一次性监听

和Zookeeper原生监听一样,使用usingWatcher注册的监听是一次性的,即监听只会触发一次,触发后就销毁。示例如下:

@Test
public void DisposableWatch() throws Exception {
    client.getData().usingWatcher(new CuratorWatcher() {
        public void process(WatchedEvent event) {
            System.out.println("节点" + event.getPath() + "发生了事件:" + event.getType());
        }
    }).forPath(nodePath);
    Thread.sleep(1000 * 1000);  //休眠以观察测试效果
}

3.2 创建永久监听

Curator还提供了创建永久监听的API,其使用方式如下:

@Test
public void permanentWatch() throws Exception {
    // 使用NodeCache包装节点,对其注册的监听作用于节点,且是永久性的
    NodeCache nodeCache = new NodeCache(client, nodePath);
    // 通常设置为true, 代表创建nodeCache时,就去获取对应节点的值并缓存
    nodeCache.start(true);
    nodeCache.getListenable().addListener(new NodeCacheListener() {
        public void nodeChanged() {
            ChildData currentData = nodeCache.getCurrentData();
            if (currentData != null) {
                System.out.println("节点路径:" + currentData.getPath() +
                        "数据:" + new String(currentData.getData()));
            }
        }
    });
    Thread.sleep(1000 * 1000);  //休眠以观察测试效果
}

3.3 监听子节点

这里以监听/hadoop下所有子节点为例,实现方式如下:

@Test
public void permanentChildrenNodesWatch() throws Exception {

    // 第三个参数代表除了节点状态外,是否还缓存节点内容
    PathChildrenCache childrenCache = new PathChildrenCache(client, "/hadoop", true);
    /*
         * StartMode代表初始化方式:
         *    NORMAL: 异步初始化
         *    BUILD_INITIAL_CACHE: 同步初始化
         *    POST_INITIALIZED_EVENT: 异步并通知,初始化之后会触发INITIALIZED事件
         */
    childrenCache.start(StartMode.POST_INITIALIZED_EVENT);

    List<ChildData> childDataList = childrenCache.getCurrentData();
    System.out.println("当前数据节点的子节点列表:");
    childDataList.forEach(x -> System.out.println(x.getPath()));

    childrenCache.getListenable().addListener(new PathChildrenCacheListener() {
        public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) {
            switch (event.getType()) {
                case INITIALIZED:
                System.out.println("childrenCache初始化完成");
                break;
                case CHILD_ADDED:
                // 需要注意的是: 即使是之前已经存在的子节点,也会触发该监听,因为会把该子节点加入childrenCache缓存中
                System.out.println("增加子节点:" + event.getData().getPath());
                break;
                case CHILD_REMOVED:
                System.out.println("删除子节点:" + event.getData().getPath());
                break;
                case CHILD_UPDATED:
                System.out.println("被修改的子节点的路径:" + event.getData().getPath());
                System.out.println("修改后的数据:" + new String(event.getData().getData()));
                break;
            }
        }
    });
    Thread.sleep(1000 * 1000); //休眠以观察测试效果
}

更多大数据系列文章可以参见个人 GitHub 开源项目: 程序员大数据入门指南

ZooKeeper学习之路(四)—— Java 客户端 Apache Curator的更多相关文章

  1. ZooKeeper系列(四)—— Java 客户端 Apache Curator

    一.基本依赖 Curator 是 Netflix 公司开源的一个 Zookeeper 客户端,目前由 Apache 进行维护.与 Zookeeper 原生客户端相比,Curator 的抽象层次更高,功 ...

  2. Zookeeper学习之路 (一)初识

    本文引用自 http://www.cnblogs.com/sunddenly/p/4033574.html 引言 Hadoop 集群当中 N 多的配置信息如何做到全局一致并且单点修改迅速响应到整个集群 ...

  3. Zookeeper的核心概念以及java客户端使用

    一.Zookeeper的核心概念 分布式配置中心(存储):disconf(zk).diamond(mysql+http) 1)znode ZooKeeper操作和维护的是一个个数据节点,称为 znod ...

  4. ZooKeeper学习之路(五)—— ACL权限控制

    一.前言 为了避免存储在Zookeeper上的数据被其他程序或者人为误修改,Zookeeper提供了ACL(Access Control Lists)进行权限控制.只有拥有对应权限的用户才可以对节点进 ...

  5. Zookeeper客户端Apache Curator

    本文不对Zookeeper进行介绍,主要介绍Curator怎么操作Zookeeper. Apache Curator是Apache ZooKeeper的Java / JVM客户端库,Apache Zo ...

  6. Redis——学习之路四(初识主从配置)

    首先我们配置一台master服务器,两台slave服务器.master服务器配置就是默认配置 端口为6379,添加就一个密码CeshiPassword,然后启动master服务器. 两台slave服务 ...

  7. memcached学习——常用命令+基于java客户端的3种简单实现(二)

    常用命令: memcached设计的原则就是简单,所以支持的命令也不是特别多~ 1.查看memcached的状态,主要用于分析内存的使用状况.优化内存分配等 stats 查看memcached的运行状 ...

  8. ZooKeeper学习笔记(四)——shell客户端命令操作

    ZooKeeper客户端命令行操作 启动服务端 [simon@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh start 查看状态信息 Using confi ...

  9. [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

随机推荐

  1. DDD实战4 实现产品仓储

    a.要实现仓储,首先要定义仓储接口.在领域层定义仓储接口,IProductRepository.cs. public interface IProductRepository { void Creat ...

  2. WPF中使用AxisAngleRotation3D实现CAD的2D旋转功能

    原文:WPF中使用AxisAngleRotation3D实现CAD的2D旋转功能       对于CAD图形来说,3D旋转比较常用,具体实现方法在上篇文章<WPF中3D旋转的实现 >中做了 ...

  3. linux_crontab_定时删除

    #每天2:30 删除4天前qac的原始log30 2 * * * find /home/iknow/ETL/RetlPull/retl-pull/data/qac -name qac.log.new. ...

  4. Linux 系统安装(5分钟)

    安装版本:CentOS 6.5 minimal 虚拟机工具:VMware 虚拟机配置:1核2线程 2G内存 50G硬盘 步骤: 一.虚拟机配置 1.打开VMware,创建新的虚拟机,选择典型安装: 2 ...

  5. HTTP协议知识点 (11个知识点,比较详细)

    (一)   对象更新校验方式: HTTP通过两种方式验证对象是否有更新if-non-match 或者 if-modified-since. 通过在Request中包含上述header向服务器发起询问. ...

  6. 自定义 DependencyProperty 与 RoutedEvent

    原文:自定义 DependencyProperty 与 RoutedEvent //自定义依赖属性 class MyBook : DependencyObject//依赖属性必须派生自Dependen ...

  7. OC笔记一:Objective

    1.OC简介 全称:Objective-C,是扩充C的面向对象编程语言,主要用于iOS和Mac OS开发. C语言的基础上,增加了一层最小的面向对象语法 完全兼容C语言 可以在OC代码中混入C语言代码 ...

  8. LINQ查询表达式---------from子句

    LINQ查询表达式---------from子句 LINQ的查询由3基本部分组成:获取数据源,创建查询,执行查询. //1.获取数据源 List<, , , , , }; //创建查询 var ...

  9. ML:吴恩达 机器学习 课程笔记(Week9~10)

    Anomaly Detection Recommender Systems Large Scale Machine Learning

  10. uwp汉堡菜单的实现

    ---恢复内容开始--- 现在uwp上面的汉堡菜单(就是那个三道杠,点击之后会出现菜单)使用的越来越普遍,比如微软自己家的Cortana.现在我使用的实现方法是使用SplitView实现.首先Spli ...