평생 한 번만 하고 말 것 같지만 그래도 혹시 몰라 기록으로 남겨둠.


*** 주의사항 ***

- 1.0.0 에서 2.6.0 으로 업그레이드는 rolling upgrade가 안되므로 당연히 downtime이 발생함.

- NameNode HA로 바로 업그레이드 하는 것은 불가능하므로 괜히 삽질하지 말 것.





사전작업

* 우선 hadoop 클러스터에 달라붙어서 HDFS에 뭘 넣거나 MapReduce 하고 있는 모든 걸 중지시킬 것.


업그레이드 여부 확인

* 이전 업그레이드가 완료되지 않았으면 업그레이드를 못하므로 확인

[root@server01]# /home/hadoop/bin/hadoop dfsadmin -upgradeProgress status

There are no upgrades in progress. // <--- OK


// 혹시 업그레이드 중이라면 아래 명령어로 완료시켜 줄 것

[root@server01]# /home/hadoop/bin/hadoop dfsadmin -finalizeUpgrade


sanity check을 위한 백업

// fsck

[root@server01]# /home/hadoop/bin/hadoop fsck / -files -blocks -locations > /BACKUP_DIR/fsck-old.log

// namespace

[root@server01]# /home/hadoop/bin/hadoop dfs -lsr / > /BACKUP_DIR/namespace-old.log

// datanode list

[root@server01]# /home/hadoop/bin/hadoop dfsadmin -report > /BACKUP_DIR/datanode_list-old.log


namenode metadata 백업

// 우선 safemode로 진입해서 새로운 write가 불가능하게 만들고

[root@server01]# /home/hadoop/bin/hadoop dfsadmin -safemode enter

// namenode metadata를 disk에 flush

[root@server01]# /home/hadoop/bin/hadoop dfsadmin -saveNamespace

// dfs.name.dir 디렉토리를 어딘가에 백업. 

// 원래 백업할 몇몇 디렉토리가 지정되어 있지만 귀찮으니까 통째로...;

[root@server01]# cp -r /home/hadoop/data/dfs/name /BACKUP_DIR/


hadoop cluster 중지

[root@server01]# /home/hadoop/bin/stop-all.sh


디렉토리 설정

// 아래 내용은 클러스터를 구성하는 전체 서버 대상으로 모두 세팅해 줄 것


// dfs.data.dir이 이전 버전의 hadoop 디렉토리 내부에 있으므로 뽑아낼 것

[root@server01]# mv /home/hadoop/data /home/hadoop_data

// 심볼릭 링크

[root@server01]# cd /home/hadoop ; ln -s /home/hadoop_data data


// hadoop 경로 자체도 심볼릭 링크 처리

[root@server01]# mv /home/hadoop /home/hadoop-1.0.0

[root@server01]# cd /home ; ln -s hadoop-1.0.0 hadoop






업그레이드


2.6.0 설치

// 다운로드 및 압축해제

[root@server01]# cd /home

[root@server01]# wget http://mirror.apache-kr.org/hadoop/common/hadoop-2.6.0/hadoop-2.6.0.tar.gz

[root@server01]# tar xfz hadoop-2.6.0.tar.gz


// 심볼릭 링크 수정

[root@server01]# rm -rf hadoop

[root@server01]# ln -s hadoop-2.6.0 hadoop


// dfs.data.dir 경로 심볼릭 링크

[root@server01]# cd hadoop

[root@server01]# ln -s /home/hadoop_data data


// pid 파일 경로 생성

[root@server01]# mkdir -p /home/hadoop/pids

// short-circuit local reads를 위한 unix domain socket 경로 생성

[root@server01]# mkdir -p /var/lib/hadoop-hdfs


설정파일

$HADOOP_HOME/etc/hadoop/hadoop-env.sh

# 아래 내용들만 추가 혹은 수정
export JAVA_HOME=/usr/lib/jvm/java-1.6.0
export HADOOP_HOME=/home/hadoop
export HADOOP_PID_DIR=${HADOOP_HOME}/pids


