ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Zookeeper Ensemble 알아보기 (Leader Election, Sequential Znode)
    Hadoop 2023. 12. 19. 04:44
    728x90
    반응형

    - 목차

     

    소개.

    ZooKeeper Ensemble 에 대해서 알아보려고 합니다. 
    ZooKeeper 들로 구성된 하나의 클러스터이며, Leader-Follower 구성을 따릅니다. 
    하나의 Leader 가 존재하고, 나머지 ZooKeeper 서버들은 Follower 가 됩니다. 
    그래서 Leader 를 Replication 하죠. 
    Leader ZooKeeper 가 전적으로 Znode 의 Write, Update, Delete 요청을 책임지며,
    카프카나 하둡에 해당하는 클라이언트와 소통하게 됩니다. 

    그리고 ZooKeeper Ensemble 에서 Leader Election 또한 매우 중요한 부분인데요. 
    이 과정에서 사용되는 Sequential Znode 에 대해서도 알아보려고 합니다. 

     

     

    ZooKeeper Ensemble 이란?


    ZooKeeper Ensemble 은 ZooKeeper 들로 구성된 클러스터입니다. 
    Leader - Follower 구성을 따르며, Follower 들은 Leader 의 Replica 라고 생각하시면 됩니다. 
    어떠한 방식으로 Replication 이 되는지 알아보기 위해서 간단한 환경을 조성한 후 테스트를 진행하려고 합니다. 

    아래 도커 커맨드를 실행하여 ZooKeeper Ensemble 을 구현합니다.

    3개의 ZooKeeper Container 가 생성됩니다.

     

    < Create ZooKeeper Containers >

    docker run -d --name zookeeper1 \
    --network zookeeper \
    -e ZOOKEEPER_CLIENT_PORT=2181 \
    -e ZOOKEEPER_PEER_PORT=2888 \
    -e ZOOKEEPER_SERVER_PORT=3888 \
    -e ZOOKEEPER_SERVER_HOST=zookeeper1 \
    -e ZOOKEEPER_TICK_TIME=2000 \
    -e ZOOKEEPER_INIT_LIMIT=5 \
    -e ZOOKEEPER_SYNC_LIMIT=2 \
    -e ZOOKEEPER_SERVER_ID=1 \
    -e ZOOKEEPER_SERVERS="zookeeper1:2888:3888;zookeeper2:2888:3888;zookeeper3:2888:3888" \
    -p 2181:2181 confluentinc/cp-zookeeper:7.4.3
    
    docker run -d --name zookeeper2 \
    --network zookeeper \
    -e ZOOKEEPER_CLIENT_PORT=2181 \
    -e ZOOKEEPER_PEER_PORT=2888 \
    -e ZOOKEEPER_SERVER_PORT=3888 \
    -e ZOOKEEPER_SERVER_HOST=zookeeper2 \
    -e ZOOKEEPER_TICK_TIME=2000 \
    -e ZOOKEEPER_INIT_LIMIT=5 \
    -e ZOOKEEPER_SYNC_LIMIT=2 \
    -e ZOOKEEPER_SERVER_ID=2 \
    -e ZOOKEEPER_SERVERS="zookeeper1:2888:3888;zookeeper2:2888:3888;zookeeper3:2888:3888" \
    -p 2182:2181 confluentinc/cp-zookeeper:7.4.3
    
    docker run -d --name zookeeper3 \
    --network zookeeper \
    -e ZOOKEEPER_CLIENT_PORT=2181 \
    -e ZOOKEEPER_PEER_PORT=2888 \
    -e ZOOKEEPER_SERVER_PORT=3888 \
    -e ZOOKEEPER_SERVER_HOST=zookeeper3 \
    -e ZOOKEEPER_TICK_TIME=2000 \
    -e ZOOKEEPER_INIT_LIMIT=5 \
    -e ZOOKEEPER_SYNC_LIMIT=2 \
    -e ZOOKEEPER_SERVER_ID=3 \
    -e ZOOKEEPER_SERVERS="zookeeper1:2888:3888;zookeeper2:2888:3888;zookeeper3:2888:3888" \
    -p 2183:2181 confluentinc/cp-zookeeper:7.4.3

     

    아래와 같은 3개의 ZooKeeper Container 들이 생성됩니다.

     

    그리고 로그를 통해서 누가 Leader 인지, 누가 Follower 인지 확인할 수 있습니다.

    zookeeper3 이 현재 leading 중임을 알 수 있죠.

    docker logs zookeeper1 -t | grep "state changed" -m 1
    docker logs zookeeper2 -t | grep "state changed" -m 1
    docker logs zookeeper3 -t | grep "state changed" -m 1

     

    INFO Peer state changed: following (org.apache.zookeeper.server.quorum.QuorumPeer)
    INFO Peer state changed: following (org.apache.zookeeper.server.quorum.QuorumPeer)
    INFO Peer state changed: leading (org.apache.zookeeper.server.quorum.QuorumPeer)

     

    Leader 변경하기.

    Leader ZooKeeper 를 강제로 종료시켜 새로운 Leader 가 선출되는 과정을 살펴보겠습니다.

     

    < Stop Leader ZooKeeper >

    docker restart zookeeper3

     

    Leader 가 zookeeper2 서버로 변경됨을 알 수 있습니다.

    docker logs zookeeper1 --tail 30 | grep 'state changed' -m 1
    docker logs zookeeper2 --tail 40 | grep 'state changed' -m 1
    docker logs zookeeper3 --tail 40 | grep 'state changed' -m 1
    [2023-12-20 01:33:21,777] INFO Peer state changed: following - synchronization (org.apache.zookeeper.server.quorum.QuorumPeer)
    [2023-12-20 01:33:21,790] INFO Peer state changed: leading - broadcast (org.apache.zookeeper.server.quorum.QuorumPeer)
    [2023-12-20 01:34:32,117] INFO Peer state changed: following (org.apache.zookeeper.server.quorum.QuorumPeer)

     

     

    이러한 테스트를 반복적으로 진행하다보면 새롭게 Leader 가 선출되는 과정을 확인할 수 있습니다.

     

    Replication 확인하기.

    ZooKeeper 들이 서로 Sync 를 유지하는지 확인해보겠습니다.

    아래 명령어는 각각의 ZooKeeper 들의 Znode 의 상태를 확인하는 명령어입니다.

     

    < List Znode >

    zookeeper1, zookeeper2, zookeeper3 모두 동일한 Znode 구성을 가집니다.

    docker exec -it zookeeper1 zookeeper-shell zookeeper1:2181 ls -R /
    echo '========================='
    docker exec -it zookeeper2 zookeeper-shell zookeeper2:2181 ls -R /
    echo '========================='
    docker exec -it zookeeper3 zookeeper-shell zookeeper3:2181 ls -R /

     

    Connecting to zookeeper1:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /zookeeper
    /zookeeper/config
    /zookeeper/quota
    =========================
    Connecting to zookeeper2:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /zookeeper
    /zookeeper/config
    /zookeeper/quota
    =========================
    Connecting to zookeeper3:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /zookeeper
    /zookeeper/config
    /zookeeper/quota

     

    Leader ZooKeeper 를 통해서 Znode 를 하나 생성해보겠습니다.

    현재 Leader ZooKeeper 는 zookeeper 3 입니다.

     

    < Create Znode in zookeeper3 >

     docker exec -it zookeeper3 zookeeper-shell zookeeper3:2181 create /testnode 123

     

    Connecting to zookeeper3:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    Created /testnode

     

    그리고 ZooKeeper 들의 Znode 의 구성을 살펴보겠습니다.

    모두 /testnode 라는 Znode 가 생성됨을 알 수 있습니다.

     

    < List Znode >

    docker exec -it zookeeper1 zookeeper-shell zookeeper1:2181 ls -R /
    echo '========================='
    docker exec -it zookeeper2 zookeeper-shell zookeeper2:2181 ls -R /
    echo '========================='
    docker exec -it zookeeper3 zookeeper-shell zookeeper3:2181 ls -R /

     

    Connecting to zookeeper1:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /testnode
    /zookeeper
    /zookeeper/config
    /zookeeper/quota
    =========================
    Connecting to zookeeper2:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /testnode
    /zookeeper
    /zookeeper/config
    /zookeeper/quota
    =========================
    Connecting to zookeeper3:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /testnode
    /zookeeper
    /zookeeper/config
    /zookeeper/quota

     

    Catch-up Replication.

    ZooKeeper Ensemble 의 ZooKeeper 하나가 종료된 시간동안 Znode 의 변경사항들이 생겼다고 가정하겠습니다.

    그리고 종료되었던 ZooKeeper 가 재시작을 하게 되었을 때,

    지금까지 발생한 Transaction 들이 어떻게 Recovery 되는지 알아보려고 합니다.

     

    먼저 Follower ZooKeeper 하나를 종료해보겠습니다.

     

    < Stop ZooKeeper 1 >

    docker stop zookeeper1

     

    < Create Znode >

    docker exec -it zookeeper3 zookeeper-shell zookeeper3:2181 create /testnode/testchild2 123
    docker exec -it zookeeper3 zookeeper-shell zookeeper3:2181 create /testnode/testchild3 123
    docker exec -it zookeeper3 zookeeper-shell zookeeper3:2181 create /testnode/testchild4 123

     

    < List Znode >

    Leader ZooKeeper 와 Follower ZooKeeper 사이의 Replication 은 정상적으로 실행되었습니다.

    docker exec -it zookeeper2 zookeeper-shell zookeeper2:2181 ls -R /
    echo '========================='
    docker exec -it zookeeper3 zookeeper-shell zookeeper3:2181 ls -R /

     

    Connecting to zookeeper2:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /testnode
    /zookeeper
    /testnode/testchild2
    /testnode/testchild3
    /testnode/testchild4
    /zookeeper/config
    /zookeeper/quota
    =========================
    Connecting to zookeeper3:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /testnode
    /zookeeper
    /testnode/testchild2
    /testnode/testchild3
    /testnode/testchild4
    /zookeeper/config
    /zookeeper/quota

     

    이 상황에서 종료되었던 ZooKeeper1 를 재실행시켜보겠습니다.

    정상적으로 누락되었던 Replication 들이 복구됨을 알 수 있습니다.

     

    < Start ZooKeeper1 >

    docker start zookeeper1
    docker exec -it zookeeper1 zookeeper-shell zookeeper1:2181 ls -R /
    Connecting to zookeeper1:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /testnode
    /zookeeper
    /testnode/testchild2
    /testnode/testchild3
    /testnode/testchild4
    /zookeeper/config
    /zookeeper/quota

     

     

    Sequential Znode 란 ?

    Znode 는 데이터 저장의 관점에서 두가지 종류를 가집니다.

    각각 Persistent Znode 와 Ephemeral Znode 입니다.

    둘의 차이는 Znode 의 저장 기간인데요.

    Persistent Znode 는 영구적으로 저장되는 Znode 이고,

    Ephemeral Znode 는 클라이언트와의 세션이 종료되면 사라집니다.

    Sequential Znode 는 데이터 저장의 관점에서 다루는 Znode 는 아니구요.

    말그대로 Sequential 한 순서로 데이터를 저장할 수 있는 방식입니다.

     

    ZooKeeper 는 Ensemble 이라고하여 여러 ZooKeeper 가 모여서 하나의 클러스터를 이룹니다.

    이때, 반드시 Leader 과 Follower 의 구조를 취하죠.

    그리고 Leader Election 과정에서 Sequential Znode 를 사용하게 되는데요.

    Sequential Znode 가 어떻게 적용되는지 알아보려고 합니다.

     

    < Create Sequential Znode >

    Sequential Znode 를 생성합니다.

    각 ZooKeeper 를 대상으로 Sequential Znode 를 생성합니다.

    아래의 결과처럼 0 ~ 2 까지 순서대로 Znode 가 생성되는데요.

    Leader Election 시점에선 먼저 Znode 를 생성한 순서대로 Leader 로 선출될 수 있는 구조를 취합니다.

     

    docker exec -it zookeeper3 zookeeper-shell zookeeper3:2181 create /sequential
    
    docker exec -it zookeeper3 zookeeper-shell zookeeper3:2181 create -s /sequential/
    docker exec -it zookeeper1 zookeeper-shell zookeeper1:2181 create -s /sequential/
    docker exec -it zookeeper2 zookeeper-shell zookeeper2:2181 create -s /sequential/
    Connecting to zookeeper1:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /sequential
    /testnode
    /zookeeper
    /sequential/0000000000
    /sequential/0000000001
    /sequential/0000000002
    /testnode/testchild2
    /testnode/testchild3
    /testnode/testchild4
    /zookeeper/config
    /zookeeper/quota
    =========================
    Connecting to zookeeper2:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /sequential
    /testnode
    /zookeeper
    /sequential/0000000000
    /sequential/0000000001
    /sequential/0000000002
    /testnode/testchild2
    /testnode/testchild3
    /testnode/testchild4
    /zookeeper/config
    /zookeeper/quota
    =========================
    Connecting to zookeeper3:2181
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    /
    /sequential
    /testnode
    /zookeeper
    /sequential/0000000000
    /sequential/0000000001
    /sequential/0000000002
    /testnode/testchild2
    /testnode/testchild3
    /testnode/testchild4
    /zookeeper/config
    /zookeeper/quota

     

    반응형
Designed by Tistory.