Можно ли рекурсивно создать путь в Zookeeper? - PullRequest
4 голосов
/ 27 июля 2010

Я втягиваю ZooKeeper в проект для некоторого управления параллелизмом, и первое, что я попробовал, было то, что для меня было совершенно очевидно (с помощью привязки zkpython):

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

И я получил NoNodeException за мою проблему.

После размышлений над этим и просмотра документов (таких, как они есть) я не смог найти способ сделать эквивалентныйmkdir -p, где ZooKeeper создаст для меня недостающие родительские узлы.

Я что-то упускаю или просто застрял, выдавая отдельные create () для каждой части пути, нравится мне это или нет

Ответы [ 4 ]

9 голосов
/ 27 июля 2010

Вы застряли, чтобы выдавать отдельные create () для каждого элемента пути. В Zookeeper встроены только атомарные операции. Создание пути рекурсивно больше не является атомарной операцией. Zookeeper не может знать, что вы хотите от него делать, если операция зависает после создания половины элементов пути. Я не знаю, есть ли уже библиотека помощников Zookeeper в python. В java есть один (zkClient), который позволит вам создавать рекурсивные пути, вызывая create () несколько раз.

2 голосов
/ 22 мая 2012

Если вы запускаете отдельные create (), вы можете прерваться или потерпеть неудачу, когда пройдете половину пути.Чтобы сделать вызов атомарным, вы можете использовать новый multi () API .См. этот ответ .

Если путь или его часть уже могут существовать, то ожидание завершения каждого create () перед выпуском следующего будет излишне медленным.В этом случае вы можете использовать асинхронный API для ускорения процесса.См. этот ответ .

Если вы просто хотите избежать дополнительных вызовов, вы можете использовать библиотеку куратор Netflix, которая имеет метод creatingParentsIfNeeded, но имейте ввидуэто может быть медленно.См. этот ответ .

0 голосов
/ 16 декабря 2014
<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>
0 голосов
/ 25 февраля 2014

У Kazoo есть операция ensure_path(path) , хотя она не считается атомарной.Использование этого по крайней мере избавит вас от необходимости писать собственный код для рекурсивного создания.

...