可以将ZK看作一个具有高可用性特征的文件系统。这个文件系统中没有文件和目录,而是统一使用节点(znode)的概念,称为znode。znode既可以作为保存数据的容器(如同文件),也可以作为保存其他znode的容器(如同目录)。所有的znode构成了一个层次化的命名空间,一种自然的建立组成员列表的方式就是利用这种层次结构,创建一个以组名为节点名的znode作为父节点,然后以组成员名(服务器名)为节点名来创建作为子节点的znode。

创建组

package com.zhen.zookeeper.createGroup;

import java.io.IOException;
import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper; /**
* @author FengZhen
* @date 2018年10月13日
* 创建组
*/
public class CreateGroup implements Watcher{ private static final int SESSION_TIMEOUT = 5000; private ZooKeeper zk;
private CountDownLatch connectedSignal = new CountDownLatch(1); public void connect(String hosts) throws IOException, InterruptedException {
/**
* hosts:ZooKeeper服务的主机地址(可指定端口,默认是2181)
* SESSION_TIMEOUT:以毫秒为单位的会话超时参数(此处为5秒)
* this:Watcher对象的实例。Watcher对象接收来自于ZooKeeper的回调,以获得各种事件的通知。
*/
zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this);
connectedSignal.await();
} /**
* 当客户端已经与ZK建立连接后,Watcher的process方法会被调用
* 参数是一个用于表示该连接的事件。
*/
public void process(WatchedEvent event) {
//连接事件
if (event.getState() == KeeperState.SyncConnected) {
/**
* 通过调用CountDownLatch的countDown方法来递减它的计数器。
* 锁存器(latch)被创建时带有一个值为1的计数器,用于表示在它释放所有等待线程之前需要发生的事件数。
* 在调用一次countDown方法之后,计数器的值变为0,则await方法返回。
*/
connectedSignal.countDown();
}
} public void create(String groupName) throws KeeperException, InterruptedException {
String path = "/" + groupName;
/**
* 用ZK的create方法创建一个新的ZK的znode
* path:路径(用字符串表示)
* null:znode的内容(字节数组,此处为空值)
* Ids.OPEN_ACL_UNSAFE:访问控制列表(简称ACL,此处为完全开放的ACL,允许任何客户端对znode进行读写)
* CreateMode.PERSISTENT:znode类型
* znode类型可以分为两种:1.短暂的(ephemeral) 2.持久的(persistent)
* 创建znode的客户端断开连接时,无论客户端是明确断开还是因为任何原因而终止,短暂znode都会被ZK服务删除。持久znode不会被删除。
* create方法的返回值是ZK所创建的节点路径
*/
String createdPath = zk.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("Created " + createdPath);
} public void close() throws InterruptedException {
zk.close();
} public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String hosts = "localhost:2181";
String groupName = "zoo";
CreateGroup createGroup = new CreateGroup();
createGroup.connect(hosts);
createGroup.create(groupName);
createGroup.close();
} }

  

提供一个连接类

package com.zhen.zookeeper;

import java.io.IOException;
import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.KeeperState; /**
* @author FengZhen
* @date 2018年10月13日
* 等待与ZK建立连接
*/
public class ConnectionWatcher implements Watcher{ private static final int SESSION_TIMEOUT = 5000; protected ZooKeeper zk;
private CountDownLatch connectedSignal = new CountDownLatch(1); public void connect(String hosts) throws IOException, InterruptedException {
/**
* hosts:ZooKeeper服务的主机地址(可指定端口,默认是2181)
* SESSION_TIMEOUT:以毫秒为单位的会话超时参数(此处为5秒)
* this:Watcher对象的实例。Watcher对象接收来自于ZooKeeper的回调,以获得各种事件的通知。
*/
zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this);
connectedSignal.await();
} /**
* 当客户端已经与ZK建立连接后,Watcher的process方法会被调用
* 参数是一个用于表示该连接的事件。
*/
public void process(WatchedEvent event) {
//连接事件
if (event.getState() == KeeperState.SyncConnected) {
/**
* 通过调用CountDownLatch的countDown方法来递减它的计数器。
* 锁存器(latch)被创建时带有一个值为1的计数器,用于表示在它释放所有等待线程之前需要发生的事件数。
* 在调用一次countDown方法之后,计数器的值变为0,则await方法返回。
*/
connectedSignal.countDown();
}
} public void close() throws InterruptedException {
zk.close();
} }

  

