High Availability(HA) Hadoop Cluster 를 설치하는 방법에 대해 알아본다.

Name Node 와 Resource Manager 를 각각 Active, Standby 두 대씩 두고 주키퍼로 관리한다.

 

 

총 다섯 대의 서로 다른 CentOS 서버를 사용한다.

해당 서버들은 모두 네트워크로 묶여 있으며, ping 을 주고 받을 수 있고

22번이 아닌 6789번 포트로 비밀번호 없이 ssh 연결 가능한 상태이다.

각 서버마다 모두 JAVA 가 설치되어 있다는 가정 하에 아래 내용을 이어나간다.

 

자세한 설명은 이 포스트에 적지 않는다.

왜 이렇게 하는지 궁금하다면 여기를 참고.

 

 

JAVA 설치하는 방법 참고

SSH 연결하는 방법 참고

SSH 포트 번호 바꾸는 방법 참고

 

 

각 서버의 이름과 IP, 설치 내용은 다음과 같다.

서버 이름(호스트 이름) IP 주소 설치 내용
master 10.22.123.105 Zookeeper, Active NameNode, Active ResourceManager, JournalNode, DataNode, NodeManager
worker1 10.22.123.106 Zookeeper, Standby NameNode, Standby ResourceManager, JournalNode, DataNode, NodeManager
worker2 10.22.123.107 Zookeeper, JournalNode, DataNode, NodeManager
worker3 10.22.123.108 DataNode, NodeManager
worker4 10.22.123.109 DataNode, NodeManager

 

 

 

 

Root 계정으로 설치가 가능하지만, 되도록 Hadoop 을 구성하는 다른 계정을 하나 더 만들어서 사용하자.

hadoop 계정명은 eyeballs

 

 

 

 

 

모든 서버에서 vi /etc/hosts 내부에 다음과 같이 IP와 호스트네임을 적어준다.

10.22.123.105 master 
10.22.123.106 worker1
10.22.123.107 worker2
10.22.123.108 worker3
10.22.123.109 worker4

 

 

 

 

네임노드와 리소스매니저의 HA 를 구성하기 위한 Zookeeper를 다음의 절차를 거쳐 설치한다.

 

 

< Zookeeper 설치 >

 

 

 

zookeeper 를 설치할 각 서버마다 아래 Zookeeper 를 받고 압축을 푼다.

master, worker1, worker2 에서
cd
wget apache.tt.co.kr/zookeeper/zookeeper-3.6.1/apache-zookeeper-3.6.1-bin.tar.gz
tar zxvf apache-zookeeper-3.6.1-bin.tar.gz

참고 : https://zookeeper.apache.org/releases.html#download

 

 

conf 로 들어가서 zoo_sample.cfg 의 이름을 zoo.cfg 로 바꾼다.

master, worker1, worker2 에서
cd apache-zookeeper-3.6.1-bin/conf
mv zoo_sample.cfg zoo.cfg

 

zoo.cfg 를 열고 아래 내용으로 업데이트한다.

아래 내용은 master 뿐만 아니라 worker1, worker2 에서도 똑같이 적용해줘야 한다.

master, worker1, worker2 에서
# The number of milliseconds of each tick 
tickTime=2000 
# The number of ticks that the initial 
# synchronization phase can take 
initLimit=10 
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement 
syncLimit=5 
# the directory where the snapshot is stored. 
# do not use /tmp for storage, /tmp here is just 
# example sakes. 
dataDir=/home/eyeballs/apache-zookeeper-3.6.1-bin/data 
# the port at which the clients will connect 
clientPort=2181 
# the maximum number of client connections. 
# increase this if you need to handle more clients 
maxClientCnxns=0 
maxSessionTimeout=180000 
server.1=master:2888:3888
server.2=worker1:2888:3888
server.3=worker2:2888:3888

 

중간에 보면 dataDir 위치가 /home/eyeballs/apache-zookeeper-3.6.1-bin/data 인 것을 볼 수 있다.

그리고 가장 아래 server 뒤에 1,2,3 숫자가 master, worker1, worker2 와 매칭되어있는 것을 볼 수 있다.

 

각 서버(master, worker1, worker2)의 내부 dataDir 에 매칭된 숫자 아이디를 넣어줘야 한다.

각 서버에 접속하여 아래 명령어로 숫자 아이디를 넣어준다.

 

