专栏首页shysh95Zookeeper Java API

Zookeeper Java API

本文主要讲解使用Java API来和Zookeeper集群进行交互,大家在看完这篇文章以后一定要亲自动手去敲代码(纸上得来终觉浅,绝知此事要躬行)。下面介绍的API依赖的maven版本为:

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.14</version>
</dependency>

创建会话

客户端和Zookeeper创建会话的过程是一个异步的过程,构造方法在调用完成后立马返回Zookeeper,但此时绝大多数情况都还没有和服务端正式建立连接,处于CONNECTING的阶段。当连接建立完成后,将会向客户端发送一个事件通知告诉客户端连接建立完成。

public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, 
        long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)
  • connectString:指定Zookeeper的服务器列表,多个服务器之间使用英文逗号分割,每个服务器节点的格式为host:port
  • sessionTimeout:会话超时时间,单位为ms。在设置的sessionTimeout时间内如果没有进行有效的心跳检测,会话将会失效
  • watcher:设置默认的Watcher事件通知处理器,可以为null
  • canBeReadOnly:标识当前会话是否支持只读模式。在Zookeeper集群中,如果一台机器和超过一半的机器失去网络连接,将不再提供读写服务。设置该参数为true,可以让这台服务器继续为客户端提供读请求。
  • sessionId和sessionPasswd:会话id和会话秘钥,两个参数共同确定一个会话,客户端可以使用这两个参数实现客户端会话复用。这两个值可以在第一次连接上服务器之后通过调用ZooKeeper实例的getSessionId()和getSessionPasswd()获取。

创建节点

/**
* 同步方式创建节点
*/
public String create(final String path, byte data[], List<ACL> acl,
            CreateMode createMode)
/**
* 异步方式创建节点
*/
public void create(final String path, byte data[], List<ACL> acl,
            CreateMode createMode,  StringCallback cb, Object ctx)
  • path:节点路径
  • data:节点存储的数据
  • acl:节点的Acl策略,如果没有策略要求,可以将该参数设置为ZooDefs.Ids.OPEN_ACL_UNSAFE
  • cb:注册一个回调函数。当服务端创建节点完成后,Zookeeper将会自动调用这个方法
  • ctx:用于传递一个对象,可以在回调方法执行的时候使用,通常是放一个上下文信息

讲个注意点:临时节点不允许有子节点。

下面看一下StringCallback的回调方法processResult:

public void processResult(int rc, String path, Object ctx, String name);
  • rc:响应码
  • path:接口调用时传入的节点路径参数
  • ctx:接口调用时传入的ctx参数
  • name:实际创建的节点的名称

删除节点

/**
* 同步删除节点
*/
public void delete(final String path, int version)
        throws InterruptedException, KeeperException

/**
* 异步删除节点
*/
public void delete(final String path, int version, VoidCallback cb,
            Object ctx)

参数的意义就不重复描述了,和创建节点的参数基本一致

读取子节点列表

public List<String> getChildren(final String path, Watcher watcher)
        throws KeeperException, InterruptedException

public List<String> getChildren(String path, boolean watch)
            throws KeeperException, InterruptedException

public void getChildren(final String path, Watcher watcher,
            ChildrenCallback cb, Object ctx)  

public void getChildren(String path, boolean watch, ChildrenCallback cb,
            Object ctx)

public List<String> getChildren(final String path, Watcher watcher,
            Stat stat)

public List<String> getChildren(String path, boolean watch, Stat stat)
            throws KeeperException, InterruptedException

public void getChildren(final String path, Watcher watcher,
            Children2Callback cb, Object ctx)

public void getChildren(String path, boolean watch, Children2Callback cb,
            Object ctx)
  • String path:指定数据节点的路径,获取该节点的所有子节点列表
  • Watcher watcher:注册的Watcher。一旦在此次获取子节点以后,如果子节点列表发生变更,该Watcher将会收到通知
  • boolean watch:表明是否需要注册一个Watcher,如果为true,则使用默认的watcher(在客户端创建会话的时候传入的Watcher),false则不使用watcher
  • ChildrenCallback cb:注册一个异步回调函数
  • Stat stat:传入一个旧的Stat信息,将会被替换为最新的Stat信息
  • Object ctx:用于传递的上下文对象

这里讲几个注意点:

  1. Watcher的注册只有一次有效果,也就是说Watcher在收到一次通知后将会失效,如果要保证Watcher一直有效,那么需要反复注册
  2. 假设子节点变更,Watcher必须要重新查询列表才能获取更新后的子节点列表

读取数据

public byte[] getData(final String path, Watcher watcher, Stat stat)
        throws KeeperException, InterruptedException

public byte[] getData(String path, boolean watch, Stat stat)
            throws KeeperException, InterruptedException

public void getData(final String path, Watcher watcher,
            DataCallback cb, Object ctx)


public void getData(String path, boolean watch, DataCallback cb, Object ctx)
  • String path:指定数据节点的路径,获取该节点存储的数据内容
  • boolean watch:表明是否需要注册一个Watcher,如果为true,则使用默认的Watcher(在客户端创建会话的时候传入的Watcher),false则不需要注册Watcher
  • DataCallback cb:注册一个异步回调函数
  • Watcher watcher:注册的Watcher。一旦在此次获取节点内容以后,如果节点内容发生变更,该Watcher将会受到通知
  • Stat stat:传入一个旧的Stat信息,将会被替换为最新的Stat信息
  • Object ctx:用于传递的上下文对象

