Apache Curator获得真正的

Curator它是Netflix一家公司来源Zookeeper顾客,与Zookeeper相比于提供本地客户端,Curator的抽象层次更高,简化了Zookeeper客户端的开发量。

1.Zookeeper安装部署

Zookeeper的部署非常easy。假设已经有Java执行环境的话。下载tarball解压后即可执行。

[root@vm Temp]$ wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz
[root@vm Temp]$ tar zxvf zookeeper-3.4.6.tar.gz
[root@vm Temp]$ cd zookeeper-3.4.6 [root@vm zookeeper-3.4.6]$ cp conf/zoo_sample.cfg conf/zoo.cfg
[root@vm zookeeper-3.4.6]$ export ZOOKEEPER_HOME=/usr/local/src/zookeeper-3.4.5
[root@vm zookeeper-3.4.6]$ export PATH=$ZOOKEEPER_HOME/bin:$PATH [root@vm zookeeper-3.4.6]$ bin/zkServer.sh start
[root@vm zookeeper-3.4.6]$ bin/zkCli.sh -server 127.0.0.1:2181

2.客户端经常使用操作

用zkCli.sh连接上Zookeeper服务后,用help能列出全部命令:

[root@BC-VM-edce4ac67d304079868c0bb265337bd4 zookeeper-3.4.6]# bin/zkCli.sh -127.0.0.1:2181
Connecting to localhost:2181
2015-06-11 10:55:14,387 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT
... [zk: localhost:2181(CONNECTED) 5] help
ZooKeeper -server host:port cmd args
connect host:port
get path [watch]
ls path [watch]
set path data [version]
rmr path
delquota [-n|-b] path
quit
printwatches on|off
create [-s] [-e] path data acl
stat path [watch]
close
ls2 path [watch]
history
listquota path
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
setquota -n|-b val path

以下就试验一下经常使用的命令:

  • create:创建路径结点。

  • ls:查看路径下的全部结点。
  • get:获得结点上的值。
  • set:改动结点上的值。
  • delete:删除结点。

[zk: localhost:2181(CONNECTED) 6] create /zktest mydata
Created /zktest
[zk: localhost:2181(CONNECTED) 12] ls /
[zktest, zookeeper]
[zk: localhost:2181(CONNECTED) 7] ls /zktest
[]
[zk: localhost:2181(CONNECTED) 13] get /zktest
mydata
cZxid = 0x1c
ctime = Thu Jun 11 10:58:06 CST 2015
mZxid = 0x1c
mtime = Thu Jun 11 10:58:06 CST 2015
pZxid = 0x1c
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 14] set /zktest junk
cZxid = 0x1c
ctime = Thu Jun 11 10:58:06 CST 2015
mZxid = 0x1f
mtime = Thu Jun 11 10:59:08 CST 2015
pZxid = 0x1c
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: localhost:2181(CONNECTED) 15] delete /zktest
[zk: localhost:2181(CONNECTED) 16] ls /
[zookeeper]

3.用Curator管理Zookeeper

Curator的Maven依赖例如以下,一般直接使用curator-recipes即可了,假设须要自己封装一些底层些的功能的话,比如添加连接管理重试机制等,则能够引入curator-framework包。

    <dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.7.0</version>
</dependency>

3.1 Client操作

利用Curator提供的客户端API。能够全然实现上面原生客户端的功能。

值得注意的是,Curator採用流式风格API。

package com.cdai.codebase.bigdata.hadoop.zookeeper.curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes; /**
* Curator framework's client test.
* Output:
* $ create /zktest hello
* $ ls /
* [zktest, zookeeper]
* $ get /zktest
* hello
* $ set /zktest world
* $ get /zktest
* world
* $ delete /zktest
* $ ls /
* [zookeeper]
*/
public class CuratorClientTest { /** Zookeeper info */
private static final String ZK_ADDRESS = "192.168.1.100:2181";
private static final String ZK_PATH = "/zktest"; public static void main(String[] args) throws Exception {
// 1.Connect to zk
CuratorFramework client = CuratorFrameworkFactory.newClient(
ZK_ADDRESS,
new RetryNTimes(10, 5000)
);
client.start();
System.out.println("zk client start successfully!"); // 2.Client API test
// 2.1 Create node
String data1 = "hello";
print("create", ZK_PATH, data1);
client.create().
creatingParentsIfNeeded().
forPath(ZK_PATH, data1.getBytes()); // 2.2 Get node and data
print("ls", "/");
print(client.getChildren().forPath("/"));
print("get", ZK_PATH);
print(client.getData().forPath(ZK_PATH)); // 2.3 Modify data
String data2 = "world";
print("set", ZK_PATH, data2);
client.setData().forPath(ZK_PATH, data2.getBytes());
print("get", ZK_PATH);
print(client.getData().forPath(ZK_PATH)); // 2.4 Remove node
print("delete", ZK_PATH);
client.delete().forPath(ZK_PATH);
print("ls", "/");
print(client.getChildren().forPath("/"));
} private static void print(String... cmds) {
StringBuilder text = new StringBuilder("$ ");
for (String cmd : cmds) {
text.append(cmd).append(" ");
}
System.out.println(text.toString());
} private static void print(Object result) {
System.out.println(
result instanceof byte[]
? new String((byte[]) result)
: result);
} }