master 에서
cd /home/eyeballs/apache-zookeeper-3.6.1-bin/
mkdir data
cd data
echo 1 >> myid
worker1 에서
cd /home/eyeballs/apache-zookeeper-3.6.1-bin/
mkdir data
cd data
echo 2 >> myid
worker2 에서
cd /home/eyeballs/apache-zookeeper-3.6.1-bin/
mkdir data
cd data
echo 3 >> myid

 

zookeeper 구성은 이것으로 끝.

각 서버의 zookeeper 계정으로 로그인해서 아래 명령어로 zookeeper 서버를 실행해본다.

master, worker1, worker2 에서
cd /home/eyeballs/apache-zookeeper-3.6.1-bin/
./bin/zkServer.sh start

 

각 서버에서  jps 명령어의 결과에 QuorumPeerMain 이 떠 있어야 한다.

각 서버에서 다음 명령어를 통해 어떤 서버가 leader 인지 follower 인지 알 수 있다.

./bin/zkServer.sh status

 

 

 

 

 

 

 

 

< Hadoop version 3 설치 >

 

모든 서버의 hadoop 계정으로 접속하여

(*가장 위에서도 써놨지만, root 계정보다는 다른 hadoop 계정을 만드는 것이 좋음)

다음 링크를 참고하여 3.x 버전의 Binary 를 다운받는다.

참고 : https://hadoop.apache.org/releases.html

cd
wget apache.mirror.cdnetworks.com/hadoop/common/hadoop-3.2.1/hadoop-3.2.1.tar.gz
tar zxvf hadoop-3.2.1.tar.gz

 

모든 서버에서 아래 명령어를 통해 hadoop home 을 추가해준다.

vi /etc/profile

//가장 아래 내용을 추가해줌
export HADOOP_HOME=/home/eyeballs/hadoop-3.2.1
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

//저장하고 나와서 아래 명령어 실행
source /etc/profile
cd $HADOOP_HOME

 

모든 서버에서 아래와 같이 환경설정 파일을 수정해준다.

cd $HADOOP_HOME/etc/hadoop/

 


< hadoop-env.sh >

//아래 내용 추가
export JAVA_HOME=[내 컴퓨터의 JAVA_HOME path를 여기 추가]
export HADOOP_PID_DIR=/home/eyeballs/hadoop-3.2.1/pids
export HADOOP_SECURE_PID_DIR=${HADOOP_PID_DIR}

export HADOOP_SSH_OPTS="-p 6789"

내 컴퓨터의 JAVA_HOME 을 찾는 방법은 여기 참고

나의 경우 22번 포트가 아니라 6789 포트를 사용하여 hadoop 을 연결하고 싶었다.

그래서 가장 마지막 export 문장을 넣어 port 를 바꾸었다.

default ssh port number 22번을 사용하지 않고 다른 번호를 사용하려 hadoop 을 구성하려면 여기 참고

 


< workers >

master
worker1
worker2
worker3
worker4

worker 로 사용할 호스트명을 적어준다.

masters 파일은 HA 을 구성하기 때문에 작성할 필요가 없다.

 


< core-site.xml >

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://mycluster</value>
    </property>
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>master:2181,worker1:2181,worker2:2181</value>
    </property>
</configuration>

 


< hdfs-site.xml >

<configuration>
        <property>
                <name>dfs.namenode.name.dir</name>
                <value>/root/data/dfs/namenode</value>
        </property>
        <property>
                <name>dfs.datanode.data.dir</name>
                <value>/root/data/dfs/datanode</value>
        </property>
        <property>
                <name>dfs.journalnode.edits.dir</name>
                <value>/root/data/dfs/journalnode</value>
        </property>
        <property>
                <name>dfs.nameservices</name>
                <value>mycluster</value>
        </property>
        <property>
                <name>dfs.ha.namenodes.mycluster</name>
                <value>nn1,nn2</value>
        </property>
        <property>
                <name>dfs.namenode.rpc-address.mycluster.nn1</name>
                <value>master:8020</value>
        </property>
        <property>
                <name>dfs.namenode.rpc-address.mycluster.nn2</name>
                <value>worker1:8020</value>
        </property>
        <property>
                <name>dfs.namenode.http-address.mycluster.nn1</name>
                <value>master:9870</value>
        </property>
        <property>
                <name>dfs.namenode.http-address.mycluster.nn2</name>
                <value>worker1:9870</value>
        </property>
        <property>
                <name>dfs.namenode.shared.edits.dir</name>
                <value>qjournal://master:8485;worker1:8485;worker2:8485/mycluster</value>
        </property>
        <property>
                <name>dfs.client.failover.proxy.provider.mycluster</name>
                <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
        </property>
        <property>
                <name>dfs.ha.fencing.methods</name>
                <value>sshfence</value>
        </property>
        <property>
                <name>dfs.ha.fencing.ssh.private-key-files</name>
                <value>/home/eyeballs/.ssh/id_rsa</value>
        </property>
        <property>
                <name>dfs.ha.automatic-failover.enabled</name>
                <value>true</value>
        </property>
        <property>
                <name>ha.zookeeper.quorum</name>
                <value>master:2181,worker1:2181,worker2:2181</value>
        </property>
