ZooKeeper 란?

Computer/BigData 2016. 8. 28. 14:26
반응형

빅데이터 기술들을 접하다 보면 ZooKeeper에 대하여 꼭 나오게 된다. 

이번 포스팅에서는 ZooKeeper에 대해서 정리해 본다.


1. ZooKeeper 개요

 ZooKeeper는 분산 시스템을 위한 코디네이터이다. 


 "분산 시스템"이란 복수의 컴퓨터가 네트워크를 통해 통신하며 하나의 목적을 위해 서로 간에 상호작용하는 것이다. 다수의 컴퓨터가 마치 하나인 것처럼 동작하는 시스템인 것이다.

 분산 시스템을 구성할때 고려해야 할 사항들은 네트워크의 신뢰성, 지연, 대역폭, 안전성, 토폴로지에 대한 고려, 전송 비용, 네트워크 유형 등 고려해야 할 사항이 많다. 분산 서버들 간의 정보 공유, 동기화 분산 서버들의 상태 확인등이 필요하다.

 분산 컴퓨팅에서 코디네이션의 예는 그룹 멤버십(Group Membership), 잠금제어(Locking), 공급/구독 (Publisher/ Subscriber), 리더선정(Leader Election), 동기화(Synchronization)등이 될 수 있다.


  ZooKeeper는 클러스터 구성원 간의 데이터 공유를 위한 데이터 스토리지(영속 데이터/임시 데이터), 클러스터 멤버십 관리를 통한 데이터 변경 통지(Watch), 마스터 및 분산 락 등에 활용되는 시퀀스 노드 등을 제공한다. 이를 통해서 다음에 활용할 수 있다.

 1) 설정 관리 (Configuration Management)

 2) 분산 클러스터 관리 (Distributed Cluster Management)

 3) 명명 서비스 (Naming Service: e.g. DNS)

 4) 분산 동기화 (Distributed Synchronization : locks, barriers, queues)

 5) 분산 시스템에서 리더 선출 (Leader election in a distributed system)

 6) 중앙집중형 신뢰성 있는 데이터 저장소 (Centralized and highly reliable data registry)


 ZooKeeper는 중앙화된 분산 코디네이터 클러스터라고 볼 수 있다.


2. ZooKeeper 구성

 ZooKeeper는 n개의 서버로 단일 주키퍼 클러스터를 구성하며 이를 서버 앙상블이라고 한다. 클라이언트는 앙상블에 속한 서버에 연결하여 서비스를 사용할 수 있다. 다음은 주키퍼 아키텍처이다.

- zookeeper 서비스는 복수의 서버에 복제되며, 모든 서버는 데이터 카피본을 저장하고 있다

- 리더는 구동 시 zookeeper 내부 알고리즘에 의해 자동 선정된다

- Followers 서버들은 클라이언트로부터 받은 모든 업데이트 이벤트를 리더에게 전달한다.

- 클라이언트는 모든 주키퍼 서버에서 읽을 수 있으며, 리더를 통해 쓸 수 있고 과반수 서버의 승인(합의)가 필요하다.


3. ZooKeeper 데이터 모델

 주키퍼는 계층적인 namespace를 제공하며 namespace 내에 존재하는 개별 노드를 znode 라고 부른다. 모든 znode는 데이터(바이트 배열)을 가질 수 있으며 자식 znode를 가질 수 있다.


1) znode

 절대 경로로 '/'로 구분된다. 상대 참조가 없으며 명칭에 유니코드 문자가 포함될 수 있다. 변경이 발생하면 버전 번호가 증가한다. 데이터는 항상 전체를 읽고 쓴다.  znode는1M 이하의 데이터를 가질 수 있으며, 자식 노드를 가질 수 있다.


 영속 종류에 따라 

 1) Persistent Nodes(영구 노드): 명시적으로 샂게되기 전까지 존재함

 2) Ephemeral Nodes(임시 노드): 세션이 유지되는 동안 활성(세션이 종료되면 삭제됨), 자식 노드를 가질 수 없음

 3) Sequence Nodes(순차 노드) : 경로의 끝에 일정하게 증가하는 카운터 추가됨, 영구 및 임시 노드 모두에 적용 가능


 Sequence Node의 경우 자식 노드가 생성한 순서에 따라 일렬번호를 가진다. 예를 들어 /svc 노드의 자식 노드로 /nodes를 시퀀스 노드로 생성하면 다음과 같은 순서로 노드를 생성한다.