加入组

package com.zhen.zookeeper.joinGroup;

import java.io.IOException;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids; import com.zhen.zookeeper.ConnectionWatcher; /**
* @author FengZhen
* @date 2018年10月13日
* 加入组-注册组成员
*/
public class JoinGroup extends ConnectionWatcher{ public void join(String groupName, String memberName) throws KeeperException, InterruptedException {
String path = "/" + groupName + "/" + memberName;
//创建短暂znode作为组znode的子节点
String createdPath = zk.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("Created " + createdPath);
} public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String hosts = "localhost:2181";
String groupName = "zoo";
String memberName = "member1";
JoinGroup joinGroup = new JoinGroup();
joinGroup.connect(hosts);
joinGroup.join(groupName, memberName);
Thread.sleep(Long.MAX_VALUE);
} /**
* echo dump | nc localhost 2181
SessionTracker dump:
Session Sets (3):
0 expire at Sat Oct 13 15:57:48 CST 2018:
0 expire at Sat Oct 13 15:57:50 CST 2018:
1 expire at Sat Oct 13 15:57:52 CST 2018:
0x166594274c90001
ephemeral nodes dump:
Sessions with Ephemerals (1):
0x166594274c90001:
/zoo/member1
*/
}

  

列出组成员

package com.zhen.zookeeper.listGroup;