</configuration>

 


< yarn-site.xml >

<configuration>
 
<!-- Site specific YARN configuration properties -->
        <property>
                <name>yarn.resourcemanager.ha.enabled</name>
                <value>true</value>
        </property>
        <property>
                <name>yarn.resourcemanager.cluster-id</name>
                <value>rmcluster</value>
        </property>
        <property>
                <name>yarn.resourcemanager.ha.rm-ids</name>
                <value>rm1,rm2</value>
        </property>
        <property>
                <name>yarn.resourcemanager.hostname.rm1</name>
                <value>master</value>
        </property>
        <property>
                <name>yarn.resourcemanager.hostname.rm2</name>
                <value>worker1</value>
        </property>
        <property>
                <name>yarn.resourcemanager.webapp.address.rm1</name>
                <value>master:8088</value>
        </property>
        <property>
                <name>yarn.resourcemanager.webapp.address.rm2</name>
                <value>worker1:8088</value>
        </property>
        <property>
                <name>hadoop.zk.address</name>
                <value>master:2181,worker1:2181,worker2:2181</value>
        </property>
        <property>
                <name>yarn.nodemanager.aux-services</name>
                <value>mapreduce_shuffle</value>
        </property>
</configuration>

 

위처럼 zookeeper 옵션을 모두 넣은 후에 zookeeper 를 초기화해야한다.

NameNode 가 동작하는 서버 하나 위에서 아래 명령어를 실행한다.

 

$HADOOP_HOME/bin/hdfs zkfc -formatZK

 

그러면 zookeeper 내부에 automatic failover system 에 대한 znode 가 생성된다.

 

 

 

 

 

 

위와 같은 설정을 모든 서버에 적용하면 Hadoop 설치는 마무리된다.

 

 

 

 

 

 

실행을 해보자.

만약 NameNode 가 뜨지 않는 등 실행이 꼬여도 아래처럼 한다.

일단 모든 서버에서 Hadoop, Zookeeper 데몬을 중지한다.

 

cd $HADOOP_HOME/sbin
./stop-all.sh
cd /home/eyeballs/apache-zookeeper-3.6.1-bin/
./bin/zkServer.sh stop

 

 

Journal node 가 동작하는 세 대의 서버에서 Journal node 데몬을 구동시킨다.

master, worker1, worker2 에서
$HADOOP_HOME/bin/hdfs --daemon start journalnode

 

master 에서 (Active 가 될) name node 를 format 한다.

master 에서
$HADOOP_HOME/bin/hdfs namenode -format

 

NameNode 를 시작한다.

master 에서
$HADOOP_HOME/bin/hdfs --daemon start namenode

 

(Standby 가 될) name node 가 구동되는 worker1 에서 

active name node 의 meta data 를 standby namenode 로 가져오는 명령어를 적용한다.

worker1 에서
$HADOOP_HOME/bin/hdfs namenode -bootstrapStandby

 

standby name node 를 구동한다.

worker1 에서
$HADOOP_HOME/bin/hdfs --daemon start namenode

 

zookeeper 서버를 구동시킨다.

master, worker1, worker2 에서
cd /home/eyeballs/apache-zookeeper-3.6.1-bin/
./bin/zkServer.sh start

 

datanode 가 동작하는 서버에서 data node 를 구동시킨다.

master, worker1, worker2, worker3, worker4 에서
$HADOOP_HOME/bin/hdfs --daemon start datanode

 

각 name node 가 구동되는 서버에서 zkfc( zookeeper failover controller )를 포맷하고 구동시킨다.

master 혹은 worker1 에서
$HADOOP_HOME/bin/hdfs zkfc -formatZK
master, worker1 에서
$HADOOP_HOME/bin/hdfs --daemon start zkfc

 

 

master에서 start-all.sh 하여 모든 데몬을 실행시킨다.

 

