Algorithm Technical

[Algorithm] Zookeeper의 이해

zookeeper 이미지 검색결과

시작하며…

Zookeeper는 어디선가 많이 들어본 용어였다. 하지만 Zookeeper가 어떠한 역할을 하는지 정확히 인지하지 않고 서버의 한 종류 라고만 생각하고 넘어갔던 나였다. 그런데 길드 모임 중 Zookeeper 알고리즘에 대한 주제가 나오게 되었고 Zookeeper에 대해 보다 자세히 알아 볼 기회인거 같아 공부하게 되었다.

Zookeeper란

Zookeeper는 Apache 재단의 오픈소스 프로젝트 중 하나이다.

왜 이름이 zookeeper인지 궁금했다. 찾아보니 사육사의 의미 그대로 사용된것이었다. Apache에선 프로젝트를 주로 동물 이름으로 표현하는데 이러한 프로젝트를 관리한다는 뜻으로 zookeeper로 정해졌다고 한다. 너무 단순하게 정해진 이름 같아서 놀랐다. 이런걸 보면서 때론 어렵게 생각하는 것보다 단순하게 생각하는 것이 더 좋을 때가 있구나 싶다.

zookeeper에 대한 의미도 알아보았으니, 이제 zookeeper가 무엇이고 무슨 역할을 하는지 분석해보고자 한다.

과거에는 한 대의 컴퓨터에서 동작하는 단일 프로그램이 주를 이루었지만 현재는 클라우드 환경에서 대규모의 시스템들이 동작는 구성으로 변화하고 있다. 이러한 변화에 대규모의 시스템을 조율하는 서버가 필요하게 되었고 이런 문제를 해결해줄 수 있는 솔루션인 zookeeper가 제공되었던 것이다.

일단 크게 Zookeeper가 대규모 시스템 서버들을 조율해주는 역할임을 알았으니 다음 단락에서 구조는 어떻게 되는지 알아보자.

Zookeeper Architecture

아래는 zookeeper의 Architecture 자료이다.

zookeeper architecture 이미지 검색결과

하나의 시스템에는 다수의 서버들이 존재할 것이고 다수의 사용자도 존재할 것이다. Zookeeper는 다수의 서버 중 하나의 서버에게 특정 역할을 맡기기 위해 특별히 Leader 서버로 선정한다. 그 이외의 서버는 Follower서버로써 역할을 수행하며, 이러한 Leader와 Follower로 나눠지는 구조를 Master-Slave 아키텍처를 기반이라고 한다. 서버들간의 동기화를 위해 Leader서버의 명령을 Follower서버에게 내리는 구조이다.

하나의 클러스터에서 사용되는 서버들을 묶어 앙상블(Ensemble)로 명칭한다. 그리고 쿼럼(Quorum)이라는 용어가 나오게 되는데 이 쿼럼이 Zookeeper 알고리즘에서 중요한 역할을 수행한다. 쿼럼(Quorum)이란 앙상블 데이터의 불일치를 방지해주는 역할을 수행한다. 일단은 이렇게 개념을 잡고 아래에서 보다 자세한 내용을 다루고자 한다.(사실 이 쿼럼에 대해 정확한 개념을 잡는 것에 오랜 시간이 소요됐다. Jay님의 도움 덕분에 개념을 확실히 잡을 수 있었다. 이게 길드의 힘인가?)

이러한 주키퍼 시스템에 클라이언트는 앙상블에 속한 서버에 연결하여 서비스를 사용하게 된다.

ZAB Algorithm

Zookeeper은 ZAB Algorithm 기반으로 동작한다고 한다. ZAB의 뜻은 Zookeeper Atomic Broadcast protocol이다. 여기서 추측 가능한 것은 ‘Zookeeper 서버간 전송을 broadcast방식으로 하는구나’이다. 그런데 Atomic은 왜 붙었을까라는 궁금증이 생겼다. 그래서 알아보았다. Atomic에 대해서… 위키백과에서 해답을 얻을 수 있었다.

an atomic broadcast or total order broadcast is a broadcast where all correct processes in a system of multiple processes receive the same set of messages in the same order;

broadcast 방식 중에 하나가 atomic broadcast인 것이었다. 위키백과에서 설명하는 내용을 해석해 보자면 멀티 프로세스 시스템에서 모든 프로세스는 동일한 순서로 동일한 메시지를 받는다는 의미이다.

