Hadoop1 시절에는 NameNode가 SPOF(SinglePointOfFailure)였음.

그때도 체크포인팅 주기를 조절하는 등 나름대로의 FailOver 노력이 있었으나,

Hadoop2 부터는 정식으로 고가용성(HighAvailability)을 보장하는 세팅이 가능함.


아래는 QJM(QuorumJournalManager)로 HA를 구성한 HDFS 구성도. (YARN관련은 제외)








각 프로세스별 동작은 아래와 같음.


Zookeeper는 네임서비스별 active/standby NameNode의 정보를 저장.


DFSZKFailoverController는 NameNode를 모니터링 하고 있다가 active NameNode가 죽으면,

standby NameNode를 active로 전환시키고 죽은 active NameNode를 클러스터에서 뽑아내고,

Zookeeper에 정보를 갱신.


JournalNode는 namespace가 변경될 때 발생하는 edit log를 저장함. 

최소 3대 이상 홀수로 실행되어야 하며, (N/2)+1 이상의 JournalNode가 살아있어야 정상동작이 보장됨.


NameNode(active)는 edit log를 JournalNode에 기록. (active만 기록 가능)


NameNode(standby)는 JournalNode에서 edit log를 읽어와 fsImage 갱신.


DataNode는 active/standby NameNode 모두에 Block 정보와 HeartBeat 보냄.






NameNode HA 구성 예제.


기존 구성이 아래와 같다고 가정함. (YARN 관련 프로세스 제외)

server01: NameNode

server02: SecondaryNameNode, DataNode

server03: DataNode

server04: DataNode

server05: DataNode


HA 구성은 아래처럼 할 예정. (YARN 관련 프로세스 제외)

server01: QuorumPeerMain(zookeeper), JournalNode, DFSZKFailoverController, NameNode(active)

server02: QuorumPeerMain(zookeeper), JournalNode, DFSZKFailoverController, NameNode(standby)

server03: QuorumPeerMain(zookeeper), JournalNode, DataNode

server04: DataNode

server05: DataNode


신규설치가 아니라 기존 non-HA NameNode를 HA NameNode로 컨버팅하는 예제임에 주의.

그래봐야 hdfs namenode -format 정도가 대체되는 수준이지만..


또 하나 주의할 점은 Failover 상황시 standby NameNode가 active NameNode로 전환되면서 이 서버 저 서버 집적거려야 하므로,

server02 도 클러스터 내부 서버들을 인증없이 ssh 로 들락거릴 수 있도록 세팅해야 함. (server01은 이미 되어있을테고)


우선 zookeeper 설치.

server01 에서 아래처럼 설치.

// 다운로드

[root@server01]# cd /home

[root@server01]# wget http://mirror.apache-kr.org/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz


// 압축해제, 설정

[root@server01]# tar xvfz zookeeper-3.4.6.tar.gz

[root@server01]# mv zookeeper-3.4.6 zookeeper

[root@server01]# cd zookeeper

[root@server01]# cp conf/zoo_sample.cfg conf/zoo.cfg

[root@server01]# vi conf/zoo.cfg


// 아래처럼 설정하고 저장

;;zoo.cfg

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/home/zookeeper/data

clientPort=2181

maxClientCnxns=0

maxSessionTimeout=180000

server.1=server01:2888:3888

server.2=server02:2888:3888

server.3=server03:2888:3888


// 데이터 디렉토리 생성, myid 세팅

[root@server01]# mkdir -p /home/zookeeper/data

[root@server01]# echo 1 > /home/zookeeper/data/myid


// 여기까지 한 다음 /home/zookeeper를 압축해서 scp 등으로 server02, server03 에 전송

// 그리고 server02, server03 서버에서 /home/zookeeper/data/myid 파일 내용을 각각 2, 3으로 저장

[root@server02] # echo 2 > /home/zookeeper/data/myid

[root@server03] # echo 3 > /home/zookeeper/data/myid


// 이제 server01~03 에서 zookeeper 서버 실행

[root@server01]# /home/zookeeper/bin/zkServer.sh start

[root@server02]# /home/zookeeper/bin/zkServer.sh start

[root@server03]# /home/zookeeper/bin/zkServer.sh start


// jps 실행해서 QuorumPeerMain이 떠있으면 성공.

[root@server01]# jps

25051 QuorumPeerMain


// 서버 상태 확인 (Mode가 leader 아니면 follower로 나올것임)

[root@server01]# /home/zookeeper/bin/zkServer.sh status

JMX enabled by default

Using config: /home/zookeeper/bin/../conf/zoo.cfg

Mode: follower



이제 Hadoop 세팅.


Hadoop은 /home/hadoop 경로에 설치되어 있다고 가정함.


NameNode HA 에서는 SecondaryNameNode란 게 사라지므로,

/home/hadoop/etc/hadoop 경로의 설정파일 중 masters 파일은 이제 쓸모없게 됨.


나머지 설정정보는 그대로 두고 아래 파일들만 설정을 바꿔주면 됨.


core-site.xml




hdfs-site.xml (설정할 게 좀 되므로 HA와 관계없는 설정들은 제외함)



여기까지 설정하고 설정파일 압축해서 서버 전체에 배포.


이제 본격적으로 실행.


// zookeeper 초기화

