ZooKeeper Clustering 설치
이번 포스팅에서는 ZooKeeper의 클러스터링을 위해 구축 할 예정입니다.
ZooKeeper은 싱글로도 충분히 동작 할 수 있지만, 개발용에나 쓰이지만, 상용에서는 클러스터링으로 사용됩니다.
또한 ZooKeeper은 분산 작업을 제어하기 때문에 ZooKeeper가 중단 될 경우 ZooKeeper에 의존하는 서비스는 영향을 받습니다.
이러한 이유로 ZooKeeper은 안정성이 보장되어야 하며, 여러 ZooKeeper를 클러스터링하여 고가용성을 제공 할 수 있습니다.
이것을 ZooKeeper 앙상블(Ensemble)이라고 합니다.
ZooKeeper의 앙상블은 과반수가 동작하면 사용이 가능하며 과반수를 필요하기 때문에 홀수 구성을 추천하고 있습니다.
예를 들자면, 3대에서 ZooKeeper를 구성 할 때 1대의 고장을 허용합니다.
· 시스템 정보
구성 : 서버 3대
OS : Centos 7.3.1611
ZooKeeper의 버전 : 3.4.9
Java 버전 : 1.8.0_121
· 요구 사항
- Java 1.7 or higher
· 설치
아래 설치는 https://zookeeper.apache.org/doc/r3.4.9/zookeeperAdmin.html#sc_zkMulitServerSetup 설치와 동일합니다.
또한, 최소 구성 및 설치로 진행됩니다.
1. Java JDK 설치.
일반적으로 OS 설치 시 Java가 기본적으로 설치가 되어있을 수도 있지만, 저 같은 경우에는 최소 설치로 직접 다운받아 설치해야합니다.
URL : http://java.sun.com/javase/downloads/index.jsp
현재 작성된 기준으로 최신 버전인 1.8.0_121 을 다운받아 RPM으로 설치합니다.
2. Java Heap Size 설정.
Swapping(스와핑)을 방지하는 것이 매우 중요하며 ZooKeeper의 성능을 심각하게 저하시킬 수 있습니다.
올바른 값을 설정하기 위해서는 Load Tests를 사용하고, Swap 할 수 있는 사용제한보다 훨씬 낮은지 확인해야합니다.
일반적으로 4GB의 Machine에서 최대 3GB를 Heap을 사용합니다.
하지만 이번 설치 포스팅에서는 Java Heap Size 설정은 생략합니다.
3. ZooKeeper 계정 생성.
일반적으로 모든 서비스는 보안을 위하여 Root가 아닌 일반 사용자 계정으로 생성하여 사용하면 좋습니다.
이 부분은 필수적이지 않지만, 습관하는 것이 중요합니다.
1 2 | $ useradd hdfs $ passwd hdfs | cs |
4. ZooKeeper Server 패키지 설치.
아래 명령어로 다운받을 수 있습니다. 현재 최신 버전이자 안정한 버전인 3.4.9 버전을 다운 받습니다.
1 2 | $ sudo wget http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.tar.gz $ tar xvfzp zookeeper-3.4.9.tar.gz | cs |
5. ZooKeeper Configuration
3대의 서버 호스트 네임은 s-seob-1, s-seob-2, s-seob-3 입니다.
1 2 3 4 5 6 7 8 9 10 11 | $ cd /home/hdfs/zookeeper-3.4.9/conf $ cp -rfp zoo_sample.cfg zoo.cfg $ vi zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/zookeeper/data clientPort=2181 server.1=s-seob-1:2888:3888 server.2=s-seob-2:2888:3888 server.3=s-seob-3:2888:3888 | cs |
Configuration Parameters에 대한 설명은 아래 URL에서 확인 할 수 있습니다.
URL : https://zookeeper.apache.org/doc/r3.4.9/zookeeperAdmin.html#sc_configuration
1 2 3 4 5 | $ mkdir -p /data/zookeeper/data $ cd /data/zookeeper/data $ touch myid $ echo <server.id> > myid $ chown hdfs:hdfs /data/zookeeper | cs |
모든 서버에서 다른 서버에 있는 ensemble을 알아야 합니다. 이 작업은 server.id=host:port:port 형식을 사용하면 됩니다.
또한, zoo.cfg 파일에 작성된 dataDir에 지정된 폴더에 각 서버마다 myid라는 파일을 작성하여 server.id 를 작성하면 됩니다.
6. myid 구성에 대한 자세한 설명.
myid 파일은 해당 머신의 ID 텍스트만 포함하여 단일 행으로 구성되어야 합니다. 따라서 s-seob-1 서버에서의 myid는 "1"만 포함하고 다른 것은 포함하지 않습니다.
ID는 ensemble에 고유하며 1에서 255까지 사용이 가능합니다.
구성에 예를 들자면 s-seob-1 서버에서는 /data/zookeeper/data/myid에 1이라는 값이 들어가있으면 되며, s-seob-2 서버에서는 myid에 2 라는 값이 들어가있으면 됩니다.
7. 시작
모든 구성 정보가 완료되었다면, ZooKeeper Server를 실행 할 수 있습니다.
1 2 | $ cd /home/hdfs/zookeeper-3.4.9/bin $ zkServer.sh start | cs |
· ZooKeeper 검증
정말 ZooKeeper가 정상적으로 동작하고 있는지 검증 할 차례 입니다. 검증 방법은 아래와 같으며 많은 유형이 있습니다.
- jsp Command를 활용한 검증
1 2 3 | $ jps 18407 QuorumPeerMain 18460 Jps | cs |
Java가 설치 되어있다면 jps 명령어를 사용 할 수 있습니다. 위와 같이 QuroumPeerMain 프로세스가 동작 중이라면 ZooKeeper가 동작 중입니다.
- netstat Tool을 활용한 검증
1 2 3 4 5 6 | $ netstat -naltop | grep -i listen tcp 0 0 0.0.0.0:2055 0.0.0.0:* LISTEN 24638/sshd off (0.00/0/0) tcp6 0 0 211.104.171.102:3888 :::* LISTEN 21594/java off (0.00/0/0) tcp6 0 0 :::40214 :::* LISTEN 21594/java off (0.00/0/0) tcp6 0 0 :::2181 :::* LISTEN 21594/java off (0.00/0/0) tcp6 0 0 :::2055 :::* LISTEN 24638/sshd off (0.00/0/0) | cs |
ZooKeeper의 포트인 2181, 3888이 LISTEN 상태인지를 확인 할 수 있습니다.
- ZooKeeper Cli를 활용한 검증.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | $ zkCli.sh -server 127.0.0.1:2181 Connecting to 127.0.0.1:2181 2017-02-16 23:07:04,036 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.9-1757313, built on 08/23/2016 06:50 GMT 2017-02-16 23:07:04,045 [myid:] - INFO [main:Environment@100] - Client environment:host.name=s-seob-1 2017-02-16 23:07:04,045 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_121 2017-02-16 23:07:04,050 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation 2017-02-16 23:07:04,051 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/usr/java/jdk1.8.0_121/jre 2017-02-16 23:07:04,051 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/home/hdfs/zookeeper-3.4.9/bin/../build/classes:/home/hdfs/zookeeper-3.4.9/bin/../build/lib/*.jar:/home/hdfs/zookeeper-3.4.9/bin/../lib/slf4j-log4j12-1.6.1.jar:/home/hdfs/zookeeper-3.4.9/bin/../lib/slf4j-api-1.6.1.jar:/home/hdfs/zookeeper-3.4.9/bin/../lib/netty-3.10.5.Final.jar:/home/hdfs/zookeeper-3.4.9/bin/../lib/log4j-1.2.16.jar:/home/hdfs/zookeeper-3.4.9/bin/../lib/jline-0.9.94.jar:/home/hdfs/zookeeper-3.4.9/bin/../zookeeper-3.4.9.jar:/home/hdfs/zookeeper-3.4.9/bin/../src/java/lib/*.jar:/home/hdfs/zookeeper-3.4.9/bin/../conf: 2017-02-16 23:07:04,051 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib 2017-02-16 23:07:04,051 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/tmp 2017-02-16 23:07:04,052 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA> 2017-02-16 23:07:04,052 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux 2017-02-16 23:07:04,052 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd64 2017-02-16 23:07:04,052 [myid:] - INFO [main:Environment@100] - Client environment:os.version=3.10.0-514.el7.x86_64 2017-02-16 23:07:04,053 [myid:] - INFO [main:Environment@100] - Client environment:user.name=hdfs 2017-02-16 23:07:04,053 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/home/hdfs 2017-02-16 23:07:04,053 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/home/hdfs/zookeeper-3.4.9/bin 2017-02-16 23:07:04,056 [myid:] - INFO [main:ZooKeeper@438] - Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@446cdf90 Welcome to ZooKeeper! JLine support is enabled 2017-02-16 23:07:04,124 [myid:] - INFO [main-SendThread(127.0.0.1:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) 2017-02-16 23:07:04,296 [myid:] - INFO [main-SendThread(127.0.0.1:2181):ClientCnxn$SendThread@876] - Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session [zk: 127.0.0.1:2181(CONNECTING) 0] 2017-02-16 23:07:04,411 [myid:] - INFO [main-SendThread(127.0.0.1:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x25a4a3c41f70000, negotiated timeout = 30000 WATCHER:: WatchedEvent state:SyncConnected type:None path:null ls / [zookeeper] [zk: 127.0.0.1:2181(CONNECTED) 1] | cs |
zkCli.sh를 통해 ZooKeeper의 Znode를 확인 할 수 있습니다.
위와 같이 접근하여 ls / 명령어로 ZooKeeper의 Znode를 확인하여 검증 할 수 있습니다.
- ZooKeeper Leader와 Follwer 확인
ZooKeeper의 Ensemble은 Leader와 Follower로 나누어집니다. Leader는 ZooKeeper의 앙상블에서 하나만 존재하게 되며, ZooKeeper가 실행
될 때 선출하게 됩니다.
다음 명령어로 어느 서버가 Leader인지, Follower 인지 구분 할 수 있습니다.
Leader 일 경우
1 2 3 4 | $ zkServer.sh status ZooKeeper JMX enabled by default Using config: /home/hdfs/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: leader | cs |
Follower 일 경우
1 2 3 4 | $ zkServer.sh status ZooKeeper JMX enabled by default Using config: /home/hdfs/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: follower | cs |
· 마무리
아주 간단하게 ZooKeeper의 설치 및 서비스 시작까지 완료했습니다. 현재까지는 최소한 구성으로 설정했으며 본문에 제공한 URL을 통해 Parameter를 조정하여 자신의 환경에 맞게 적용 할 수 있습니다.
중요한 것은 아니지만, bash_profile에 ZooKeeper의 환경 변수를 넣어 어떤 경로에서든 ZooKeeper의 명령어를 실행 할 수 있도록 설정합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $ vi ~/.bash_profile # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs # Zookeeper Part export ZOO_LOG_DIR=/data/zookeeper/logs export ZOOKEEPER_HOME=/home/hdfs/zookeeper-3.4.9 PATH=$PATH:$HOME/.local/bin:$HOME/bin:$ZOOKEEPER_HOME/bin export PATH | cs |