我正在将ZooKeeper拉进一个项目进行并发管理,我尝试的第一件事对我来说非常明显(使用zkpython绑定):
zh = zookeeper.init('localhost:2181')
zookeeper.create(zh, '/path/to/a/node', '', [ZOO_OPEN_ACL_UNSAFE])
我为我的麻烦找回了NoNodeException
。
在对此进行反思并查看文档(例如它们)之后,我一直无法找到相当于mkdir -p
的方法,其中ZooKeeper会为我创建缺少的父节点。< / p>
我是否遗漏了任何内容,或者我只是因为喜欢与否而在路径的每个部分发出单独的create()?
答案 0 :(得分:9)
你不得不为路径的每个元素发出单独的create()。 Zookeeper只构建了原子操作。递归创建路径不再是原子操作。如果在创建一半路径元素后操作挂起,Zookeeper无法知道您想要它做什么。 我不知道,如果python中已经有一个Zookeeper帮助程序库了。 java(zkClient)中有一个可以通过多次调用create()来创建递归路径。
答案 1 :(得分:2)
如果你发出单独的create(),你可能会在中途中断或失败。要使调用成为原子,您可以使用新的multi() API。请参阅this answer。
如果路径或其中的一部分可能已经存在,那么在发出下一个之前等待每个create()完成将会不必要地慢。在这种情况下,您可以使用异步API来加速该过程。请参阅this answer。
如果您只是想避免额外的调用,可以使用具有creatingParentsIfNeeded
方法的Netflix's curator库,但请注意它可能很慢。请参阅this answer。
答案 2 :(得分:0)
Kazoo has an ensure_path(path)
operation,虽然它不被认为是原子的。使用它至少可以节省编写自己的代码以进行递归创建的需要。
答案 3 :(得分:0)
<Code>
public void updateNode(String path, byte[] data, int version) {
try {
if (zk.exists(path, this) == `enter code here`null) {
createRecursivly(path);
}
zk.setData(path, data, version);
} catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void createRecursivly(String path){
try {
if (zk.exists(path, this) == null && path.length() > 0) {
String temp = path.substring(0, path.lastIndexOf("/"));
createRecursivly(temp);
zk.create(path, null, Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
}else{
return;
}
} catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
</code>