这边讲一个注意点:即使节点的数据没有发生变化,但是如果dataVersion发生了变化,Watcher也会收到通知。

更新数据

public Stat setData(final String path, byte data[], int version)

public void setData(final String path, byte data[], int version,
            StatCallback cb, Object ctx)
  • String path:指定数据节点的路径,设置该节点的内容
  • byte data[]:节点新的数据内容
  • int version:数据版本,基于这个版本进行数据更新
  • StatCallback cb:注册一个异步回调函数
  • Object ctx:用于传递上下文的对象

下面我们看一下version这个参数,首先Zookeeper并不会存储多个版本的数据,那么这个version到底有什么用?

这个version和JAVA中的CAS理论相似(这里我默认大家都知道什么是CAS),假设一个客户端A基于上次获取的version对数据进行变更,如果在变更过程中有其他客户端对节点数据进行了变更,那么version和客户端A携带的version将会不一致更新失败。通过这一机制,我们很容易的解决了分布式高并发的更新问题。

version的值也可以为-1,虽然这是一个看似不合法的值,但-1是为了告诉Zookeeper服务器客户端需要基于对数据的最新版本进行更新。如果对Zookeeper节点的更新没有原子性要求,可以使用-1。

节点是否存在

public Stat exists(final String path, Watcher watcher)
        throws KeeperException, InterruptedException

public Stat exists(String path, boolean watch) throws KeeperException,
        InterruptedException

public void exists(final String path, Watcher watcher,
            StatCallback cb, Object ctx)

public void exists(String path, boolean watch, StatCallback cb, Object ctx)
  • String path:指定数据节点的路径,返回节点的属性信息,如果不存在则返回null
  • boolean watch:表明是否需要注册一个Watcher,如果为true,则使用默认的Watcher(在客户端创建会话的时候传入的Watcher),false则不需要注册Watcher
  • Watcher watcher:注册一个Watcher。用来监听以下事件:节点被创建、节点被删除、节点被更新
  • StatCallback cb:注册一个异步回调函数
  • Object ctx:用于传递上下文的对象

权限控制

如果想使用权限控制功能,那么需要在Zookeeper客户端创建之后,为Zookeeper客户端添加权限控制信息,API接口如下:

public void addAuthInfo(String scheme, byte auth[])
  • schema:权限控制模式,主要有以下几种:world、auth、digest、ip和super
  • auth[]:具体的权限信息

这边有个注意点:就是删除权限的控制比较特殊,当客户端对一个数据节点加了权限信息以后,对于删除操作而言,作用范围是子节点,但是这个节点本身还是可以自由删除的。

通过上面的讲述,我们可以看出使用原生的Zookeeper API还是比较复杂的,在上面我们还没有考虑关于Session重连等问题,因此我们很少直接使用原生的API与Zookeeper服务端进行交互,而是使用一些经过封装改良的客户端(例如ZkClient和Curator,这个后面讲),但是作为原生的API我们还是需要去了解的,因为封装改良的客户端其实最后还是使用的原生API进行操作的。

本文分享自微信公众号 - shysh95(shysh95),作者:shysh95

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ZkClient使用

    使用原生的Zookeeper API来与Zookeeper服务端进行交互还是比较繁琐复杂的,为了简化这些操作,就诞生了一些封装客户端。这些客户端除了简单易用,还...

    shysh95
  • Dubbo注册中心之Zookeeper(续)

    上图是Dubbo注册中心的整体类图,基于接口的实现方式可以方便我们扩展注册中心的实现方式,下面简单介绍一下各个类的作用:

    shysh95
  • Kafka日志分段与消息查找

    Kafka作为一个消息中间件(后面Kafka逐渐转向一个流失处理平台KafkaStream),消息最终的存储都落在日志中。

    shysh95
  • PHP-多文件上传

    2、一只猴子看守一堆桃子,第一天吃了一半后又多吃了1个,第二天一样,到第十天的时候就剩下一个桃子,请问原来有几个桃子?

    cwl_java
  • Zookeeper客户端API之读取子节点列表(八)

    本篇博客介绍一下Zookeeper原生客户端API提供的获取子节点列表方法。 获取子节点列表方法 方法 Zookeeper原生客户端API提供了以下8中获取子节...

    用户1161110
  • 多路径软件multipath.conf配置详解

    Multipath简称为多路径访问,主要功能就是和存储设备一起配合实现三大功能: 1. 故障的切换和恢复 2. IO流量的负载均衡 3. 磁盘的虚拟化

    孙杰
  • 用状态机的思想解析字符串

    在编程思想比较高级的有递归和状态机等使用比较少的代码就可以做出复杂的逻辑,状态机的思想是在一个状态到另一个状态,每个状态知道自己能处理的内容,同时知道可以调用哪...

    林德熙
  • 牵手大众、现代,滴滴绯闻“女友”Aurora无人车启动商业化

    维金 夏乙 编译整理 量子位 出品 | 公众号 QbitAI ? 团队阵容豪华、行事低调的无人车创业公司Aurora Innovations在创立一年之后,终于...

    量子位
  • 音乐不是你想卖,想卖他就买:提升用户购买欲的设计探索 - 腾讯ISUX

    腾讯ISUX
  • 目标检测--Faster R-CNN

    Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks

    用户1148525

扫码关注云+社区

领取腾讯云代金券