$HADOOP_HOME/etc/hadoop/mapred-env.sh

# 아래 내용만 수정
export HADOOP_MAPRED_PID_DIR=${HADOOP_PID_DIR}


$HADOOP_HOME/sbin/yarn-daemon.sh

# 아래 내용만 수정
YARN_PID_DIR=${HADOOP_PID_DIR}


$HADOOP_HOME/etc/hadoop/core-site.xml

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://server01:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/home/hadoop/data/temp</value>
    </property>
    <property>
        <name>fs.trash.interval</name>
        <value>1440</value>
    </property>
</configuration>


$HADOOP_HOME/etc/hadoop/masters

server01


$HADOOP_HOME/etc/hadoop/slaves

server02
server03
server04
server05
server06
server07


$HADOOP_HOME/etc/hadoop/excludes

그냥 0 바이트짜리 파일만 생성해 둠


$HADOOP_HOME/etc/hadoop/includes

server02
server03
server04
server05
server06
server07


$HADOOP_HOME/etc/hadoop/hdfs-site.xml

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <name>dfs.datanode.du.reserved</name>
        <value>10737418240</value>
    </property>
    <property>
        <name>dfs.hosts</name>
        <value>/home/hadoop/etc/hadoop/includes</value>
    </property>
    <property>
        <name>dfs.hosts.exclude</name>
        <value>/home/hadoop/etc/hadoop/excludes</value>
    </property>
    <!--
        dfs.name.dir -> dfs.namenode.name.dir
    -->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:///home/hadoop/data/dfs/name</value>
    </property>
    <!--
        dfs.data.dir -> dfs.datanode.data.dir
    -->
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:///home/hadoop/data/dfs/data</value>
    </property>
    <property>
        <name>dfs.namenode.checkpoint.dir</name>
        <value>file:///home/hadoop/data/dfs/namesecondary</value>
    </property>
    <property>
        <name>dfs.http.address</name>
        <value>server01:50070</value>
    </property>
    <property>
        <name>dfs.secondary.http.address</name>
        <value>server01:50090</value>
    </property>
    <!-- Short-Circuit Local Reads 사용함 -->
    <property>
        <name>dfs.client.read.shortcircuit</name>
        <value>true</value>
    </property>
    <!-- Short-Circuit Local Reads에 사용할 UNIX domain socket 경로 -->
    <property>
        <name>dfs.domain.socket.path</name>
        <value>/var/lib/hadoop-hdfs/dn_socket</value>
    </property>
</configuration>


$HADOOP_HOME/etc/hadoop/mapred-site.xml

<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>


$HADOOP_HOME/etc/hadoop/yarn-site.xml

<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
    <property>
        <name>yarn.resourcemanager.nodes.include-path</name>
        <value>/home/hadoop/etc/hadoop/includes</value>
    </property>
    <property>
        <name>yarn.resourcemanager.nodes.exclude-path</name>
        <value>/home/hadoop/etc/hadoop/excludes</value>
    </property>
    <property>
        <name>yarn.nodemanager.local-dirs</name>
        <value>file:///home/hadoop/data/yarn/nm-local-dir</value>
    </property>
    <property> 
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.resourcemanager.fs.state-store.uri</name>
        <value>/home/hadoop/data/yarn/rmstore</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>server01</value>
    </property>
</configuration>


Native Library

server01 에서 native library를 빌드한 후 나머지 서버로 배포할 생각임.

만약 클러스터를 구성하는 서버의 환경이 다르다면 각 서버별로 빌드를 해야할 것.

빌드 하는 법은 아래 페이지 참조

Hadoop Native Library 빌드


전체 클러스터 배포

// 배포할 hadoop 설치본 압축

[root@server01]# cd /home

[root@server01]# tar cfz hadoop-2.6.0-dist.tar.gz hadoop-2.6.0


// 전체 서버 전송

