네임노드 HA 구성하기 - NFS 활용

HDFS는 블록을 복제해 저장해놓음으로써 데이터 손실을 방지하지만, 그러한 메타데이터들을 저장하고있는 수뇌부인 네임노드가 죽을 경우 손가락만 빨게 된다.

따라서 네임노드는 단일 실패 지점(SPOF)이 되며, 네임노드의 이런 문제를 해결하기 위해 하둡 2.0 부터 네임노드 HA를 지원한다.

Acitve-Standby 형식으로 두개(혹은 그 이상)의 네임노드가 떠서, 액티브 네임노드는 일반적인 네임노드 역할을 하고, 스탠바이 네임노드는 액티브에 장애가 발생할 경우 그 역할을 문제 없이 이어받을 수 있게 하는 방식이다.

이를 지원하기 위해 네임노드들은 메타데이터가 변경되는 사항인 edit log 들을 공유 스토리지를 통해 공유하여 스탠바이가 액티브의 상태를 항상 따라가는 구조이다.

또한 네임노드들은 블록 정보들을 메모리에 올려 관리하고 있기 때문에, 데이터노드들이 블록 리포트를 두개의 네임노드에 모두 전송해야 한다.

네임노드의 HA를 위한 공유 스토리지에는 NFS를 사용하는 방식과 QJM(Quorum Journal Manager)을 사용하는 방식이 있는데, 이 글에서는 우선 nfs를 활용한다.

구조는 아래와 비슷하다.

데이터노드들이 두 네임노드에 블록 리포트를 모두 전송하고, 그 외에 액티브의 edit log들은 공유 스토리지에 저장됨으로써 죽어버렸을 떄 스탠바이 네임노드가 기존 액티브가 하던 역할을 그대로 이어받는다.

주의해야할 점은, nfs 로 공유 스토리지를 마운트해서 네임노드 HA를 구성한다고 하더라도, 스토리지가 spof 지점이 되어 가용성 문제가 발생할 수 있다는 점이다.

따라서 공유 스토리지 서버에 대해서도 단순한 리눅스 서버가 아닌, 고가용성을 보장하는 NAS 어플라이언스 등이나 HA로 구성된 스토리지를 사용하는 것이 권장된다.

그러나 지금은 테스트용이기 때문에 h01 서버의 특정 디렉토리를 공유하여 h02 가 같이 쓰도록 한다.

역할주소호스트명장비운영체제
Active NN192.168.100.141h01노트북Ubuntu Desktop 20.04
Standby NN192.168.100.142h02데스크탑Ubuntu Desktop 20.04
DataNode192.168.100.143h03노트북Ubuntu Desktop 20.04


네임노드 HA 세팅을 위해서는, hdfs-site.xml 이랑 core-site.xml 에 몇가지 속성값들을 지정해줘야 한다.

프로퍼티들을 설정하는 순서는 상관 없지만, dfs.nameservicesdfs.ha.namenodes.[nameservice ID]의 경우는 다른 프로퍼티들이 참조하는 값이기 때문에 반드시 맨 앞에 지정해주자.

hdfs-site.xml

# dfs.nameservices
# 클러스터 안에 HA 네임노드들이 여럿 존재할 수 있기 때문에 이를 식별하기 위한 네임서비스 식별자
# 마음대로 설정하면 되며, 다른 프로퍼티들이 이 네임서비스 식별자를 기반으로 지정됨
<property>
    <name>dfs.nameservices</name>
    <value>hanfs</value>
</property>
# dfs.ha.namenodes.[nameservice ID] - 특정 네임서비스 안에서 각 네임노드들에 대한 식별자
# 목록을 쉼표로 구분하여 나열하며, 앞에서 네임서비스 식별자를 hanfs 로 지정했기 때문에 프로퍼티는 dfs.ha.namenodes.hanfs 가 된다.
<property>
    <name>dfs.ha.namenodes.hanfs</name>
    <value>nn1,nn2</value>
</property>
# dfs.namenode.rpc-address.[nameservice ID][namenode ID] - 각 네임노드들이 열어둘 rpc 포트
# 각 네임노드마다 하나씩 세팅
<property>
    <name>dfs.namenode.rpc-address.hanfs.nn1</name>
    <value>h01:8020</value>
</property>
<property>
    <name>dfs.namenode.rpc-address.hanfs.nn2</name>
    <value>h02:8020</value>
</property>
# # dfs.namenode.http-address.[nameservice ID][namenode ID] - 각 네임노드들이 열어둘 web UI 포트
# 각 네임노드마다 하나씩 세팅, 
<property>
    <name>dfs.namenode.http-address.hanfs.nn1</name>
    <value>h01:9870</value>