위와 같이 하거나 이래도 되지 않는다 싶을 때는 초기부터 모든 data 를 지우고 시작해보자.

각 하둡 xml 에 보면 /home/eyeballs/data 로 시작하는 path 가 있는데

이들의 데이터를 모두 지우고 다시 해보자.

혹은 (필자가 꼬였을 때 도움을 받은) 곳을 참고해본다.

https://www.edureka.co/blog/how-to-set-up-hadoop-cluster-with-hdfs-high-availability/

 

 

실행 후 각 서버에서 jps 명령어의 결과가 아래처럼 떠야 한다.

master worker1 worker2 worker3 worker4
DataNode
JournalNode
DFSZKFailoverController
NameNode
NodeManager
ResourceManager
QuorumPeerMain
DataNode
JournalNode
DFSZKFailoverController
NameNode
NodeManager
ResourceManager
QuorumPeerMain
DataNode
JournalNode
NodeManager
QuorumPeerMain
DataNode
NodeManager
DataNode
NodeManager

 

 

잘 작동하는지 아래 명령어를 통해 word count 예제를 실행시켜보자.

$HADOOP_HOME/bin/hdfa dfs -put $HADOOP_HOME/README.md /input
$HADOOP_HOME/bin/yarn jar $HADOOP_HOME/share/mapreduce/hadoop-mapreduce-examples-3.2.1.jar wordcount /input /output
$HADOOP_HOME/bin/hdfs dfs -cat /output/*

 

README.md 를 대상으로 한 word count 결과가 잘 떴(으면 좋겠)다.

 

 

 

 

 

만약 zkfc 가 동작하지 않는다면, namenode 가 동작하는 서버 위에서 아래 명령어를 통해 직접 zkfc 데몬을 실행시킨다.

 

master, worker1 에서
$HADOOP_HOME/bin/hdfs --daemon start zkfc

 

 

 

 

 

 

 

 

각 네임 노드가 동작하는 master, worker1 에서 아래 명령어를 통해

현재 어떤 네임 노드가 Active 인지, Standby 인지 알 수 있다.

 

master 에서
$HADOOP_HOME/bin/hdfs haadmin -getServiceState nn1

 

worker1 에서
$HADOOP_HOME/bin/hdfs haadmin -getServiceState nn2

 

 

각 RM 이 동작하는 master, worker1 에서 아래 명령어를 통해

현재 어떤 RM 이 Active 인지, StandBy 인지 알 수 있다.

master 에서
$HADOOP_HOME/bin/yarn rmadmin -getServiceState rm1

 

worker1 에서
$HADOOP_HOME/bin/yarn rmadmin -getServiceState rm2

 

 

 

 

 

 

 

 

Active Name Node 가 구동되는 서버에서

jps 를 통해 나온 name node 의 프로세스 id 값을 이용하여

name node kill 을 해보자.

그리고 아래 명령어를 통해 다시 살려본다.

Active Name Node 를 죽인 서버에서
$HADOOP_HOME/bin/hdfs --daemon start namenode

 

해당 작업 후에 standby 였던 name node 는 Active 가 되고

(왜냐면 사용자가 Active 를 죽였기 때문에 standby 가 Active 로 승격됨)

기존에 Active 였던 name node(우리가 다시 살린) 는 standby 가 된다.

 

 

 

 

 

 

 

 

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

https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html

 

https://www.edureka.co/blog/how-to-set-up-hadoop-cluster-with-hdfs-high-availability/

 

https://excelsior-cjh.tistory.com/73

https://redplug.tistory.com/760

https://cyberx.tistory.com/148

https://bloodguy.tistory.com/entry/Hadoop-YARN-ResourceManager-HA-HighAvailability

http://blog.naver.com/PostView.nhn?blogId=juner84&logNo=220489980731

https://medium.com/@gamzabaw/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B6%84%EC%84%9D-%EC%9D%B8%ED%94%84%EB%9D%BC-%EA%B5%AC%EC%B6%95%EA%B8%B0-2-4-616df0d52ac3

 

https://docs.cloudera.com/HDPDocuments/HDP3/HDP-3.1.0/fault-tolerance/content/configuring_the_namenode_ha_cluster.html

https://docs.cloudera.com/HDPDocuments/HDP3/HDP-3.1.0/fault-tolerance/content/deploying_namenode_ha_cluster.html

 

https://www.linode.com/docs/databases/hadoop/how-to-install-and-set-up-hadoop-cluster/

 

+ Recent posts