2010-07-27 100 views
4

我拉进ZooKeeper一些并发管理一个项目,我想的第一件事是什么,对我而言,是很明显的(使用zkpython绑定):我可以递归地在Zookeeper中创建一个路径吗?

zh = zookeeper.init('localhost:2181') 
zookeeper.create(zh, '/path/to/a/node', '', [ZOO_OPEN_ACL_UNSAFE]) 

而且我得到了一回NoNodeException因为我的麻烦。

经过反思和审查文档(如他们)后,我一直无法找到一种方法来做相当于mkdir -p ZooKeeper将为我创建丢失的父节点。

我是否缺少任何东西,还是我坚持为每个部分的路径发出单独的create()s,无论我喜欢与否?

+0

我在哪里可以找到ZOO_OPEN_ACL_UNSAFE? – xitrium 2011-03-23 22:16:03

回答

7

您被困于为路径的每个元素分别发出create()。 Zookeeper只有内建的原子操作。递归地创建一个路径不再是原子操作。如果操作在创建一半路径元素之后挂起,则Zookeeper无法知道您希望如何操作。 我不知道,如果Python中已经有一个Zookeeper助手库。在java(zkClient)中有一个可以让你通过多次调用create()来创建递归路径。

+0

到目前为止,我发现Zookeeper的唯一Python接口是Zookeeper树中的一个(它只是基本绑定到核心API),所以我想我会编写自己的便捷方法。 :) 谢谢! – 2010-07-27 16:28:17

2

如果您发出单独的create(),则在半途中可能会中断或失败。要使呼叫原子化,可以使用新的multi() API。请参阅this answer

如果路径或其中的一部分可能已经存在,那么在发出下一个命令之前等待每个create()完成将会不必要地缓慢。在这种情况下,您可以使用异步API来加速进程。见this answer

如果你只是想避免额外的电话,你可以使用Netflix's curator库有一个creatingParentsIfNeeded方法,但请注意,它可能会很慢。见this answer

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> 
相关问题