</property>
<property>
    <name>dfs.namenode.http-address.hanfs.nn2</name>
    <value>h02:9870</value>
</property>
# dfs.namenode.shared.edits.dir - 마운트된 공유 스토리지(nfs) 위치
# 스탠바이 네임노드가 액티브 네임노드의 변경사항들을 계속 따라가기 위해 edits 들을 저장할 경로
# 공유 스토리지는 모든 네임노드들이 읽고 쓸 수 있는 권한을 가져야 하며, 절대 경로로 넣어줘야 함
<property>
    <name>dfs.namenode.shared.edits.dir</name>
    <value>file:///nfs_HA</value>
</property>
# dfs.client.failover.proxy.provider.[nameservice ID] - hdfs 클라이언트가 액티브 네임노드와 통신하기 위한 클래스
# 오타에 주의하자!
<property>
    <name>dfs.client.failover.proxy.provider.hanfs</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
# 펜싱을 위한 기법과 ssh-key 위치
<property>
    <name>dfs.ha.fencing.methods</name>
    <value>sshfence</value>
</property>
<property>
    <name>dfs.ha.fencing.ssh.private-key-files</name>
    <value>/home/bconfiden2/.ssh/id_rsa</value>
</property>

core-site.xml

# 하둡의 파일시스템 클라이언트가 기본적으로 사용할 prefix
# HDFS 경로에 hdfs-site 에서 지정해줬던 네임서비스 식별자(hanfs)를 넣어줘야 한다.
<property>
    <name>fs.defaultFS</name>
    <value>hdfs://hanfs</value>
</property>

기본적인 HA 구성을 위한 프로퍼티들은 이정도로 세팅해주고, 설정파일들을 클러스터에 동일하게 복사해준다.

하둡 클러스터를 처음부터 구성 중에 HA 세팅을 하고 있다면, 먼저 아무런 한쪽 노드에서 hdfs namenode -format으로 네임노드를 포맷해준 뒤 start-all.sh 등으로 클러스터를 띄우면 된다.

그러나 만약 이미 단일 네임노드로 구성되어 포맷된 상태라면, 기존 네임노드의 메타데이터들을 전부 그대로 복사해준 뒤, hdfs namenode -bootstrapStandby로 상태를 맞춰준다.

마지막으로는 처음부터 포맷했든지 기존 네임노드를 복사해왔든지 간에 상관없이 hdfs namenode -initializeSharedEdits로 공유 스토리지를 초기화하여 네임노드들이 사용할 수 있게 하면 끝!


네임노드가 정상적으로 떴는지는 각 노드의 로그가 저장되는 경로에서 확인하든지, jps 등으로 볼 수 있다.

혹은 hdfs haadmin 명령어를 지원해주는데, 아래처럼 모든 특정 네임서비스에 속한 네임노드들의 현재 상태를 확인해보자.

bconfiden2@h01:/opt/hadoop/etc/hadoop$ hdfs haadmin -ns hanfs -getAllServiceState
h01:8020                                           standby
h02:8020                                           standby

HA 구성만 한 뒤 아무런 추가 작업을 하지 않으면, 기본적으로 두 네임노드가 모두 스탠바이로 뜨게 된다.

이 상태에서는 hdfs dfs -ls 등으로 파일시스템 조회도 되지 않으며, 9870으로 각 네임노드의 웹UI를 확인해봐도 스탠바이 노드이기 때문에 파일시스템을 확인할 수 없다.

수동으로 두 네임노드 중 하나를 액티브로 바꿔준다.

bconfiden2@h01:/opt/hadoop/etc/hadoop$ hdfs haadmin -transitionToActive nn1
bconfiden2@h01:/opt/hadoop/etc/hadoop$ hdfs haadmin -ns hanfs -getAllServiceState
h01:8020                                           active
h02:8020                                           standby

nn1 의 식별자는 h01 로 세팅했었기 때문에, 해당 네임노드가 액티브로 바뀐 것을 확인할 수 있다!

이제 hdfs 에다가 파일을 막 넣어주면, hdfs haadmin -transitionToStandby nn1으로 nn1 을 스탠바이로 바꿔준 뒤 nn2 를 액티브로 바꾼다고 하더라도, 두 네임노드의 상태가 동일하게 유지되었기 때문에 문제 없이 파일들이 유지된다.

그러나 여기서 끝내는 것은 재미없다.

액티브 상태이던 노드가 불의의 사고로 인해 죽어버렸을 때 이를 자동으로 감지해서 스탠바이 네임노드가 액티브로 변환되는 것을 원하지만, 지금 단계에서는 관리자가 수동으로 바꿔줘야하기 때문이다.

다음 글에서 주키퍼를 찍어먹어보자.