[ZooKeeper] (2) zookeeper server는 어떠게 구성되는가?

ensemble

테스트 환경이나 개발 환경에서는 stand-alone mode를 이용하여 한 대의 ZooKeeper 서버만을 실행하여 사용할 수 있지만, 이렇게 되면 ZooKeeper의 큰 장점인 availability를 크게 해치게 된다. 그래서 실제 배포 환경에서는 보통 최소 3대의 ZooKeeper 서버를 cluster로 묶어서 배포하는 것이 일반적이다. 이때 ZooKeeper cluster를 ensemble이라고 부른다.

같은 ZooKeeper ensemble에 포함된 서버는 모두 같은 data를 저장함으로써 특정 서버가 SPOF(Single Point Of Failure)가 되는 일을 막는다. 그렇다면 분산 된 환경에서 모든 서버에 같은 data가 저장되는 것을 어떻게 보장해줄 수 있을까?

Leader

ZooKeeper ensemble에는 외부에는 공개되지 않지만, 내부적으로 사용되는 leader가 있다. client는 ensemble에 포함된 어떤 서버에게도 query를 날릴 수 있다. 서버는 query를 받으면 이 query를 ensemble의 leader에게 전달해 주고, leader가 모든 서버에 같은 data가 저장되는 것을 보장해 준다.

Two phase commit

ZooKeeper는 모든 follower가 leader와 같은 data를 가지고 있는 것을 보장하기 위하여 간략화된 two phase commit을 사용한다. leader는 request에 대해서 follower에 해당하는 server들에게 propose message를 보낸다. propose message를 받은 follower는 해당 proposal에 대해서 local disk에 commit log를 저장하고 ack message를 보낸다.

leader는 Follower로부터 받은 ack이 quorum(보통은 n/2 + 1이다.)을 넘으면 모든 Follower들에게 Commit을 날린다. Commit을 받으면 zookeeper는 commit log에 저장되어 있던 커밋을 실행하여 znode를 갱신한다. Follower들은 이후 자신에게 들어오는 read 요청에 대하여 request가 반영된 값을 보여준다. 이 순간 ZooKeeper 서버들은 각각 다른 값을 가지고 있을 수 있고, 이 때문에 ZooKeeper는 eventual consistency만을 보장한다고 한다.

https://zookeeper.apache.org/doc/r3.4.6/zookeeperInternals.html#sc_activeMessaging를 수정.
지금 document에 올라가 있는 그림은 틀렸다. 왼쪽 아래에 있는 commit의 방향이 반대로 되어 있다.

일반적인 two phase coommit과는 다르게 propose에 대해서 agree/abort 하거나 commit/rollback을 하고 그 결과에 대해서 받는 과정이 없이 언제나 성공할 것으로 생각하고 ack을 기다린다. 이때 leader는 보내는 모든 proposal에 대해 자신이 받은 순서대로 transaction id를 매겨서 처리하기 때문에 sequential consistency를 보장할 수 있다.

Leader election

이렇게 leader를 통해서 consistency와 동기화가 보장된다면 leader가 또 다른 SPOF가 되는 것은 아닐까 하는 의문이 든다. ZooKeeper는 leader가 또 다른 SPOF가 되는 것을 막기 위하여, leader에 문제가 생겼을 때, 내부적으로 leader를 선출하는 mechanism을 가지고 있다. ZooKeeper의 leader election mechanism에 대해서는 다음에 설명하도록 하겠다.


댓글

이 블로그의 인기 게시물

[C++] enum class - 안전하고 쓰기 쉬운 enum

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

RAII는 무엇인가

[Python] cache 데코레이터로 최적화하기

[Web] SpeechSynthesis - TTS API