import java.io.IOException;
import java.util.List; import org.apache.zookeeper.KeeperException; import com.zhen.zookeeper.ConnectionWatcher; /**
* @author FengZhen
* @date 2018年10月13日
* 列出组成员
*/
public class ListGroup extends ConnectionWatcher{ public void list(String groupName) {
String path = "/" + groupName;
try {
/**
* 输出一个znode的子节点列表
* path:该znode的路径
* false:观察标志
* 如果在一个znode上设置了观察标志,那么一旦该znode的状态改变,关联的观察(Watcher)会被触发。
* 虽然此处没有使用观察,但在查看一个znode的子节点时,通过设置观察可以让应用程序接收到组成员加入、退出和组被删除的有关通知
*/
List<String> children = zk.getChildren(path, false);
if (children.isEmpty()) {
System.out.printf("No members in group %s\n", groupName);
System.exit(1);
}
for (String child : children) {
System.out.println(child);
}
} catch (KeeperException e) {
System.out.printf("Group %s does not exist\n", groupName);
System.exit(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) throws IOException, InterruptedException {
String hosts = "localhost:2181";
String groupName = "zoo";
ListGroup listGroup = new ListGroup();
listGroup.connect(hosts);
listGroup.list(groupName);
listGroup.close();
} /**
* 也可使用命令行工具
* ./zkCli.sh -server localhost:2181 ls /zoo
* Connecting to localhost:2181
2018-10-13 16:26:10,856 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.9-1757313, built on 08/23/2016 06:50 GMT
2018-10-13 16:26:10,860 [myid:] - INFO [main:Environment@100] - Client environment:host.name=192.168.1.109
2018-10-13 16:26:10,860 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_162
2018-10-13 16:26:10,863 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2018-10-13 16:26:10,863 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home/jre
2018-10-13 16:26:10,863 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../build/classes:/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../build/lib/*.jar:/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../lib/slf4j-log4j12-1.6.1.jar:/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../lib/slf4j-api-1.6.1.jar:/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../lib/netty-3.10.5.Final.jar:/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../lib/log4j-1.2.16.jar:/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../lib/jline-0.9.94.jar:/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../zookeeper-3.4.9.jar:/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../src/java/lib/*.jar:/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin/../conf:
2018-10-13 16:26:10,863 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/Users/FengZhen/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
2018-10-13 16:26:10,863 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/var/folders/tr/vc5hfpsd2c56s7m9wh93401h0000gn/T/
2018-10-13 16:26:10,863 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA>
2018-10-13 16:26:10,863 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Mac OS X
2018-10-13 16:26:10,864 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=x86_64
2018-10-13 16:26:10,864 [myid:] - INFO [main:Environment@100] - Client environment:os.version=10.13.4
2018-10-13 16:26:10,864 [myid:] - INFO [main:Environment@100] - Client environment:user.name=FengZhen
2018-10-13 16:26:10,864 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/Users/FengZhen
2018-10-13 16:26:10,864 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/Users/FengZhen/Desktop/Hadoop/zookeeper-3.4.9/bin
2018-10-13 16:26:10,865 [myid:] - INFO [main:ZooKeeper@438] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@799f7e29
2018-10-13 16:26:10,898 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181. Will not attempt to authenticate using SASL (unknown error)
2018-10-13 16:26:11,014 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@876] - Socket connection established to localhost/0:0:0:0:0:0:0:1:2181, initiating session
2018-10-13 16:26:11,024 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2181, sessionid = 0x166594274c90006, negotiated timeout = 30000 WATCHER:: WatchedEvent state:SyncConnected type:None path:null
[member1]
*/
}

  

删除组

package com.zhen.zookeeper.deleteGroup;

import java.io.IOException;
import java.util.List; import org.apache.zookeeper.KeeperException; import com.zhen.zookeeper.ConnectionWatcher; /**
* @author FengZhen
* @date 2018年10月13日
* 删除组
*
*/
public class DeleteGroup extends ConnectionWatcher{ public void delete(String groupName) {
String path = "/" + groupName;
try {
List<String> children = zk.getChildren(path, false);
for (String child : children) {
zk.delete(path + "/" + child, -1);
}
/**
* delete方法有两个参数
* path:节点路径
* -1:版本号
* 如果所提供的版本号与znode的版本号一致,ZK会删除这个znode。
* 这是一种乐观的加锁机制,使客户端能够检测出对znode的修改冲突。
* 通过将版本号设置为-1,可以绕过这个版本检测机制,不管znode的版本号是什么而直接将其删除。
* ZK不支持递归删除,因此在删除父节点之前必须先删除子节点
*/
zk.delete(path, -1);
} catch (KeeperException e) {
System.out.printf("Group %s does not exist\n", groupName);
System.exit(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) throws IOException, InterruptedException {
String hosts = "localhost:2181";
String groupName = "zoo";
DeleteGroup deleteGroup = new DeleteGroup();
deleteGroup.connect(hosts);
deleteGroup.delete(groupName);
deleteGroup.close();
} }

  

ZooKeeper-znode概念与使用的更多相关文章

  1. 1、ZooKeeper 基本概念、使用方法、实践场景

    ZooKeeper 基本概念 ZooKeeper 是面向分布式应用的协调服务,其实现了树形结构的数据模型(与文件系统类似),并且提供了简洁的编程原语.ZooKeeper 能够作为基础,用于构建更高层级 ...

  2. ZooKeeper 基本概念并介绍RPC中Netty和Zookeeper的使用

    前言 ZooKeeper 是一个分布式协调服务,可用于服务发现,分布式锁,分布式领导选举,配置管理等.Zookeeper提供一个类似Linux文件系统的属性结构,每个节点可存储少量的内存文件,并提供每 ...

  3. ERROR: The node /hbase is not in ZooKeeper. It should have been written by the master. Check the value configured in 'zookeeper.znode.parent'. There could be a mismatch with the one configured in the

    hbase  shell下list命令出错. [hadoop@djt002 hbase]$ hbase shell 2016-07-20 19:37:12,522 INFO  [main] Confi ...

  4. Hbase出现ERROR: Can't get master address from ZooKeeper; znode data == null解决办法