3.2 监听器

Curator提供了三种Watcher(Cache)来监听结点的变化:

  • Path Cache:监视一个路径下1)孩子结点的创建、2)删除。3)以及结点数据的更新。产生的事件会传递给注冊的PathChildrenCacheListener。
  • Node Cache:监视一个结点的创建、更新、删除。并将结点的数据缓存在本地。

  • Tree Cache:Path Cache和Node Cache的“合体”,监视路径下的创建、更新、删除事件。并缓存路径下全部孩子结点的数据。

以下就測试一下最简单的Path Watcher:

package com.cdai.codebase.bigdata.hadoop.zookeeper.curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
import org.apache.curator.retry.RetryNTimes; /**
* Curator framework watch test.
*/
public class CuratorWatcherTest { /** Zookeeper info */
private static final String ZK_ADDRESS = "192.168.1.100:2181";
private static final String ZK_PATH = "/zktest"; public static void main(String[] args) throws Exception {
// 1.Connect to zk
CuratorFramework client = CuratorFrameworkFactory.newClient(
ZK_ADDRESS,
new RetryNTimes(10, 5000)
);
client.start();
System.out.println("zk client start successfully!"); // 2.Register watcher
PathChildrenCache watcher = new PathChildrenCache(
client,
ZK_PATH,
true // if cache data
);
watcher.getListenable().addListener((client1, event) -> {
ChildData data = event.getData();
if (data == null) {
System.out.println("No data in event[" + event + "]");
} else {
System.out.println("Receive event: "
+ "type=[" + event.getType() + "]"
+ ", path=[" + data.getPath() + "]"
+ ", data=[" + new String(data.getData()) + "]"
+ ", stat=[" + data.getStat() + "]");
}
});
watcher.start(StartMode.BUILD_INITIAL_CACHE);
System.out.println("Register zk watcher successfully!"); Thread.sleep(Integer.MAX_VALUE);
} }

以下是在zkCli.sh中操作时Java程序的输出:

Java: zk client start successfully!
Java: Register zk watcher successfully! zkCli: [zk: localhost:2181(CONNECTED) 11] create /zktest/hello mydata
Java: Receive event: type=[CHILD_ADDED], path=[/zktest/hello], data=[mydata], stat=[121,121,1434001221097,1434001221097,0,0,0,0,6,0,121] zkCli: [zk: localhost:2181(CONNECTED) 12] set /zktest/hello otherdata
Java: Receive event: type=[CHILD_UPDATED], path=[/zktest/hello], data=[otherdata], stat=[121,122,1434001221097,1434001228467,1,0,0,0,9,0,121] zkCli: [zk: localhost:2181(CONNECTED) 13] delete /zktest/hello
Java: Receive event: type=[CHILD_REMOVED], path=[/zktest/hello], data=[otherdata], stat=[121,122,1434001221097,1434001228467,1,0,0,0,9,0,121]

4.Curator“菜谱”

既然Maven包叫做curator-recipes。那说明Curator有它独特的“菜谱”

  • :包含共享锁、共享可重入锁、读写锁等。
  • 选举:Leader选举算法。

  • Barrier:阻止分布式计算直至某个条件被满足的“栅栏”,能够看做JDK Concurrent包中Barrier的分布式实现。
  • 缓存:前面提到过的三种Cache及监听机制。
  • 持久化结点:连接或Session终止后仍然在Zookeeper中存在的结点。
  • 队列:分布式队列、分布式优先级队列等。

4.1 分布式锁

分布式编程时,比方最容易碰到的情况就是应用程序在线上多机部署,于是当多个应用同一时候訪问某一资源时,就须要某种机制去协调它们。比如,如今一台应用正在rebuild缓存内容。要暂时锁住某个区域暂时不让訪问;又比方调度程序每次仅仅想一个任务被一台应用执行等等。

以下的程序会启动两个线程t1和t2去争夺锁。拿到锁的线程会占用5秒。执行多次能够观察到。有时是t1先拿到锁而t2等待,有时又会反过来。