[root@server01]# /home/hadoop/bin/hdfs zkfc -formatZK


// 초기화 확인을 위해 zookeeper 접속

[root@server01]# /home/zookeeper/bin/zkCli.sh


// /hadoop-ha 아래에 dfs.nameservices 지정한 nameserviceID 노드가 있으면 성공.

ls /hadoop-ha

[my-hadoop-cluster]

// 빠져나오자

[zk: localhost:2181(CONNECTED) 1] quit



// server01~03 에서 JournalNode 실행

[root@server01]# /home/hadoop/sbin/hadoop-daemon.sh start journalnode

[root@server02]# /home/hadoop/sbin/hadoop-daemon.sh start journalnode

[root@server03]# /home/hadoop/sbin/hadoop-daemon.sh start journalnode


// 저널 초기화

[root@server01]# /home/hadoop/bin/hdfs namenode -initializeSharedEdits


// active NameNode 실행

[root@server01]# /home/hadoop/sbin/hadoop-daemon.sh start namenode


// active NameNode용 ZKFC 실행

[root@server01]# /home/hadoop/sbin/hadoop-daemon.sh start zkfc


// 확인

[root@server01]# jps

1096 NameNode

1650 DFSZKFailoverController

1456 JournalNode

25051 QuorumPeerMain


// 전체 DataNode 실행 (server03 ~ 05)

[root@server03]# /home/hadoop/sbin/hadoop-daemon.sh start datanode

[root@server04]# /home/hadoop/sbin/hadoop-daemon.sh start datanode

[root@server05]# /home/hadoop/sbin/hadoop-daemon.sh start datanode


// server02에서 standby NameNode 준비

[root@server02]# /home/hadoop/bin/hdfs namenode -bootstrapStandby


// standby NameNode 실행

[root@server02]# /home/hadoop/sbin/hadoop-daemon.sh start namenode


// standby NameNode용 ZKFC 실행

[root@server02]# /home/hadoop/sbin/hadoop-daemon.sh start zkfc


// 여기까지 하면 NameNode HA 설정완료.


// 이제 나머지 YARN, JobHistoryServer를 실행

[root@server01]# /home/hadoop/sbin/start-yarn.sh

[root@server01]# /home/hadoop/sbin/mr-jobhistory-daemon.sh start historyserver




여기까지 하면 완료.

잘 돌아가는지 확인하고 싶으면 http://server01:50070 혹은 http://server02:50070 으로 접속해도 되고,

아래처럼 haadmin 명령어로 확인도 가능함.

// 각 NameNode 상태확인

[root@server01]# /home/hadoop/bin/hdfs haadmin -getServiceState nn1

active


[root@server01]# /home/hadoop/bin/hdfs haadmin -getServiceState nn2

standby






이제 진짜 Failover가 되는지 테스트.

// NameNode의 active/standby 상태는 위처럼 nn1이 active, nn2가 standby라고 가정.


// active NameNode를 죽여보자.

[root@server01]# jps

1456 JournalNode

25051 QuorumPeerMain

1096 NameNode

1650 DFSZKFailoverController

26058 JobHistoryServer

1911 ResourceManager


[root@server01]# kill -9 1096


// active NameNode가 죽은 후 standby였던 nn2의 상태를 확인해보면 active로 바뀐 걸 확인할 수 있음.

[root@server01]# /home/hadoop/bin/hdfs haadmin -getServiceState nn2

active


// 기타 나머지 dfs 관련 명령어도 아무 문제 없이 잘 되는 것을 확인해 보자.


// 이제 죽었던 namenode를 다시 살리고

[root@server01]# /home/hadoop/sbin/hadoop-daemon.sh start namenode


// 죽었다 살아난 namenode는 이제 standby

[root@server01]# /home/hadoop/bin/hdfs haadmin -getServiceState nn1

standby








ps. 혹시나 삽질할 사람이 있을까 걱정되어 사족을 남기는데, 내 경험에 의하면 Hadoop 1.0.0 에서 2.6.0 으로 업그레이드 할 때 한방에 HA로는 안되었음.

일단 non-HA 로 업그레이드하고 나서 HA 로 컨버팅하는 것을 권장함.

나는 어떻게든 되지 않을까 싶어서 삽질하다가 시간만 옴팡지게 낭비했음.




[참고]

https://hadoop.apache.org/docs/r2.6.0/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html











저작자 표시
신고
Posted by bloodguy

댓글을 달아 주세요

  1. NJ 2017.04.17 17:07 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 글 감사합니다.

  2. js 2017.08.23 11:29 신고  댓글주소  수정/삭제  댓글쓰기

    질문드려요!
    글 보고 HA 설정은 완료했는데 nanode01(active) , namenode02(standy) 상태에서 namenode01 을 kill 했을때 namenode02가 바로 active로 올라오지않고 kill되었던 namenode01을 다시 스타트 해줘야 namenode01(standy),namenode02(active) 가 되네요 ... 혹시 이유를 아실까해서 적어봅니다.

    • bloodguy 2017.08.23 22:34 신고  댓글주소  수정/삭제

      글쎄요. 단지 증상만 가지고는 잘 모르겠습니다. 로그를 보시거나 하셔서 정확한 원인을 파악해보시는 게 좋을 것 같아요.



티스토리 툴바