/svc/nodes0000000001

/svc/nodes0000000002

 Persistent와 Ephemeral 에 보두 적용 가능하며 시퀀스 번호는 4byte 정수이다.


2) operations

주요 operation은 create, delete, exists, getChildren, getData, setData 등이 있다. 그리고 Java, C, Python, Ruby, Scala 등 언어별 바인딩을 제공한다.


3) watch

Znode가 변경 시 Noti를 클라이언트로 trigger 해주어, 주키퍼의 znode의 변화를 통지 받는다. 오퍼레이션 실행시 watcher 등록 (zk.getChildren("/mysvc/nodes",watcher)

이벤트 종류는 다음과 같다.

- 노드의 자식이 변경된 경우(NodeChildrenChanged)

- 노드가 생성된 경우 (NodeCreated)

- 노드의 데이터가 변경된 경우 (NodeDataChanged)

- 노드가 삭제된 경우(NodeDeleted)

 Watch는 일회성 이벤트 수신으로, 다시 Watch 하고 싶으면 재등록 해야 하며, 재등록 전에 발생한 변경은 수신하지 못한다. 클라이언트는 이벤트 수신 및 새로운 감시 요청을 전송하는 중 발생할 수 있는 지연에 대비해야 한다. 상태 변경 요청한 클라이언트가 성공 코드를 받은 이후에, watcher를 등록한 클라이언트에 통지된다. ZooKeeper의 변경 순서대로 Watch 이벤트를 수신한다.


4) 일관성 보장

 - Sequential Consistency: 변경 요청은 순서대로 적용

 - Atomicity : 변경은 확실히 성공 또는 실패

 - Single System Image : 클라이언트는 연결한 서버에 상관 없이 동일 서비스(View 조회) 사용

 - Reliability : 변경은 적용된 이후에 동일한 클라이언트에게 의해 덮어써지기 전까지는 지속(유지) 된다. 클라이언트가 성공 코드를 받으면, 서버에 반영됨을 보장

 - Timeliness : 클라이언트는 일정 시간내에 최신 상태를 사용(Eventual Consistency)



4. ZooKeeper 사용 예

1) 클러스터 관리

 - 그룹 멤버십 목록을 가질 부모  znode를 생성(예: /members)

 - 부모 znode에 자신을 위한 자식  znode를 ephemeral로 생성 (예: /members/m-hostip

 - 자식 znode 데이터는 다른 구성원이 자신과 통신하는데 필요한 정보 저장(예: IP/Port)

 - 또는 주기적으로 상태를 변경(load, memory, CPU etc.)

 - 탈퇴하고자 할 경우 자신에 해당하는  znode를 삭제

 - 멤버십 목록, 주기적 갱신(각 클라이언트) - 주기적으로 getChildren 실행해서 목록 갱신

 - 멤버십 목록,  Watch 이용(각 클라이언트) - 부모 znode에 getChildren 로 WATCH 등록하고 getChildren 결과로 목록 갱신

 - NodeChildrenChanged 이벤트 수신 시, 위 과정 재실행


2) 리더 선출

 - 마스터 후보 등록: 부모 znode에 자신을 위한 자식 znode를 시퀀스 & ephemeral 로 생성 (예: /masters/m-0000000010)

 - 마스터 선출

 . 부모 znode에 getChild로 WATCH 등록

 . NodeChildrenChanged 이벤트 수신시, 현재 마스터가 없는지 확인

 . 마스터에 해당 자식 znode가 없으면 부모 znode에 자식 znode를 구한뒤 시퀀스 번호가 가장 작은 znode를 마스터로 선택