Curator会用我们提供的lock路径的结点作为全局锁,这个结点的数据相似这样的格式:[_c_64e0811f-9475-44ca-aa36-c1db65ae5350-lock-0000000005],每次获得锁时会生成这样的串,释放锁时清空数据。

package com.cdai.codebase.bigdata.hadoop.zookeeper.curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.RetryNTimes; import java.util.concurrent.TimeUnit; /**
* Curator framework's distributed lock test.
*/
public class CuratorDistrLockTest { /** Zookeeper info */
private static final String ZK_ADDRESS = "192.168.1.100:2181";
private static final String ZK_LOCK_PATH = "/zktest"; public static void main(String[] args) throws InterruptedException {
// 1.Connect to zk
CuratorFramework client = CuratorFrameworkFactory.newClient(
ZK_ADDRESS,
new RetryNTimes(10, 5000)
);
client.start();
System.out.println("zk client start successfully!"); Thread t1 = new Thread(() -> {
doWithLock(client);
}, "t1");
Thread t2 = new Thread(() -> {
doWithLock(client);
}, "t2"); t1.start();
t2.start();
} private static void doWithLock(CuratorFramework client) {
InterProcessMutex lock = new InterProcessMutex(client, ZK_LOCK_PATH);
try {
if (lock.acquire(10 * 1000, TimeUnit.SECONDS)) {
System.out.println(Thread.currentThread().getName() + " hold lock");
Thread.sleep(5000L);
System.out.println(Thread.currentThread().getName() + " release lock");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
lock.release();
} catch (Exception e) {
e.printStackTrace();
}
} } }

4.2 Leader选举

当集群里的某个服务down机时。我们可能要从slave结点里选出一个作为新的master,这时就须要一套能在分布式环境中自己主动协调的Leader选举方法。

Curator提供了LeaderSelector监听器实现Leader选举功能。同一时刻,仅仅有一个Listener会进入takeLeadership()方法,说明它是当前的Leader。注意:当Listener从takeLeadership()退出时就说明它放弃了“Leader身份”。这时Curator会利用Zookeeper再从剩余的Listener中选出一个新的Leader。

autoRequeue()方法使放弃Leadership的Listener有机会又一次获得Leadership。假设不设置的话放弃了的Listener是不会再变成Leader的。

package com.cdai.codebase.bigdata.hadoop.zookeeper.curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.leader.LeaderSelector;
import org.apache.curator.framework.recipes.leader.LeaderSelectorListener;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.retry.RetryNTimes;
import org.apache.curator.utils.EnsurePath; /**
* Curator framework's leader election test.
* Output:
* LeaderSelector-2 take leadership!
* LeaderSelector-2 relinquish leadership!
* LeaderSelector-1 take leadership!
* LeaderSelector-1 relinquish leadership!
* LeaderSelector-0 take leadership!
* LeaderSelector-0 relinquish leadership!
* ...
*/
public class CuratorLeaderTest { /** Zookeeper info */
private static final String ZK_ADDRESS = "192.168.1.100:2181";
private static final String ZK_PATH = "/zktest"; public static void main(String[] args) throws InterruptedException {
LeaderSelectorListener listener = new LeaderSelectorListener() {
@Override
public void takeLeadership(CuratorFramework client) throws Exception {
System.out.println(Thread.currentThread().getName() + " take leadership!"); // takeLeadership() method should only return when leadership is being relinquished.
Thread.sleep(5000L); System.out.println(Thread.currentThread().getName() + " relinquish leadership!");
} @Override
public void stateChanged(CuratorFramework client, ConnectionState state) {
}
}; new Thread(() -> {
registerListener(listener);
}).start(); new Thread(() -> {
registerListener(listener);
}).start(); new Thread(() -> {
registerListener(listener);
}).start(); Thread.sleep(Integer.MAX_VALUE);
} private static void registerListener(LeaderSelectorListener listener) {
// 1.Connect to zk
CuratorFramework client = CuratorFrameworkFactory.newClient(
ZK_ADDRESS,
new RetryNTimes(10, 5000)
);
client.start(); // 2.Ensure path
try {
new EnsurePath(ZK_PATH).ensure(client.getZookeeperClient());
} catch (Exception e) {
e.printStackTrace();
} // 3.Register listener
LeaderSelector selector = new LeaderSelector(client, ZK_PATH, listener);
selector.autoRequeue();
selector.start();
} }

版权声明:本文博主原创文章,博客,未经同意不得转载。