    问题描述如下: hbase(main)::> list TABLE ERROR: Can't get master address from ZooKeeper; znode data == n ...

  5. HBase错误:ERROR: Can't get master address from ZooKeeper; znode data == null 解决办法

    一.问题背景 使用命令 $ hbase shell 进入hbase的shell之后使用create命令创建表时出现错误:ERROR: Can't get master address from Zoo ...

  6. hbase shell出现ERROR:Can't get master address from Zookeeper;znode data==null

    hbase shell出现ERROR:Can't get master address from Zookeeper;znode data==null(ERROR:org.apache.hadoop. ...

  7. phoenix hbase Can't get master address from ZooKeeper; znode data == null

    问题描述: 项目一直在用的hbase节点  简称h1 由于网络问题,无法使用,重新找了一个网络稳定的节点  z1作为新的hbase库,库名称hbase_test,zookeeper等都配置好后,通过j ...

  8. 第一章 zookeeper基础概念

    1.ZooKeeper是什么 ZooKeeper为分布式应用提供了高效且可靠的分布式协调服务,提供了统一命名服务. 配置管理和分布式锁等分布式的基础服务.在解决分布式数据一致性方面, ZooKeepe ...

  9. 二:ZooKeeper术语概念

    一:Zookeeper的设计目标   -->Zookeeper致力于提供一个高性能,高可用,且具有严格的顺序访问控制能力(主要是写操作的严格顺行性)的分布式协调服务. -->高性能使得Zo ...

  10. zookeeper基本概念及原理

    zookeeper是一个分布式的,开源的分布式应用程序,该程序主要用于管理其他分布式应用程序.其他分布式应用程序可以基于zookeeper实现数据同步,配置维护和命名服务等等.zookeeper是Ha ...

随机推荐

  1. poll机制实例参考

    poll机制:为了减少CPU资源的占用率,在编写驱动函数中添加poll机制 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就 ...

  2. CodeIgniter框架——创建一个简单的Web站点(include MySQL基本操作)

    目标 使用 CodeIgniter 创建一个简单的 Web 站点.该站点将有一个主页,显示一些宣传文本和一个表单,该表单将发布到数据库表中. 按照 CodeIgniter 的术语,可将这些需求转换为以 ...

  3. CODEVS 必做题:3149、2821、1531、3369、1230

    3149 爱改名的小融 2  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description Wikioi上有个人叫小融,他喜 ...

  4. 安装mysql报错—解决方法:error while loading shared libraries: libssl.so.6

    for 32bit ln -sf /usr/lib/libssl.so.10 /usr/lib/libssl.so.6ln -sf /usr/lib/libcrypto.so.10 /usr/lib/ ...

  5. Shell脚本实现用户数据导入

    #输入:固定格式的用户数据user.sql #处理:循环读取user.sql中的每行(每行对应一条用户数据),依次调用curl命令将用户插入BearyChat #输出:执行结果输出到日志文件outlo ...

  6. unity坑faq

    遇到的坑记录下来,大都都是听说,没有实测 1. Graphics.copyTexture,在某些机型上不支持从不同类型拷贝 2. msaa 小米mix2不支持,晓龙845 3. android4.2下 ...

  7. python函数回顾:dict()

    描述 dict() 函数用于创建一个字典. 语法 dict 语法: class dict(**kwarg) class dict(mapping, **kwarg) class dict(iterab ...

  8. RabbitMQ_消息队列基本使用_1

    什么叫消息队列 消息(Message)是指在应用间传送的数据.消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象. 消息队列(Message Queue)是一种应用间的通信方式,消 ...

  9. Python3.6全栈开发实例[006]

    6.检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者. dic = {"k1": "v1v1", " ...

  10. matlab学习笔记之五种常见的图形绘制功能

    分类: 离散数据图形绘制 函数图形绘制 网格图形绘制 曲面图形绘制 特殊图形绘制 本文重点介绍matlab五种图形绘制方法的后三种. 一.网格图形绘制 以绘制函数z=f(x,y)三维网格图为例,下面为 ...