그럼 이제 ZAB에 대해 본격적으로 분석해 보자. 분산 시스템을 구축할 때, 모든 노드가 독립적으로 돌아가는 시스템을 설계한 것이 아니라면, 공유된 상태를 합의하기 위한 방법이 필요하다고 한다. 왜냐면 서로 다른 클라이언트는 서로 다른 서버를 바라보지만 데이터는 모든 서버가 동일해야하기 때문이다. 분산 환경에서 상태를 공유하는 알고리즘을 consensus algorithm(합의 알고리즘)이라고 한다. consensus algorithm 중에서 가장 유명한 대표적 알고리즘은 Paxos이다. 하지만 Paxos는 복잡하고 Paxos를 구현한 라이브러리가 거의 없기에 비교적 쉬운 Zab algorithm을 사용하는 것이 Zookeeper이다.

ZAB 알고리즘이 트랜잭션에 대한 순서를 부여하고 합의 알고리즘을 통해 데이터 분산 처리를 한다는 것을 이해하였다. 그럼 어떻게 순서를 부여하고 합의 알고리즘은 어떻게 진행되는 것인지 알아보자.

Quorum & Majority

위에서 언급했듯이 쿼럼이 Zookeeper 알고리즘에 큰 역할을 수행한다. 그렇기에 쿼럼에 대해 자세히 알아볼 필요가 있다.

쿼럼은 앙상블을 이루고 있는 서버 중 과반수 서버로 이루어진다.

n/2 + 1 (n: 서버갯수)

서버의 개수를 n개라고 했을 때 쿼럼의 수는 n/2 + 1개인 과반수(Majority)로 지정한다. 그리고 최소 서버의 수가 3대이어야 한다고 한다. 왜냐면 서버가 2대일 때는 과반수인 쿼럼이 2대가 되고 이는 앙상블과 같은 수가 되기 때문이다.

쿼럼은 반드시 가동되고 있어야하며 클라이언트의 요청을 처리하는 최소한의 서버 노드이며, 쿼럼의 노드들은 클라이언트의 트랜잭션이 반영된 상태를 유지한다. 이 말은 쿼럼을 구성 못할 시 Zookeeper는 동작하지 못한다는 뜻을 의미한다.

이때, 과반수(Majority)의 서버로 쿼럼을 지정하는 이유는 예상치 못한 장애가 발생해도 분산 시스템의 일관성을 유지시키기 위함이다. 쿼럼의 서버 중 장애가 발생할 시 쿼럼이 아닌 나머지 서버들로 쿼럼을 구성하지 못하기에 주키퍼는 이용 불가 상태가 되고 클라이언트에게 알려 장애를 알릴 수 있는 것이다.

예를 들어 5개의 서버로 이루어진 앙상블을 이루는 주키퍼가 있다고 할 때 과반수가 아닌 2대의 서버를 쿼럼으로 지정하고 작업(트랜잭션A) 도중 에러가 발생할 경우 쿼럼이 아닌 나머지 3대의 서버 중 2대의 서버가 쿼럼을 이룰 수 있게 되어 다음 작업(트랜잭션B)을 정상적으로 처리하게 된다. 이렇게 되면 장애가 발생했던 작업(트랜잭션A)는 유실되는 상황이 발생하게 된다. 하지만 과반수인 3대의 서버를 쿼럼으로 지정할 경우 작업도중 장애가 발생하면 쿼럼이 아닌 나머지 2대의 서버가 쿼럼 구성을 할 수 없기 때문에 다음 작업을 할 수 없게 되고 장애를 인식하여 클라이언트에게 알리게 되는 것이다.

아래 자료는 쿼럼의 수행 흐름도이다.

Screen Shot 2015-11-20 at 1.56.51 PM
  1. 클라이언트가 서버에게 Request하면 이를 받게된 서버는 Leader 서버에게 알린다.
  2. 이후 Leader서버는 쿼럼을 구성하고 있는 Follower서버들에게 Propose 요청하고 해당 트랜잭션을 수행해도 된다고 확인된 쿼럼 서버들은 Ack로 Leader에게 응답한다.
  3. 쿼럼의 모든 Ack를 받은 Leader 서버는 해당 Request를 수행해도 된다고 판단하여 모든 Follow 서버에게 해당 트랜잭션을 처리해라는 명령을 broadcast 한다.