Apache Curator获得真正的的更多相关文章

  1. Apache Curator: Zookeeper客户端

    Apache Curator Framework url: http://curator.apache.org/curator-framework/ The Curator Framework is ...

  2. Service Discovery with Apache Curator

    Curator的介绍 Curator就是Zookeeper的一个客户端工具(不知道Zookeeper的同学可以到http://www.ibm.com/developerworks/cn/opensou ...

  3. 15. 使用Apache Curator管理ZooKeeper

    Apache ZooKeeper是为了帮助解决复杂问题的软件工具,它可以帮助用户从复杂的实现中解救出来. 然而,ZooKeeper只暴露了原语,这取决于用户如何使用这些原语来解决应用程序中的协调问题. ...

  4. Apache Curator入门实战

    Apache Curator入门实战 Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeep ...

  5. Apache Curator is a Java/JVM client library for Apache ZooKeeper

    http://curator.apache.org/index.html Welcome to Apache Curator What is Curator? Curator n ˈkyoor͝ˌāt ...

  6. java.lang.NoSuchMethodError: org.apache.curator.framework.api.CreateBuilder.creatingParentsIfNeeded()Lorg/apache/curator/framework/api/ProtectACLCreateModeStatPathAndBytesable;

    1 错误信息 java.lang.NoSuchMethodError: org.apache.curator.framework.api.CreateBuilder.creatingParentsIf ...

  7. java.lang.NoClassDefFoundError: org/apache/curator/RetryPolicy解决方法

    今天集成es-job到公司的框架时,启动时出现上述错误 java.lang.NoClassDefFoundError: org/apache/curator/RetryPolicy at storm. ...

  8. 15. 使用Apache Curator装饰ZooKeeper

    Apache ZooKeeper是为了帮助解决复杂问题的软件工具,它可以帮助用户从复杂的实现中解救出来. 然而,ZooKeeper只暴露了原语,这取决于用户如何使用这些原语来解决应用程序中的协调问题. ...

  9. 【zookeeper】Apache curator的使用及zk分布式锁实现

    上篇,本篇主要讲Apache开源的curator的使用,有了curator,利用Java对zookeeper的操作变得极度便捷. 其实在学之前我也有个疑虑,我为啥要学curator,撇开涨薪这些外在的 ...

随机推荐

  1. ubuntu12.10下arm-linux-gcc交叉编译环境的搭建

    交叉编译环境搭建的原因:通俗上讲,因为嵌入式系统可用资源比较少:几十M的ARM 二三百M的flash相对我们的pc机来说资源真的没法比.所以,为了解决这种局面就将PC机等作为主机,搭建开发环境,进行编 ...

  2. SQL--存储过程+触发器 对比!

    一.存储过程 一:存储过程:存储过程是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中. 可以用存储过程名字和参数来调用存储过程,这样可以避免代码重复出现,用起来也方便. 例:    下面 ...

  3. 虚继承之单继承的内存布局(VC在编译时会把vfptr放到类的头部,这和Delphi完全一致)

    C++2.0以后全面支持虚函数与虚继承,这两个特性的引入为C++增强了不少功能,也引入了不少烦恼.虚函数与虚继承有哪些特性,今天就不记录了,如果能搞了解一下编译器是如何实现虚函数和虚继承,它们在类的内 ...

  4. span标签可以使用hide()方法隐藏吗?

    /获取li下的span var $span = $('ul.selector li span'); //span对象隐藏 $span.hide(); //或者 $span.css('display', ...

  5. 14.5.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量

    14.5.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量 改变InnoDB redo ...

  6. Python -- 堆数据结构 heapq - I love this game! - 博客频道 - CSDN.NET

    Python -- 堆数据结构 heapq - I love this game! - 博客频道 - CSDN.NET Python -- 堆数据结构 heapq 分类: Python 2012-09 ...

  7. ORALCE 之LRU链与脏LRU链【转载】

    今天是2013-09-09,时别n久的一篇经典文章,有被我在google发现了,再次转载一下.学习一下. 一.LRU链: 任何缓存的大小都是有限制的,并且总不如被缓存的数据多.就像Buffer cac ...

  8. Modular Fibonacci

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=30506#problem/U fib数列对2^m取模的循环节为3*(2^(m-1)) #i ...

  9. 高逼格UI-ASD(Android Support Design)

    绪 今年的Google IO给我们android开发着带来了三样非常屌非常屌的library: ASD(Android Support Design) APL(Android Percent Layo ...

  10. [poj 2991]Crane[线段树表示向量之和,而非数量]

    题意: 起重机的机械臂, 由n段组成, 对某一些连接点进行旋转, 询问每次操作后的末端坐标. 思路: 由于旋转会影响到该点之后所有线段的角度, 因此容易想到用线段树记录角度, 成段更新. (但是不是每 ...