ZooKeeper 멀티 서버 구성
· Version : Zookeeper
주키퍼를 멀티서버로 구성하려면 각 서버에 멀티서버에 대한 정보를 추가해야 한다. 주피커 설치 디렉터리에서 conf/zoo.cfg 파일에 아래와 같이 정보를 입력 한다.
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/zookeeper clientPort=2181
server.1=192.168.1.1:2888:3888 server.2=192.168.1.2:2888:3888 server.3=192.168.1.3:2888:3888 |
zoo.cfg 파일에서 서버 수 만큼 server.x=IP:Port:Port 를 입력한다. server는 예약어이며, x는 서버를 식별하는 ID로 숫자를 입력한다. IP는 각 서버의 IP를 입력하고, 첫번째 포트는 리더에 접속하기 위한 포트이며, 두번째 포트는 리더를 선출하는데 사용되는 포트이다. 위에서 생성한 설정 파일을 각 서버에 복사하고, 각 서버의 데이터 디렉터리에 myid 라는 파일을 만들어서 해당 서버의 아이디를 입력한다. 아래 예제는 서버1에서 데이터 경로가 /data/zookeeper 를 사용하였다.
vi /data/zookeeper/myid 1 #숫자 입력 후 종료 |
설정이 완료되고 각 서버에서 주키퍼 서버를 시작하면, 멀티서버 주키퍼 클러스터로 동작한다. 멀티서버 구성에는 실행되고 있는 서버의 수가 과반수(등록된 서버 수 + 1)/2) 이하이면 동작하지 않는다. 예를들어 클러스터가 3대일때, 2대의 서버 장애가 발생하면 서비스가 중지 된다. 아래 스크립트는 주키퍼 서버를 시작하는 명령어이다.
bin/zkServer.sh start |
각 서버에서 주키퍼를 시작하면 첫번째 서버 시작시 오류 메시지가 나타나는데, 멀티서버로 설정된 주키퍼는 설정 파일에 있는 다른 서버에 접속해 리더 선출과정을 거쳐야 정상으로 작동되기 때문에 설정 파일에 등록된다른 서버를 시작하면 경고가 발생하지 않는다. 서버 메시지에서 “LEADING” 메시지가 표시된 서버가 리더로 선출된 서버이다.
아래 표는 주키퍼 환경 설정에 대한 속성과 설명이다.
속성 |
설명 |
clientPort |
클라이언트로 요청을 받기 위한 포트 |
dataDir |
메모리에 있는 데이터를 스냡샷으로 저장하는 디렉터리 경로 |
tickTime |
주키퍼에서 사용되는 기본 시간 단위. 최소 세션타임아웃은 이 값의 2배이다. |
dataLogDir |
트랜잭션 로그를 저장하는 디렉터리. 특별한 설정을 하지 않으면 dataDir에 저장. 성능상 다른 디스크의 디렉터리에 분리하는것이 좋다. |
globalOutstandingLimit |
큐가 많이 쌓이게 되면 메모리 부족으로 정상 작동하지 못하게 된다. 큐 사이즈보다 더 많은 요청을 받지 못하도록 설정하는 값이며 기본값은 1000 이다. |
preAllocSize |
트랜잭션 로그 저장을 위해 미리 할당 받은 파일 사이즈. 기본값은 64MB로 스냅샷을 자주 만들경우 이 값을 줄여서 사용한다. |
snapCount |
트랜잭션 회수가 snapCount 값 이상되면 메모리 내용을 스냅샷 파일로 저장하고 새로운 트랜잭션 파일을 만든다. |
traceFile |
이 설정이 켜져 있으면 클라이언트 요청을 traceFile.year.month.day 형태의 파일명에 저장한다. 주로 디버그 용도로 활용하며 설정이 켜져 있으면 오버헤드가 발생한다. |
maxClientCnxns |
클라이언트로 부터 동시에 접속할 수 있는 연결 수를 지정. 연결수는 클라이언트 IP당 개수이며, 기본값은 10이며 0은 무제한이다. |
clientPortBindAddress |
서버의 네트워 카드 및 IP가 여러개 일때, 클라이언트가 접속할 서버의 IP주소나 호스트명을 지정한다. 기본값은 모든 IP 주소, 네트워크 카드에 접속 가능하다. |
minSessionTimeout |
최소 세션 타임아웃이며 단위는 밀리세컨드 (ms)이다. 기본값은 tickTime *2 이다. |
maxSessionTimeout |
최대 세션 타임아웃이며 단위는 밀리세컨드(ms)이다. 기본값은 tickTime *20 이다. |
electionAlg |
리더를 선출하는 알고리즘. 기본값은 3이다. 1 : UDP 기반의 비인증 빠른 리더 선출(FastLeaderElection) 2 : UDP 기반의 인증 빠른 리더 선출 3 : TCP 기반의 빠른 리더 선출 |
initLimit |
초기에 팔로워가 리더에 접속하거나 데이터를 동기화 시키기 위한 시간으로 단위는 tickTime 이며 initLimit * tickTime으로 계산된다. |
leaderServes |
클라이언트의 요청을 리더가 받을 것인지에 대한 설정 기본값은 yes 이다. 쓰기 연산이 많은 경우, 리더가 클라이언트 요청을 받게되면 쓰기 연산에 대한 처리와 클라이언트로 부터의 읽기,쓰기 연산을 동시에 하게 되면서 많은 오버헤드가 발생한다. 이 경우 no로 설정하는 것이 좋다. |
server.x=ip:port:port |
멀티 서버를 구성할 경우 서버 목록 지정. 앞의 포트는 리더에 접속하기 위한 포트이며, 두 번째는 리더를 선출하는 포트이다. |
syncLimit |
Sync를 수행하는 시간으로 Tick기준이다. 이 시간동안 sync가 안되면 해당 팔로워는 클러스터에서 제외된다. |
group.x=id[:id] |
계층적 정족수를 설정한다 x는 그룹 아이디로 숫자 값을 설정한다. = 이후에는 그룹에 포함될 서버 아이디를 입력하며 구분자는 : 이다. |
weight.x= n |
서버간 정족수 투표를 할때 서버의 가중치를 설정. X는 서버 아이디이며 n은 가중치 값을 설정한다. 기본값은 1이다. |
주키퍼는 자바로 개발되었으며 JVM(Java Virtual Machine)환경에서 운영된다. 그래서 JVM에 대한 설정도 고려해야한다. JVM은 GC(Garbage Collection)을 수행할때 모든 스레드가 멈추게 되는 경우도 있다. GC가 수행되는 모든 모든 스레드가 동작하지 못하게 되면 예기치 못한 타임아웃이 발생하고, 클라이언트, 서버 모두 정상적인 상황임에도 세션을 유지하지 못하는 상태가 발생한다. 주키퍼 서버를 실행할 때 GC옵션을 아래와 같이 설정하며 GC가 수행중에도 스레드가 동작할 수 있게 한다.
-XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC |
이 외에도 성능이 저하되지 않도록 JVM 힙 메모리 스왑이 발생하지 않도록 해야한다.
[참고자료]
· Clustered (Multi-Server) Setup : https://zookeeper.apache.org/doc/r3.3.2/zookeeperAdmin.html#sc_zkMulitServerSetup
· How To Install and Configure an Apache ZooKeeper Cluster on Ubuntu 18.04 : https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-an-apache-zookeeper-cluster-on-ubuntu-18-04
· 16 Tuning JVM Garbage Collection for Production Deployments : https://docs.oracle.com/cd/E40972_01/doc.70/e40973/cnf_jvmgc.htm#autoId0
2020-05-16 / Sungwook Kang / http://sungwookkang.com
Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, 주키퍼, Zookeeper, 분산 코디네이션
'SW Engineering > Hadoop' 카테고리의 다른 글
Hive에서 쉘 명령 실행 (0) | 2020.05.18 |
---|---|
ZooKeeper 클라이언트 요청 처리 (0) | 2020.05.18 |
ZooKeeper 리더선출과 데이터 ACID 정책 (0) | 2020.05.14 |
Zookeeper 세션(Session) (0) | 2020.05.13 |
Zookeeper 접근제한(Access Control List) (0) | 2020.05.11 |