이를 통해 모든 서버가 모든 트랜잭션을 처리한 동일한 최신 정보를 소유하게 되는 것이고 모든 클라이언트는 동일한 최신 데이터를 바라볼 수 있는 것이다.

하지만 여기서 문제가 발생할 수 있다. 그 문제는 어떠한 다른 트랜잭션이 동시 또는 비슷한 시기에 발생 되었을 때 하나의 트랜잭션이 충돌 및 유실되는 경우가 발생될 수 있기 때문이다. 먼저 결론을 말하자면 주키퍼는 이러한 문제도 자동을 해결해 준다. 어떻게 해결해 주는지는 다음에서 알아보자.

Broadcast Problem

해당 문제는 트랜잭션에 대한 순서를 정하게 되면 모두 해결된다. 트랜잭션에 대한 순서를 매기고 FIFO(선입선출 : 먼저들어온 트랜잭션을 먼저 처리) 순서로 처리를 하면 트랜잭션에 대한 유실 걱정없이 모든 처리가 가능하게 된다.

img

예들들어 먼저, 트랜잭션 A가 하나의 서버에 의해 트랜잭션 B보다 먼저 커밋되면 트랜잭션 A는 모든 서버에 의해 트랜잭션 B보다 먼저 commit 된다. 트랜잭션 A와 트랜잭션 B가 커밋 된 메시지 인 경우 트랜잭션 A가 트랜잭션 B보다 먼저 커밋되거나 트랜잭션 B가 트랜잭션 A보다 먼저 커밋함으로써 트랜잭션에 대한 충돌 문제를 해결하는 것이다. 즉, 처리 요청을 받은 트랜잭션의 번호(예시 4번)와 처리 완료된 트랜잭션 번호(예시 2번) 사이가 비었을 경우(예시 3번) 해당 트랜잭션 처리 요청이 올 때 까지 기다린 후 순서대로 처리(예시 3번 처리 후 4번 처리)하여 유실을 방지한다.

Broadcast VS Multicast

이제 Zookeeper에 대한 이해가 모두 된거 같다. 여기서 하나의 궁금증이 생겼다. 그렇다면 Zookeeper가 나오기 전엔 어떻게 분산 시스템을 구축하였을까?

바로 멀티캐스트를 활용하여 분산시스템을 구축하였다. 먼저, 멀티캐스트와 브로트캐스트의 정의를 알아보자.

Broadcast

통신의 대상이 특정한 한 네트워크가 아니라 네트워크 안의 모든 장비들에게 통신을 하는 방식.

Multicast

보내고자 하는 정보를 그룹 내의 일정 네트워크 장비들에게만 한번에 보낼 수 있는 통신 방식.

멀티캐스트은 일반적으로 UDP를 사용한다. 정해진 채널에 데이터를 일괄적으로 전송하는 것이기 때문에, TCP의 특성인 데이터 재전송등의 기능이 없다. 정보를 보낸다는 신호나 받는다는 신호 절차를 거치지 않고, 보내는 쪽에서 일방적으로 데이터를 전달하는 프로토콜이다. 멀티캐스트는 브로드캐스트 방식과 달리 로컬네트워크의 경계인 라우터를 통과해서 패킷을 전송하는 제약을 갖고 있어 멀티캐스트에서 브로트캐스트 방식으로 분산 시스템을 구축으로 변화한 것이다.

마무리

zookeeper가 대표적으로 사용된 시스템으로는 Naver Line과 Arcus가 있다. 이중 Arcus는 메모리 캐시 클라우드이다. Arcus는 데이터베이스의 앞단에 위치하여 데이터를 캐싱하여, 서비스 응용에게 빠른 응답성을 제공하고 데이터베이스의 부하를 감소시키는 역할을 수행한다. 여기서 Zookeeper는 클라이언트와 캐시 클라우드 사이에서 분산 환경을 구축하는 역할을 수행한다.

정리하자면 한 마디로 Zookeeper는 안정적이고 가용성 높은 분산 데이터 시스템을 제공하는 클러스터 서버이며, 대규모 클라우드 시스템으로 변화하고 있는 현재에 필수적인 서버 시스템이다. Zookeeper에 대한 관심과 완벽한 이해를 바탕으로 대규모 서비스에서 분산 시스템을 구축하기 위한 용도로 활용하기 위한 노력을 지속적으로 해야 된다고 생각한다.

참고사이트

댓글 남기기

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.

%d 블로거가 이것을 좋아합니다: