[hadoop][基本原理]zookeeper简单使用
代码:https://github.com/xufeng79x/ZkClientTest
1、简介
zookeeper的基本原理和使用场景描述可参考:[hadoop][基本原理]zookeeper基本原理
本文主要讲解zookeeper节点的增删除改查,以及watcher的使用。
2.工程准备
除了zookeeper的自身API外,有两个开源的api更加方便的去让开发者使用----ZkClient和Curator。
上述两个开源API中个人感觉ZkClient使用起来更加直观明了,所以在这里我会使用ZkClient来做讲解。
新建maven工程,在pom文件按照版本需求增加下列依赖:
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.6</version>
</dependency>
3.增删改查操作
public static void main(String[] args) {
String znodePath = "/xufeng";
String znodeChildPath1 = "/xufeng/xufeng";
String znodeChildPath2 = "/xufeng/xufeng"; // 创建连接(既创建session)
//param1:zookeeper集群信息
//param2:session超时时间
//param3:连接超时时间
//param4:序列化方法,既我们设定在znode上的数据类的序列与反序列方法
ZkClient zc = new ZkClient("xufeng-1:2181,xufeng-2:2181,xufeng-3:2181", , , new SerializableSerializer());
System.out.println("connected osssssssk!"); //由于在创建此节点的时候已经指定了一般pojo类的序列类,所以我们可以直接将一个实例类在创建的时候设定到znode上去
Server server = new Server("myserver", ""); zc.create(znodePath, server, CreateMode.PERSISTENT); // 检查znode是否创建成功
boolean isExist = zc.exists(znodePath);
if (isExist)
{
System.out.println(znodePath + " has been created!");
} // 勾取znode的状态信息
Stat stat = new Stat();
server = zc.readData(znodePath, stat);
System.out.println("server info : " + server + " state : " + stat); // 创建子节点
zc.create(znodeChildPath1, null, CreateMode.EPHEMERAL_SEQUENTIAL);
zc.create(znodeChildPath2, null, CreateMode.EPHEMERAL_SEQUENTIAL);
if (zc.exists(znodeChildPath1) && zc.exists(znodeChildPath2))
{
System.out.println("znodeChildPaths + has been created!");
}
// 取得子节点列表
List<String> childs = zc.getChildren(znodePath);
System.out.println(childs); // 删除没有子节点的节点
boolean e1 = zc.delete(znodeChildPath1);
// 删除有子节点的节点
boolean e2 = zc.deleteRecursive(znodePath);
if (e1 && e2)
{
System.out.println("All znode have been deleted!");
}
}
}
其中Server为pojo类,它必须实现序列化接口(方法可以不必去实现,SerializableSerializer对象会做出处理)
// 必须实现序列化接口
public class Server implements Serializable{
private String name = null;
private String id = null; public Server(String name, String id) {
super();
this.name = name;
this.id = id;
}
// 序列化与反序列化中必须要有这个构造方法(默认是有的,但是你一旦创建了其他构造方法,那么就默认没有了)
public Server() {
super();
this.name = null;
this.id = null;
}
运行结果:
connected osssssssk!
/xufeng has been created!
server info : Server [name=myserver, id=] state : ,,,,,,,,,, [xufeng0000000000, xufeng0000000001]
结果分析:
1. 上述/xufeng 为永久节点,如果不删除就不会消失
2. 设定在/xufeng节点上的数据也被正确的read出来。
3. 节点状态也可以read出来,但是必须先构造Stat对象然后将数据勾出来。
4. 创建节点时候可以指定是否SEQUENTIAL,如上的两个临时子节点就是用了SEQUENTIAL他会自动给名称按序不重复,这在队列,锁和主备场景下很有实际用处。
4.节点状态订阅
所谓状态订阅有三种,一种为节点数据变化的订阅,一种是节点状态改变和另外一种的节点子节点(或者其本身)创建和删除的变化的订阅,分别通过不同的回调函数来实现这两种订阅处理。
下面代码执行后会创建如下节点:
[zk: localhost:(CONNECTED) ] ls /
[hadoop-ha, yarn-leader-election, zookeeper, xufeng]
[zk: localhost:(CONNECTED) ] ls /xufeng
[xufeng0000000000, xufeng0000000001]
public class ZkClientScribeTest { public static void main(String[] args) throws InterruptedException {
String znodePath = "/xufeng";
String znodeChildPath1 = "/xufeng/xufeng";
String znodeChildPath2 = "/xufeng/xufeng"; // 创建连接(既创建session)
//param1:zookeeper集群信息
//param2:session超时时间
//param3:连接超时时间
//param4:序列化方法,既我们设定在znode上的数据类的序列与反序列方法
ZkClient zc = new ZkClient("xufeng-1:2181,xufeng-2:2181,xufeng-3:2181", , , new BytesPushThroughSerializer());
System.out.println("connected ok!"); // 创建节点与其子节点,为了易于操作,我们将以永久节点来进行测试
zc.create(znodePath, "I am /xufeng".getBytes(), CreateMode.PERSISTENT);
zc.create(znodeChildPath1, "I am /xufeng/xufeng*0".getBytes(), CreateMode.PERSISTENT_SEQUENTIAL);
zc.create(znodeChildPath2, "I am /xufeng/xufeng*1".getBytes(), CreateMode.PERSISTENT_SEQUENTIAL); // 订阅节点数据发生变化
zc.subscribeDataChanges(znodePath, new IZkDataListener() {
// 当其本身或者子节点的删除或者增加的时候讲触发此操作
public void handleDataDeleted(String dataPath) throws Exception {
System.out.println(dataPath + " data has been deleted!");
} public void handleDataChange(String dataPath, Object data) throws Exception {
System.out.println(dataPath + " data has been change to " + String.valueOf(data));
}
}); // 订阅节点及其子节点发生变化
zc.subscribeChildChanges(znodePath, new IZkChildListener() {
// 当其本身或者子节点的删除或者增加的时候讲触发此操作
public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
System.out.println(parentPath + " childs has been change : ");
System.out.println(currentChilds); }
}); // 订阅节点状态发生变化
zc.subscribeStateChanges(new IZkStateListener() {
public void handleStateChanged(KeeperState state) throws Exception {
System.out.println(state); } public void handleSessionEstablishmentError(Throwable error) throws Exception {
System.out.println(error); } public void handleNewSession() throws Exception {
System.out.println("new session!"); }
}); Thread.sleep(Long.MAX_VALUE); } }
1.修改/xufeng节点数据
[zk: localhost:(CONNECTED) ] set /xufeng
cZxid = 0x1600000005
ctime = Thu Jul :: EDT
mZxid = 0x1600000008
mtime = Thu Jul :: EDT
pZxid = 0x1600000007
cversion =
dataVersion =
aclVersion =
ephemeralOwner = 0x0
dataLength =
numChildren =
[zk: localhost:(CONNECTED) ]
程序测将会输出:
/xufeng data has been change to [B@4222023a
2. 在/xufeng/节点下增加一个节点:
[zk: localhost:(CONNECTED) ] create -s /xufeng/xufeng
Created /xufeng/xufeng0000000002
程序侧将会输出:
/xufeng childs has been change :
[xufeng0000000000, xufeng0000000001, xufeng0000000002]
3.删除/xufeng/xufeng0000000000节点
[zk: localhost:(CONNECTED) ] delete /xufeng/xufeng0000000000
[zk: localhost:(CONNECTED) ]
程序侧将输出:
/xufeng childs has been change :
[xufeng0000000001, xufeng0000000002]
4.删除/xufeng节点
[zk: localhost:(CONNECTED) ] rmr /xufeng
[zk: localhost:(CONNECTED) ]
程序侧将会输出:可以看到先去删除子节点(触发watcher),在删除本身(触发watcher)然后触发数据删除watcher
/xufeng childs has been change :
[]
/xufeng childs has been change :
null
/xufeng data has been deleted!
5. 思考-----如何保证一个临时节点不被删除(既如何维护这个临时节点)
public class saveEphemeralNode {
public static void main(String[] args) throws InterruptedException {
String znodePath = "/xufeng_EPHEMERAL"; // 创建连接(既创建session)
//param1:zookeeper集群信息
//param2:session超时时间
//param3:连接超时时间
//param4:序列化方法,既我们设定在znode上的数据类的序列与反序列方法
ZkClient zc = new ZkClient("xufeng-1:2181,xufeng-2:2181,xufeng-3:2181", , , new SerializableSerializer());
System.out.println("connected ok!"); zc.create(znodePath, null, CreateMode.EPHEMERAL); Thread.sleep(Long.MAX_VALUE);
} }
上述代码中Thread.sleep(Long.MAX_VALUE)语句保证了进程不会退出,此时/xufeng_EPHEMERAL一直保持存在状态,而当手动结束此进程后的10秒后这个节点消失。
有此得出结论,只要保持session长连接的存在,临时节点就不会被删除。
[hadoop][基本原理]zookeeper简单使用的更多相关文章
- [hadoop][基本原理]zookeeper基本原理
1.简介 https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/ 2. 数据模型 Zookeeper 会维护一个具有层次关系 ...
- [hadoop][基本原理]zookeeper场景使用
代码:https://github.com/xufeng79x/ZkClientTest 1. 简介 zookeeper的特性决定他适用到某些场景非常合适,比如典型的应用场景: 1.集群管理(Grou ...
- 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解
引言 在之前的大数据学习系列中,搭建了Hadoop+Spark+HBase+Hive 环境以及一些测试.其实要说的话,我开始学习大数据的时候,搭建的就是集群,并不是单机模式和伪分布式.至于为什么先写单 ...
- HADOOP+SPARK+ZOOKEEPER+HBASE+HIVE集群搭建(转)
原文地址:https://www.cnblogs.com/hanzhi/articles/8794984.html 目录 引言 目录 一环境选择 1集群机器安装图 2配置说明 3下载地址 二集群的相关 ...
- ZooKeeper简单使用
原文:ZooKeeper简单使用 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012055638/article/details/8066811 ...
- Hadoop+Hbase+Zookeeper分布式存储构建
目录: 软件准备 Hadoop安装配置 zookeeper安装配置 Hbase安装配置 Hadoop+Hbase+zookeeper分布式存储构建 前言* Hadoop是Apache开源组织的一个分布 ...
- Linux配置zookeeper 和zookeeper简单介绍
一.zookeeper介绍? 一.zookeeper 简单介绍? 1.什么是集群? // 很多台服务器保持连接通讯状态,并且所有的服务器做同一件事就称之为集群 2.什么是zookeeper? 注册中心 ...
- [推荐]Hadoop+HBase+Zookeeper集群的配置
[推荐]Hadoop+HBase+Zookeeper集群的配置 Hadoop+HBase+Zookeeper集群的配置 http://wenku.baidu.com/view/991258e881c ...
- Hadoop,HBase,Zookeeper源码编译并导入eclipse
基本理念:尽可能的参考官方英文文档 Hadoop: http://wiki.apache.org/hadoop/FrontPage HBase: http://hbase.apache.org/b ...
随机推荐
- java动态代理(JDK和CGLIB)笔记
动态代理:为一堆interface或类的实现提供统一的执行通道,从含义上就像局域网电脑通过代理上网一样,走统一的通道,代理控制通道,自然可以在通道里加上自定义实现,例如像AOP切面,日志等. JDK的 ...
- bzoj 1207: [HNOI2004]打鼹鼠 (dp)
var n,m,i,j,ans:longint; x,y,time,f:..]of longint; begin readln(n,m); to m do readln(time[i],x[i],y[ ...
- [HNOI2012]排队 组合数
公式:A(n,n)*A(n+1,2)*A(n+3,m) + A(n,n)*C(m,1)*A(2,2)*C(n+1,1)*A(n+2,m-1) 分情况讨论推出公式 前者为无论何时都合法的,后者为先不合法 ...
- BZOJ5323 & 洛谷4562:[JXOI2018]游戏——题解
https://www.luogu.org/problemnew/show/P4562 https://www.lydsy.com/JudgeOnline/problem.php?id=5323 (B ...
- HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包)
HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包) 题意分析 裸完全背包 代码总览 #include <iostream> #include <cstdio& ...
- 【二分】【P1314】 【NOIP2011D2T2】聪明的质监员
传送门 Description 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 \(n\) 个矿石,从 \(1\) 到 \(n\) 逐一编号,每个矿石都有自己的重量 \(w_i\) ...
- POJ1236:Network of Schools (思维+Tarjan缩点)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24880 Accepted: 99 ...
- OpenCV学习笔记(01)我的第一个OpenCV程序(环境配置)
昨天刚刚考完编译原理,私心想着可以做一些与考试无关的东西了.一直想做和图像处理相关的东西,趁这段时间有空学习一下OpenCV,搭建环境真是一件麻烦的事情,搞了近三个小时终于OK了.先来张图: 大致描述 ...
- javascript功能封装
实现方式其实很简单,我在代码打上注释,大家就懂了! var _date=[],dateData=["1月","2月","3月",&qu ...
- HBase客户端访问超时的多个因素及参数
在一个需要低延时响应的hbase集群中,使用hbase默认的客户端超时配置简直就是灾难. 但是我们可以考虑在客户端上加上如下几个参数,去改变这种状况: 1. hbase.rpc.timeout: RP ...