복붙노트

[HADOOP] 경로의 루트 요소가 존재하거나 존재하지 않을 수있는 사육사에서 경로를 만드는 가장 효율적인 방법은 무엇입니까?

HADOOP

경로의 루트 요소가 존재하거나 존재하지 않을 수있는 사육사에서 경로를 만드는 가장 효율적인 방법은 무엇입니까?

"/ root / child1 / child2 / child3"경로를 상상해보십시오.

사육사를 상상해보십시오. 아마도 "/ root / child1"

사육사에는 "mkdir -p"와 동일한 기능이 없습니다. 또한 하나의 작업이 실패하면 ZooKeeper.multi ()가 실패하므로 "make path"가 실제로 다중 호출로 구워 질 수 없습니다. 또한, 다른 클라이언트가 동일한 경로를 만들려고 할 수 있습니다 ...

이것은 내가 길을 창조하기 위해 생각해 낸 것입니다. exist () 호출의 왕복을 저장하기 위해 부품이 존재하는지 여부를 확인하는 것이 가치가 있는지 궁금합니다.

//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;
        }
    }
}

이 작업을 수행하는 가장 효율적인 방법은 무엇입니까? a) 미리 경로가 얼마나 존재하는지 미리 알지 못한다고 가정하고 b) 다른 클라이언트가 동일한 경로를 작성하려 할 수 있습니다 (잠금을 피하기를 원합니다).

해결법

  1. ==============================

    1.서버에서 클라이언트로의 1 왕복으로 기존 호출을 수행 할 수 있습니다.

    서버에서 클라이언트로의 1 왕복으로 기존 호출을 수행 할 수 있습니다.

    create 호출은 동일한 왕복 시간을 가지지 만, create는 zk 클러스터의 서버 사이에 왕복이 두 번 더 발생하는 쓰기 작업이므로 create가 약간 더 비싸다.

    알고리즘의 총 시간은

    1 판독 시간 * 확률 노드가 이미 존재 + (1 쓰기 연산 시간) * (1- 확률 노드가 이미 존재 함).

    그래서 if (! exist ()) create () vs create ()가 더 빠를 수 있습니다. 결국 그것은 중요하지 않습니다.

    정말 빨라지려면 비동기 API를 사용하여 서버가 요청에 1 대 1로 응답 할 때까지 기다리지 않고 경로의 모든 구성 요소를 만들 수 있습니다.

    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 ...
    }
    
  2. ==============================

    2.사육사를 훨씬 더 간단하게 만드는 Netflix의 큐레이터 라이브러리를 사용할 수 있습니다.

    사육사를 훨씬 더 간단하게 만드는 Netflix의 큐레이터 라이브러리를 사용할 수 있습니다.

    client.create().withMode(CreateMode.PERSISTENT).forPath("/root/child1/child2/child3", new byte[0]).withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE).creatingParentsIfNeeded();
    
  3. from https://stackoverflow.com/questions/9898837/most-efficient-way-to-create-a-path-in-zookeeper-where-root-elements-of-the-path by cc-by-sa and MIT license