[ 참고 및 주의 사항 ]
여기에 정리된 내용은 원문을 기준으로 여러 가지 테스트와 문제점의 검토 및 해결책을 찾으면서 나름대로 정리한 내용으로 오역과 잘 못 이해하고 정리한 부분이 있을 수 있습니다.
ZooKeeper 란?
ZooKeeper는 분산 어플리케이션들에 대한 분산 조정 서비스를 제공하는 프로그램으로 표준 파일 시스템과 유사하게 구성되어 공유된 계층적 공간을 통해서 분산된 프로세스들이 서로 조정할 수 있는 기능을 관리한다. 공유되는 공간은 ZooKeepr의 용어로 zNodes라고 불리는 데이터 등록의 집합으로 구성 되어 있으며 이 구조는 폴더들과 파일들의 구성과 유사하다. 파일 시스템과는 달리 ZooKeeper는 자바로 실행되며 자바와 C에 대한 바인딩을 가지고 있다.
ZooKeeper Cluster 기본 구성
ZooKeeper Service 는 “Ensemble” 이라고 불리는 Host 들의 집합들을 통해서 복제되며, 동일한 어플리케이션을 구성하는 서버들의 복제된 그룹을 “Quorum” 이라고 부른다. Quorum 내의 모든 서버는 동일한 설정 파일들의 복제본을 가지고 있다.
ZooKepper의 서버 구성의 수는 절반이 실패해도 기능을 수행할 수 있도록 항상 홀수로 구성하는 것을 권장한다. 예를 들어 2대의 서버가 장애 상태가 되어도 나머지 서버들이 동작할 수 있도록 5대의 서버로 구성하는 것이다. 이 중에 한 대는 Leader가 된다. 최소한의 구성은 3 대가 된다.
ZooKeeper 구성할 때 검토할 부분
ZooKeeper를 구성하기 위해서는 최소한 아래에 언급한 내용들에 대한 검토가 선행이 되어야 한다. 그리고 ZooKeeper Cluster의 구성은 아래의 그림과 같이 기본적으로 Leader를 포함하는 홀 수의 서버 구성이 되어야 한다.
여기서는 샘플을 테스트하는 것을 기준으로 검토를 진행하도록 한다.
- ZooKeeper 서버 구성의 수는 어떻게 할 것인가? - 위에서 언급한 것과 같이 홀수를 기준으로 구성하며, 테스트 환경이므로 3대의 서버로 구성한다.
- 물리적인 서버의 수는 어떻게 할 것인가? - 물리적인 장애가 발생하는 경우를 대비해서 가능하면 물리적으로 존재하는 서버로 구성하는 것이 좋다. 그러나 테스트이므로 단일 서버를 사용하도록 한다.
- 운영을 위한 포트의 구성은 어떻게 할 것인가? - 별도의 서버로 존재하면 Port를 크게 신경쓰지 않아도 되지만 테스트를 위해서 단일 서버에 구성하는 것이기 때문에 아래와 같이 구성한다.
- Client Port 는? - 클러스터에서 운영할 어플리케이션에 ZooKeeper로 접속하기 위한 포트를 의미한다.
- Qourum Port 는? - 클러스터내의 ZooKeeper 서버간에 통신을 위한 포트를 의미한다.
- Leader election Port 는? - 클러스터내의 ZooKeeper 서버간에 Leader를 선출하기 위한 통신 포트를 의미한다.
Notes
샘플 구성을 위해서 3개의 ZooKeeper 서버를 단일 장비에서 운영한다면 아래와 같이 포트 구성을 조정해 주어야 한다.
Server ID |
Client Port |
Quorum Port |
Leader Election Port |
1 |
2181 |
2888 |
3888 |
2 |
2182 |
2889 |
3889 |
3 |
2183 |
2890 |
3890 |
- ZooKeeper 서버의 dataDir 경로는? - “D:\ZooKepper\data” 와 같이 고정된 경로를 사용하여 데이터 구성을 위한 기본 폴더로 사용한다. 이 경로를 설정하는 것은 ZooKeeper의 성능과도 연결되므로 성능관련 고려사항을 검토하도록 한다.
- ZooKeeper 서버의 dataLogDir 경로는? - “D:\ZooKeeper\logs” 와 같이 고정된 경로를 사용하여 Log 구성을 위한 기본 폴더로 사용한다. 이 경로를 설정하는 것은 ZooKeeper의 성능과도 연결되므로 성능관련 고려사항을 검토하도록 한다.
- ZooKeeper에 대한 메모리 설정은? - 테스트를 위한 것이라면 기본 Heap size를 사용해도 상관없다. 그러나 실제 운영을 위한 것이라면 ZooKeeper 설치 경로의 “/conf/java.env” 파일을 생성해서 관련된 메모리 설정을 조정해 주어야 한다. 이런 설정은 ZooKeeper의 성능과도 연결되므로 성능관련 고려사항을 검토하도록 한다.
Notes
{ZooKeeper_HOME}\conf\java.env 파일을 생성하고 다음과 같이 설정해 주면 된다. (Heap Max size 설정으로 크기는 상황에 맞게 지정하면 된다)
export JVMFLAGS=”-Xmx2048m”
ZooKeeper Multiple Server 구성하기
샘플 테스트를 위한 ZooKeeper 서버들을 구성하도록 한다.
- ZooKeeper 서버 운영을 위한 기본 폴더 구조를 작성한다.
Root 폴더는 “D:\ZooKeeper” 로 한다.
각 서버는 다음과 같이 3개의 폴더로 구성한다.
D:\ZooKeeper\zk-server1
D:\ZooKeeper\zk-server2
D:\ZooKeeper\zk-server3
각 서버별 데이터 관리를 위한 폴더를 “data” 폴더 밑으로 구성한다.
D:\ZooKeeper/data/zk1
D:\ZooKeeper/data/zk2
D:\ZooKeeper/data/zk3
각 서버별 Log 관리를 위한 폴더를 “logs” 폴더 밑으로 구성한다.
D:\ZooKeeper/logs/zk1
D:\ZooKeeper/logs/zk2
D:\ZooKeeper/logs/zk3
- 이제 각 서버별로 식별할 수 있는 ID 를 지정하기 위해서 위에서 설정한 “data” 폴더의 각 서버 밑에 “myid” 라는 파일을 생성하고 (ex. D:\ZooKeeper\data\zk1\myid) 파일의 내용에 서버를 식별할 수 있는 ID 값 (zk1 은 1, zk2 는 2, zk3 는 3) 으로 설정한다.
- 다운로드 해 놓은 ZooKeeper 3.4.6 폴더에서 전부를 복사해도 되고, 필수적인 폴더들 (bin, conf, lib) 과 필요한 jar (zookeeper-3.4.6.jar) 파일을 각 서버 (zk1, zk2, zk3) 폴더에 복사해 넣는다.
- ZooKeeper 서버를 구동할 수 있는 환경 설정을 각 서버별로 구성한다. 복사한 서버(ex. zk1) 폴더의 conf 에 보면 zoo-sample.cfg 파일이 존재하므로 이를 복사해서 zoo.cfg 파일을 생성한다.
- zk1 서버 폴더의 conf 에 zoo-sample.cfg 파일이 존재한다. 이 파일을 복사하여 zoo.cfg 파일을 생성한다.
- 파일의 내용 중에서 해당 서버와 연결되는 항목인 clientPort, dataDir, dataLogDir 정보를 위에서 설정한 폴더 구조에 맞도록 설정한다. 물론 포트도 역시 위에서 정리한 서버 별 포트 내용에 맞도록 설정한다.
Notes
zk1 서버에 zoo.cfg 는 다음과 같이 구성되어야 한다.
tickTime=2000
initLimit=10
syncLimit=5
dataDir=D:\\ZooKeeper\\data\\zk1
clientPort=2181
dataLogDir=D:\\ZooKeeper\\logs\\zk1
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890
>
- 위에서 구성한 Log 폴더를 이용하기 위해서는 각 ZooKeeper 서버의 bin 폴더에 존재하는 zkEnv 파일에서 “ZOO_LOG_DIR” 을 수정해 주면 된다. (Log 설정을 위한 정보는 conf 폴더에 log4j.properties 파일이 존재하며, bin 폴더의 zkServer 스크립트 파일에서 Log와 관련된 정보를 사용한다)
...
set ZOOCFGDIR=%~dp0%..\conf
set ZOO_LOG_DIR=%~dp0%..\..\logs\zk1
set ZOO_LOG4J_PROP=INFO,ROLLINGFILE
...
- 구동을 위한 설정이 준비되었으므로 각 ZooKeeper 서버를 구동하면 된다. 각 서버의 bin 폴더에서 zkServer.cmd 를 실행하면 된다.
Notes
zk-server1 을 실행하면 Log 상에 2번과 3번 서버로의 통신이 실패했다는 Log를 볼 수 있다. zk-server2 를 실행하면 3 번 서버로의 통신이 실패했다는 Log를 볼 수 있다. 1번과 2번이 실행되었으므로 1번과 2번 모두 3번과 연결할 수 없다는 Log를 확인할 수 있다. 마지막으로 zk-server3 을 실행하면 연결이 모두 되어 동작하는 것을 확인할 수 있다.
zkServer.sh 스크립트는 다양한 명령을 제공한다.
- start
- start-foreground
- stop
- restart
- status
- upgrade
- print-cmd
그러나 Windows 에서 사용할 zkServer.cmd 파일은 배포된 버전에서는 위와 같은 명령을 제공하지 않는다. 따라서 “zkServer.cmd start” 라고 실행하면 오류가 발생한다. 따라서 zsServer.cmd 만을 실행하면 ZooKeeper 서버가 실행된다. zkServer.cmd 와 명령이 제공되는 버전은 여기서 받으면 된다. 그러나 역시 start 는 되지만 stop 은 오류가 발생할 수 있으며, 정상 동작하는 경우에 전체 ZooKeeper 서버를 모두 종료 시킨다. 한다.
ZooKeeper CLI Client 사용법
ZooKeeper CLI 는 Command Line 으로 ZooKeeper를 관리할 수 있는 도구로
“How to connect ZooKeeper through CLI?” 와
“Famous Four letter commands” 를 참조하면 된다.
ZooKeeper Cluster를 어플리케이션에서 사용하는 방법
ZooKeeper Cluster 를 이용할 어플리케이션은 ZooKeeper Cluster 구성 후에는 바로 연결할 수 있다. 이 때 필요한 정보는 다음과 같다.
- ZooKeeper Server 의 Host Address / Host IP
- ZooKeeper Server 의 Client Access Port No
현재 작업 중인 부분이 SolrCloud 이기 때문에 이에 대한 사용 방법은
“ZooKeeper 와 SolrCloud를 Tomcat7 에 설정해 보기” 를 참고하도록 한다.
기본적인 유지 관리 부분
별다른 작업이 필요한 것은 아니고 다음과 같은 정보를 정리하면 된다.
ZooKeeper는 “autopurge.snapRetainCount” 와 “autopurge.purgeInterval” 과 같은 설정을 통해서 자동으로 정리하는 기능 (Autopurge) 을 제공하고 있다. 그러나 실제 ZooKeeper 관리 방법은 IT 조직의 운영 방침과 요구에 따라서 달라지므로
“ZooKeeper maintenance” 를 참고하여 적절한 방침과 방법을 수립하면 된다.
성능과 가용성에 대한 검토 사항들
- Ensemble 을 구성하는 서버들의 대부분이 가동되면 ZooKeeper 서비스를 이용할 수 있다. 위에서도 계속 언급을 했지만 절반이 실패하더라도 구성이 가능할 수 있도록 홀 수를 유지하는 것이 중요하다. 예를 들어 짝수로 구성된 4개의 서버 중에서 2개의 서버가 실패하면 나머지 2개의 서버 중에서 1개의 서버는 리더가 되고 1개의 서버가 복제 상태가 되는데 이런 경우는 복제가 실패했을 때 대응을 할 수 없는 상태가 된다. 여기서 리더는 복제 단위가 아니기 때문에 1개 서버 만으로 복제를 운영할 수 없는 상태가 된다.
- ZooKeeper는 오류가 발생하면 프로세스가 종료되는 Fail-Fast 정책으로 운영된다. 따라서 자동으로 복원을 하는 것이 아니기 때문에 관리자의 감독하에서 실행하는 것이 상당히 중요하다. 자세한 내용은 여기를 참고하면 된다.
- ZooKeeper의 데이터 디렉토리는 Emsemble 에서 처리되는 zNodes 들의 정보 복사본들이 저장된다. 이 파일들은 Snapshot 파일들로 zNodes 들에서 처리된 변경들을 트랜잭션 로드로 추가하며, 때때로 Log들이 커지게 되면 모든 zNode 들의 현재 상태의 Snapshot 들을 파일 시스템에 기록하고 기존의 Log들을 대체한다.
- ZooKeeper의 Transaction Log는 전용 장치에 존재해야 하며, 파티션으로 처리된 전용 공간으로는 충분하지 않다고 명시되어 있다. 즉 ZooKeeper는 Log를 순차적으로 기록하며, 다른 프로세스들과 탐색이 경합이 발생할 수 있는 Log 장치의 공유를 허용하지 않는 것을 원칙으로 해야 한다.
- ZooKeeper 을 Swap이 발생할 수 있는 상황으로 관리하면 안 된다. ZooKeeper가 기능을 제대로 발휘할 수 있도록 하기 위해서는 Swap 발생을 미리 차단해 놓아야 한다. 예를 들어 ZooKeeper가 사용할 수 있는 Heap Size를 물리적인 사용 가능 메모리보다 크게 지정하면 나중에 메모리 Swap이 발생하므로 이런 설정은 피해야 한다. 이와 같은 피해야 할 부분들은 여기를 참고하면 된다.
댓글
댓글 쓰기