分散式 ZooKeeper 快取用法例項教程
ZooKeeper是一個分散式的,開放原始碼的分散式應用程式協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要元件。
可以利用ZooKeeper在叢集的各個節點之間快取資料。 每個節點都可以得到最新的快取的資料。 Curator提供了三種型別的快取方式:Path Cache,Node Cache 和Tree Cache。
Path Cache
Path Cache用來監控一個ZNode的子節點. 當一個子節點增加, 更新,刪除時, Path Cache會改變它的狀態, 會包含最新的子節點, 子節點的資料和狀態。 這也正如它的名字表示的那樣, 那監控path。
實際使用時會涉及到四個類:
PathChildrenCache
PathChildrenCacheEvent
PathChildrenCacheListener
ChildData
通過下面的建構函式建立Path Cache:
public PathChildrenCache(CuratorFramework client, String path, boolean cacheData)
想使用cache,必須呼叫它的start方法,不用之後呼叫close方法。 start有兩個, 其中一個可以傳入StartMode,用來為初始的cache設定暖場方式(warm):
NORMAL: 初始時為空。
BUILD_INITIAL_CACHE: 在這個方法返回之前呼叫rebuild()。
POST_INITIALIZED_EVENT: 當Cache初始化資料後傳送一個PathChildrenCacheEvent.Type#INITIALIZED事件
public void addListener(PathChildrenCacheListener listener)可以增加listener監聽快取的改變。
getCurrentData()方法返回一個List<ChildData>物件,可以遍歷所有的子節點。
這個例子摘自官方的例子, 實現了一個控制檯的方式操作快取。 它提供了三個命令, 你可以在控制檯中輸入。
set 用來新增或者更新一個子節點的值, 也就是更新一個快取物件
remove 是刪除一個快取物件
list 列出所有的快取物件
另外還提供了一個help命令提供幫助。
設定/更新、移除其實是使用client (CuratorFramework)來操作, 不通過PathChildrenCache操作:
client.setData().forPath(path, bytes);
client.create().creatingParentsIfNeeded().forPath(path, bytes);
client.delete().forPath(path);
而查詢快取使用下面的方法:
for (ChildData data : cache.getCurrentData()) {
System.out.println(data.getPath() + " = " + new String(data.getData()));
}
Node Cache
Path Cache用來監控一個ZNode. 當節點的資料修改或者刪除時,Node Cache能更新它的狀態包含最新的改變。
涉及到下面的三個類:
NodeCache
NodeCacheListener
ChildData
想使用cache,依然要呼叫它的start方法,不用之後呼叫close方法。
getCurrentData()將得到節點當前的狀態,通過它的狀態可以得到當前的值。 可以使用public void addListener(NodeCacheListener listener)監控節點狀態的改變。
我們依然使用上面的例子框架來演示Node Cache。
package com.colobu.zkrecipe.cache;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingServer;
import org.apache.curator.utils.CloseableUtils;
import org.apache.zookeeper.KeeperException;
public class NodeCacheExample {
private static final String PATH = "/example/nodeCache";
public static void main(String[] args) throws Exception {
TestingServer server = new TestingServer();
CuratorFramework client = null;
NodeCache cache = null;
try {
client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(1000, 3));
client.start();
cache = new NodeCache(client, PATH);
cache.start();
processCommands(client, cache);
} finally {
CloseableUtils.closeQuietly(cache);
CloseableUtils.closeQuietly(client);
CloseableUtils.closeQuietly(server);
}
}
private static void addListener(final NodeCache cache) {
// a PathChildrenCacheListener is optional. Here, it's used just to log
// changes
NodeCacheListener listener = new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
if (cache.getCurrentData() != null)
System.out.println("Node changed: " + cache.getCurrentData().getPath() + ", value: " + new String(cache.getCurrentData().getData()));
}
};
cache.getListenable().addListener(listener);
}
private static void processCommands(CuratorFramework client, NodeCache cache) throws Exception {
printHelp();
try {
addListener(cache);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
boolean done = false;
while (!done) {
System.out.print("> ");
String line = in.readLine();
if (line == null) {
break;
}
String command = line.trim();
String[] parts = command.split("s");
if (parts.length == 0) {
continue;
}
String operation = parts[0];
String args[] = Arrays.copyOfRange(parts, 1, parts.length);
if (operation.equalsIgnoreCase("help") || operation.equalsIgnoreCase("?")) {
printHelp();
} else if (operation.equalsIgnoreCase("q") || operation.equalsIgnoreCase("quit")) {
done = true;
} else if (operation.equals("set")) {
setValue(client, command, args);
} else if (operation.equals("remove")) {
remove(client);
} else if (operation.equals("show")) {
show(cache);
}
Thread.sleep(1000); // just to allow the console output to catch
// up
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
}
}
private static void show(NodeCache cache) {
if (cache.getCurrentData() != null)
System.out.println(cache.getCurrentData().getPath() + " = " + new String(cache.getCurrentData().getData()));
else
System.out.println("cache don't set a value");
}
private static void remove(CuratorFramework client) throws Exception {
try {
client.delete().forPath(PATH);
} catch (KeeperException.NoNodeException e) {
// ignore
}
}
private static void setValue(CuratorFramework client, String command, String[] args) throws Exception {
if (args.length != 1) {
System.err.println("syntax error (expected set <value>): " + command);
return;
}
byte[] bytes = args[0].getBytes();
try {
client.setData().forPath(PATH, bytes);
} catch (KeeperException.NoNodeException e) {
client.create().creatingParentsIfNeeded().forPath(PATH, bytes);
}
}
private static void printHelp() {
System.out.println("An example of using PathChildrenCache. This example is driven by entering commands at the prompt:n");
System.out.println("set <value>: Adds or updates a node with the given name");
System.out.println("remove: Deletes the node with the given name");
System.out.println("show: Display the node's value in the cache");
System.out.println("quit: Quit the example");
System.out.println();
}
}
操作和上面的Path cache類似, 只是getCurrentData()返回的型別不同
Tree Node
這種型別的即可以監控節點的狀態,還監控節點的子節點的狀態, 類似上面兩種cache的組合。 這也就是Tree的概念。 它監控整個樹中節點的狀態。 涉及到下面四個類。
TreeCache
TreeCacheListener
TreeCacheEvent
C(www.111cn.net)hildData
而關鍵的TreeCache的建構函式為
public TreeCache(CuratorFramework client, String path, boolean cacheData)
想使用cache,依然要呼叫它的start方法,不用之後呼叫close方法。
getCurrentChildren()返回cache的狀態,型別為Map<String, ChildData>。 而getCurrentData()返回監控的path的資料。
public void addListener(TreeCacheListener listener)可以增加listener來監控狀態的改變。
例子依然採用和上面的例子類似, 尤其和Path Cache類似。
package com.colobu.zkrecipe.cache;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Map;
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.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingServer;
import org.apache.curator.utils.CloseableUtils;
import org.apache.curator.utils.ZKPaths;
import org.apache.zookeeper.KeeperException;
public class TreeCacheExample {
private static final String PATH = "/example/treeCache";
public static void main(String[] args) throws Exception {
TestingServer server = new TestingServer();
CuratorFramework client = null;
TreeCache cache = null;
try {
client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(1000, 3));
client.start();
cache = new TreeCache(client, PATH);
cache.start();
processCommands(client, cache);
} finally {
CloseableUtils.closeQuietly(cache);
CloseableUtils.closeQuietly(client);
CloseableUtils.closeQuietly(server);
}
}
private static void addListener(final TreeCache cache) {
TreeCacheListener listener = new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
switch (event.getType()) {
case NODE_ADDED: {
System.out.println("TreeNode added: " + ZKPaths.getNodeFromPath(event.getData().getPath()) + ", value: "
+ new String(event.getData().getData()));
break;
}
case NODE_UPDATED: {
System.out.println("TreeNode changed: " + ZKPaths.getNodeFromPath(event.getData().getPath()) + ", value: "
+ new String(event.getData().getData()));
break;
}
case NODE_REMOVED: {
System.out.println("TreeNode removed: " + ZKPaths.getNodeFromPath(event.getData().getPath()));
break;
}
default:
System.out.println("Other event: " + event.getType().name());
}
}
};
cache.getListenable().addListener(listener);
}
private static void processCommands(CuratorFramework client, TreeCache cache) throws Exception {
// More scaffolding that does a simple command line processor
printHelp();
try {
addListener(cache);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
boolean done = false;
while (!done) {
System.out.print("> ");
String line = in.readLine();
if (line == null) {
break;
}
String command = line.trim();
String[] parts = command.split("s");
if (parts.length == 0) {
continue;
}
String operation = parts[0];
String args[] = Arrays.copyOfRange(parts, 1, parts.length);
if (operation.equalsIgnoreCase("help") || operation.equalsIgnoreCase("?")) {
printHelp();
} else if (operation.equalsIgnoreCase("q") || operation.equalsIgnoreCase("quit")) {
done = true;
} else if (operation.equals("set")) {
setValue(client, command, args);
} else if (operation.equals("remove")) {
remove(client, command, args);
} else if (operation.equals("list")) {
list(cache);
}
Thread.sleep(1000); // just to allow the console output to catch
// up
}
} finally {
}
}
private static void list(TreeCache cache) {
if (cache.getCurrentChildren(PATH).size() == 0) {
System.out.println("* empty *");
} else {
for (Map.Entry<String, ChildData> entry : cache.getCurrentChildren(PATH).entrySet()) {
System.out.println(entry.getKey() + " = " + new String(entry.getValue().getData()));
}
}
}
private static void remove(CuratorFramework client, String command, String[] args) throws Exception {
if (args.length != 1) {
System.err.println("syntax error (expected remove <path>): " + command);
return;
}
String name = args[0];
if (name.contains("/")) {
System.err.println("Invalid node name" + name);
return;
}
String path = ZKPaths.makePath(PATH, name);
try {
client.delete().forPath(path);
} catch (KeeperException.NoNodeException e) {
// ignore
}
}
private static void setValue(CuratorFramework client, String command, String[] args) throws Exception {
if (args.length != 2) {
System.err.println("syntax error (expected set <path> <value>): " + command);
return;
}
String name = args[0];
if (name.contains("/")) {
System.err.println("Invalid node name" + name);
return;
}
String path = ZKPaths.makePath(PATH, name);
byte[] bytes = args[1].getBytes();
try {
client.setData().forPath(path, bytes);
} catch (KeeperException.NoNodeException e) {
client.create().creatingParentsIfNeeded().forPath(path, bytes);
}
}
private static void printHelp() {
System.out.println("An example of using PathChildrenCache. This example is driven by entering commands at the prompt:n");
System.out.println("set <name> <value>: Adds or updates a node with the given name");
System.out.println("remove <name>: Deletes the node with the given name");
System.out.println("list: List the nodes/values in the cache");
System.out.println("quit: Quit the example");
System.out.println();
}
}
from:http://www.111cn.net/jsp/Java/78903.htm
相關文章
- 【zookeeper】zookeeper分散式鎖分散式
- 分散式-zookeeper分散式
- 分散式快取基礎教程分散式快取
- zookeeper分散式鎖分散式
- 4.5 zookeeper分散式分散式
- ZooKeeper 分散式鎖分散式
- 基於快取或zookeeper的分散式鎖實現快取分散式
- 十九、Redis分散式鎖、Zookeeper分散式鎖Redis分散式
- Zookeeper-分散式鎖分散式
- Zookeeper(5)---分散式鎖分散式
- zookeeper 分散式鎖解析分散式
- charAt()函式用法例項程式碼函式
- linux下grep命令用法例項教程Linux
- 分散式鎖的3種實現(資料庫、快取、Zookeeper)分散式資料庫快取
- .Net分散式快取應用例項:Couchbase分散式快取
- 分散式技術-Zookeeper概述分散式
- Zookeeper — 本地完全分散式 搭建分散式
- 分散式鎖之Zookeeper實現分散式
- 分散式鎖實現(二):Zookeeper分散式
- ZooKeeper分散式鎖的實現分散式
- 【分散式】Zookeeper應用場景分散式
- 6 zookeeper實現分散式鎖分散式
- Zookeeper簡介及分散式概念分散式
- 分散式快取分散式快取
- JS訪問SWF的函式用法例項JS函式
- ZooKeeper分散式專題(一) -- zookeeper安裝以及介紹分散式
- 分散式系列七: zookeeper簡單用法分散式
- 【分散式】Zookeeper的Leader選舉分散式
- ZooKeeper分散式任務排程中心分散式
- 搭建分散式系統的利器:ZooKeeper分散式
- 搞懂分散式技術3:初探分散式協調服務zookeeper分散式
- 分散式快取方案分散式快取
- redis→分散式快取Redis分散式快取
- 聊聊分散式快取分散式快取
- DCS分散式快取服務例項型別介紹分散式快取型別
- 一文帶你認識zookeeper並探究分散式鎖實現原理(附docker構建zookeeper教程)分散式Docker
- 分散式服務框架 Zookeeper -- 管理分散式環境中的資料分散式框架
- 簡直騷操作,ThreadLocal還能當快取用thread快取