[root@server01]# scp hadoop-2.6.0-dist.tar.gz root@server02:/home

... ...

[root@server01]# scp hadoop-2.6.0-dist.tar.gz root@server07:/home


// 압축 해제

[root@server01]# ssh root@server02 'cd /home ; tar xfz hadoop-2.6.0-dist.tar.gz'

... ...

[root@server01]# ssh root@server07 'cd /home ; tar xfz hadoop-2.6.0-dist.tar.gz'


// 심볼릭 링크 수정

[root@server01]# ssh root@server02 'cd /home ; rm -rf hadoop ; ln -s hadoop-2.6.0 hadoop'

... ...

[root@server01]# ssh root@server07 'cd /home ; rm -rf hadoop ; ln -s hadoop-2.6.0 hadoop'


// 기타 필요한 디렉토리 생성

[root@server01]# ssh root@server02 'mkdir -p /home/hadoop/pids ; mkdir -p /var/lib/hadoop-hdfs'

... ...

[root@server01]# ssh root@server07 'mkdir -p /home/hadoop/pids ; mkdir -p /var/lib/hadoop-hdfs'


서버별 설정

클러스터를 구성하는 서버별로 다른 설정이 필요할 경우 서버별 설정을 해줄 것.


업그레이드

// 업그레이드 시도

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


// 업그레이드가 완료된 이 상태에서

// 우선 namespace sanity check이 가능하므로 내키면 미리 해봐도 됨


// 업그레이드가 성공적이라면 HDFS 실행

[root@serer01]# /home/hadoop/sbin/start-dfs.sh


sanity check

// sanity check을 위해 업그레이드 된 데이터를 새로 추출

// fsck

[root@server01]# /home/hadoop/bin/hdfs fsck / -files -blocks -locations > /BACKUP_DIR/fsck-new.log


// namespace

[root@server01]# /home/hadoop/bin/hdfs dfs -ls -R / > /BACKUP_DIR/namespace-new.log


// datanode list

[root@server01]# /home/hadoop/bin/hdfs dfsadmin -report > /BACKUP_DIR/datanode_list-new.log


/*

1.0.0 과 2.6.0 은 출력되는 데이터 포맷이 각각 다르므로 일반적인 diff 로는 비교할 수 없고,

비교를 위한 적절한 스크립트를 만들어서 sanity check을 수행할 것.

*/







업그레이드 이후


YARN 실행

// YARN 실행

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


// jobhistory server 실행

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


최종확인


HDFS

HDFS에서 파일을 몇 개 뽑아본다던가 하면서 확인


MapReduce

실제로 돌려보고 결과값을 비교해 보면서 확인

나는 streaming으로만 해서 수정해야 할 부분은 jar 파일 경로밖에 없음.

/home/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.6.0.jar 


finalize

upgrade 최종승인 단계.

하지만 finalize를 하면 롤백 아카이브가 제거되어 절대 돌이킬 수 없으므로 확인에 확인을 거듭한 후 실행할 것.

// finalize

[root@server01]# /home/hadoop/bin/hdfs dfsadmin -finalizeUpgrade







업그레이드 실패


rollback

namespace가 어긋났거나 뭔가 기분이 이상하거나 할 경우 rollback을 할 수 있음.

// 우선 이전에 띄웠던 2.6.0 버전 클러스터 shutdown

[root@server01]# /home/hadoop/sbin/stop-dfs.sh

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

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


// 심볼릭 링크 변경 (전체 서버 대상)

[root@server01]# cd /home ; rm -rf hadoop ; ln -s hadoop-1.0.0 hadoop

[root@server01]# ssh root@server02 'cd /home ; rm -rf hadoop ; ln -s hadoop-1.0.0 hadoop'

... ...

[root@server01]# ssh root@server07 'cd /home ; rm -rf hadoop ; ln -s hadoop-1.0.0 hadoop'


// rollback

[root@server01]# /home/hadoop/bin/start-dfs.sh -rollback










Posted by bloodguy
,