.부모 znode에 getChild로 WATCH 등록


3) 분산 배타적 잠금

 - N개의 클라이언트가 잠금(lock)을 소유하려고 시도한다고 가정

 - 클라이언트들을 임시, 순차znode를 /cluster/locknode에 생성

 - 클라이언트들은 잠금 znode 하위의 자식 리스트를 요청한다

 - 가장 낮은 ID를 가진 클라이언트가 잠금을 소유한다.

 - 그 외의 클라이언트들은 감시(WATCH)를 수행한다.

 - 통지가 발생할 떄마다 잠금을 확인한다.

 - 잠금을 해제하고 싶은 클라이언트는 노드를 삭제하고 다음 클라이언트가 잠금을 획득하게 된다.


4) 기타 용도

 이벤트 통지: WATCH 사용

 pub/sub : SEQUENCE사용

 분산카운터: SEQUENCE 또는 znode의 version 사용


5. 기타

1) ZooKeeper의 동작방식

- zxid : zookeeper transaction ID : 모든 변경은 고유 트랜잭션 ID를 가짐, 순서를 가짐

- version : znode가 변경될 때마다 버전 값 증가

- cversion : 자식 znode가 변경될 때 마다 버전 값 증가


2) Quorum : 가용성, 데이터 변경

 - 과반 정족수 이상 서버 다운시, 서비스 중지 (예를 들어 2대중 1대 다운되면 서비스 중지, 이런 이유로 서버 개수는 홀수로 맞춤 3,5등)

 - 데이터 변경시 성공 기준 : 리더 서버가 트랜잭션 생성 후 다른 서버에 전파할 때, 과반 정족수 이상 트랜잭션 성공하면 클라이언트에 변경 성공 결과 리턴


6. ZooKeeper 설치하기

다음의 노드 3대를 가정하고 zookeeper를 설치해 보도록 하겠다.

192.168.0.100 nn

192.168.0.101 d1

192.168.0.102 d2


먼저 zookeeper를 다운로드 하고 압축을 푼다. 본 예제에서는 /usr/local 밑에 설치한다고 가정한다. 다음처럼 환경 설정을 해준다.

export ZOOKEEPER_HOME=/usr/local/zookeeper-3.4.8

export PATH=$PATH:$ZOOKEEPER_HOME/bin


/user/local/zookeeper-3.4.8/conf/zoo.cfg 를 다음으로 설정한다. 

1. dataDir을 생성하고 설정해준다.

2. server.X 를 설정하는데, 이때 X는 dataDir의 myid 에 지정된 값이 되어야 한다.

- 192.168.0.100 에서 echo "1" > /usr/local/data/zookeeper/myid

- 192.168.0.101 에서 echo "2" > /usr/local/data/zookeeper/myid

- 192.168.0.102 에서 echo "3" > /usr/local/data/zookeeper/myid

# The number of milliseconds of each tick

tickTime=2000

# The number of ticks that the initial

# synchronization phase can take

initLimit=10

# The number of ticks that can pass between

# sending a request and getting an acknowledgement

syncLimit=5

# the directory where the snapshot is stored.

# do not use /tmp for storage, /tmp here is just

# example sakes.

dataDir=/usr/local/data/zookeeper

# the port at which the clients will connect

clientPort=2181

# the maximum number of client connections.

# increase this if you need to handle more clients

#maxClientCnxns=60

#

# Be sure to read the maintenance section of the

# administrator guide before turning on autopurge.

#

# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance

#

# The number of snapshots to retain in dataDir

#autopurge.snapRetainCount=3

# Purge task interval in hours

# Set to "0" to disable auto purge feature

#autopurge.purgeInterval=1

server.1=nn:2888:3888

server.2=d1:2888:3888

server.3=d2:2888:3888


 1번 서버부터 차례대로 zkServer.sh start 로 zookeeper 데몬을 실행한다. jps를 했을 때 QuorumPeerMain 가 실행되고 있어야 한다.

반응형
Posted by alias
,