java 在zookeeper中创建路径的最有效方法,其中路径的根元素可能存在也可能不存在?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9898837/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Most efficient way to create a path in zookeeper where root elements of the path may or may not exist?
提问by marathon
Imagine a path "/root/child1/child2/child3"
想象一个路径“/root/child1/child2/child3”
Imagine in zookeeper that maybe a part of this exists, say "/root/child1"
想象一下在zookeeper中可能存在其中的一部分,比如“/root/child1”
There is no equivalent of "mkdir -p" in zookeeper; Also, ZooKeeper.multi() will fail if any one operation fails, so a "make path" couldn't really be baked into a multi call. Additionally, you could have some other client trying to make the same path...
zookeeper 中没有“mkdir -p”的等价物;此外,如果任何一个操作失败,ZooKeeper.multi() 都会失败,因此“创建路径”不能真正融入多调用中。此外,您可能会让其他一些客户端尝试使用相同的路径...
This is what I have come up with for creating a path. I wonder if it is even worth checking to see if a part exists or not, to save the round trip of the exists() call.
这就是我想出的创建路径的方法。我想知道是否值得检查部件是否存在,以节省exists() 调用的往返行程。
//String[] pathParts new String[] { "root", "child1", "child2", "child3" };
public void savePath(String[] pathParts) {
if (zooKeeper.exists(pathString, false) != null) return;
StringBuilder path = new StringBuilder();
for (String pathElement : pathParts) {
path.append(UNIX_FILE_SEPARATOR).append(pathElement);
String pathString = path.toString();
try {
//bother with the exists call or not?
if (zooKeeper.exists(pathString, false) == null) {
zooKeeper.create(pathString, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
} catch (KeeperException e) {
if (e.code() != KeeperException.Code.NODEEXISTS)
throw e;
}
}
}
What would be the most efficient way to do this? Assuming that a) you don't know ahead of time how much of the path already exists and b) some other client might be trying to write the same path (and we want to avoid locking).
什么是最有效的方法来做到这一点?假设 a) 您事先不知道路径中已经存在多少路径,并且 b) 其他一些客户端可能正在尝试编写相同的路径(并且我们希望避免锁定)。
采纳答案by sbridges
An exist call can be made with 1 round trip from the server to the client.
可以通过从服务器到客户端的 1 次往返来进行存在调用。
A create call has the same round trip, but create is a write operation that entails a couple more round trips between the servers in the zk cluster, so a create is a little more expensive that an exist.
create 调用具有相同的往返行程,但 create 是一个写操作,需要在 zk 集群中的服务器之间进行更多的往返行程,因此 create 比存在的要贵一些。
So the total time for your algorithm is,
所以你的算法的总时间是,
Time for 1 read op * Probability node already exists + (Time for 1 write op) * (1 - Probability the node already exists).
1 次读取操作的时间 * 概率节点已经存在 +(1 次写入操作的时间)*(1 - 节点已经存在的概率)。
So either of if(!exist()) create()
vs create()
could be faster. In the end it probably doesn't matter.
所以if(!exist()) create()
vs中的任何一个create()
都可以更快。到头来大概也无所谓了。
If you want to be really fast, you can use the async api so that you can create all the components of your path without waiting for the server to respond to requests 1 by 1.
如果你想真的很快,你可以使用 async api,这样你就可以创建路径的所有组件,而无需等待服务器一一响应请求。
final AtomicBoolean success = new AtomicBoolean(false);
final CountdownLatch latch = new CountdownLatch(1);
StringCallback cb = new StringCallback() {
processResult(int rc, String path, Object ctx, String name) {
if(name.equals(pathString ) {
//wait for the last path
success.set(rc == KeeperException.Code.NODEEXISTS ||
rc == KeeperException.Code.OK);
latch.countDown();
}
}
};
StringBuilder path = new StringBuilder();
for (String pathElement : pathParts) {
path.append(UNIX_FILE_SEPARATOR).append(pathElement);
String pathString = path.toString();
//send requests to create all parts of the path without waiting for the
//results of previous calls to return
zooKeeper.create(pathString, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, cb);
}
latch.await();
if(!success.get()) {
throw ...
}
回答by Arnon Rotem-Gal-Oz
You can use Netflix's curatorlibrary which makes using zookeeper much simpler
您可以使用Netflix 的策展人库,这使得使用 Zookeeper 变得更加简单
client.create().withMode(CreateMode.PERSISTENT).forPath("/root/child1/child2/child3", new byte[0]).withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE).creatingParentsIfNeeded();