Hadoop2 HA方案之QJM

喜歡一我的,能夠爲TA作任何事,獲得不接受卻依然心甘情願鞍前馬後,苦苦等候那一線但願。對,這就是備胎,掛在汽車背後,可能一生也用不到的那個圓圈狀的玩意兒,大部分狀況下,它都會默默地掛在那裏,等待幾千分之一的機會,有個倒黴的輪子兄弟出事了,因而它就能派上用場了……(摘自豆瓣)html

在Hadoop的分佈式文件系統HDFS中,NameNode用來保存文件系統的元數據(包含目錄結構/數據塊位置等),若是NameNode上的數據丟失,HDFS上對應的文件數據就沒法找回來了。Hadoop在2.0.0以前的版本,使用SecondaryNameNode備份NameNode的數據,但SecondaryNameNode沒法轉成NameNode,若是NameNode掛了,整個HDFS就會掛掉,沒法實現真正的failover。這篇博文總結了5種Hadoop HA(High Available,高可用)方案,Hadoop2以後官方引入了QJM(Quorum Journal Manager)和NFS用於NameNode的備份和切換。本方將介紹的是QJM方案,它使用第二個NameNode實時同步當前NameNode的數據,相比於SecondaryNameNode,他能夠隨時切換成爲真正的NameNode(一個可轉正的高級備胎)。node

先看看沒有HA的HDFS的系統架構(用draw.io畫的,尼馬這麼好的網站也被牆了):web

HDFS Architecture

而後有HA方案的系統架構:apache

HDFS HA Architecture

如下的實驗基於4個節點的Hadoop集羣。其中每一個節點的運行的進程列表以下:bootstrap

Role\Host hd1 hd2 hd3 hd4
NN
DN
JN
ZK

實驗環境中,全部節點的運行環境基本相同:bash

  • Ubuntu14.04 X64
  • 4G內存
  • OpenJDK-1.7.0
  • 100Mbps以太網

下面是實現這個系統的流程(官方文檔+我的註解+輔助Shell命令)。架構

1. 安裝Hadoop系統。

嚴格按照單節點搭建集羣搭建兩個步驟,系統建起來徹底沒壓力。我遇到的問題是剛開始在配置文件(salves和core-site.xml等文件)中使用的是ip地址而非主機名,而後在log文件裏看到各類沒法鏈接。解決方案是修改主機名並在hosts文件裏創建映射關係。app

hostname {new_hostname} # 修改主機名,只有當前Session有效
sudo vi /etc/hostname   # 永久修改主機名的方法

另外,對於64位的系統,最好從新編譯源碼。ssh

2. 修改配置文件。

hdfs-site.xml文件:分佈式

<configuration>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/data/hadoop/namenode</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/data/hadoop/datanode</value>
  </property>
  <property>
    <name>dfs.replication</name>
    <value>2</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>hd1:8020</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-address.mycluster.nn2</name>
    <value>hd3:8020</value>
  </property>
  <property>
    <name>dfs.namenode.http-address.mycluster.nn1</name>
    <value>hd1:50070</value>
  </property>
  <property>
    <name>dfs.namenode.http-address.mycluster.nn2</name>
    <value>hd3:50070</value>
  </property>
  <property>
    <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://hd1:8485;hd2:8485;hd4: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/hduser/.ssh/id_rsa</value>
  </property>
  <property>
    <name>dfs.journalnode.edits.dir</name>
    <value>/data/hadoop/journalnode</value>
  </property>
</configuration>
  • 其中nameservices是集羣的命名空間,即便有多個集羣,能夠共用配置文件,可是要注意某些配置項的順序。
  • dfs.ha.namenodes.mycluster中的mycluster是能夠任取的,可是要和dfs.nameservices對應。
  • dfs.namenode.rpc-address.mycluster.nn1參考上一條。
  • dfs.namenode.shared.edits.dir值的格式是"qjournal://host1:port1;host2:port2;host3:port3/journalId",用來指定對應的JN節點,journalId建議使用和nameservices相同的名稱。
  • dfs.client.failover.proxy.provider.mycluster指定激活NameNode的Java類,目前Hadoop內置的只有上面那個。
  • dfs.ha.fencing.methods是來用來隔離失效的NameNode的方法,有sshfence和Shell兩種方式。sshfence須要配置dfs.ha.fencing.ssh.private-key-files私鑰文件,以便交互的過程不須要輸入密碼。
  • dfs.journalnode.edits.dir是JN保存數據的文件。

core-site.xml文件:

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://mycluster</value>
    </property>
</configuration>
  • 注意mycluster要和dhfs-site.xml中的dfs.nameservices對應。fs.defaultFS不用端口號。

3. 部署

改好配置文件好,就要將配置文件同步到全部的機器上了。能夠用rsync將文件同步到多臺機器上。rsync是一個增量同步工具,須要先安裝。下面的rsync.sh的功能是將當前目錄的全部文件發送到文件或參數對應的機器上。

$ cat rsync.sh 
#! /bin/bash

dir=`pwd`
pdir=`dirname $dir`

send(){
    echo "Sending to $2:$1"
    rsync -avez -e ssh $1 $2:$3
}

mul_send(){
    while read host
    do
        send $dir $host $pdir
    done < $1
}

[ -f $1 ] && mul_send $1 || send $dir $1 $pdir

將rsync.sh放在etc/hadoop目錄下,進入目錄運行

chmod +x rsync.sh
./rsync.sh slaves
# or ./rsync.sh hostname

發送完文件以後,就是啓動系統。步驟以下:

啓動JNs.

在全部JournalNode上運行

sbin/hadoop-daemon.sh --script hdfs start journalnode

啓動NameNode.

在原NameNode上運行

bin/hadoop --script hdfs start namenode # NameNode須要已經format。

(使用上面的rsync.sh文件)將原NameNode(nn1)上的數據複製到第二個NameNode(nn2)。而後在nn2上運行:

bin/hdfs namenode -bootstrapStandby

啓動其餘節點

在NameNode上運行

sbin/start-dfs.sh

4. 切換NameNode

手動方式

上面的NameNode默認以standby的狀態啓動,這時由於沒有active的NameNode,因此是不能在HDFS讀寫文件,須要將其中的一個轉成active狀態。好比將nn1(對應前面的配置)轉成Active:

bin/hdfs haadmin -transitionToActive nn1

而後在NameNode的web頁面上部的括號裏的standby變成active。
轉成standby的命令是:

bin/hdfs haadmin -transitionToStandby nn1

自動切換

在當前NameNode不能使用時自動切換到第二個NameNode上,須要藉助於ZooKeeper(ZK)。

ZK的安裝過程和Hadoop差很少,就是下載文件、修改配置、複製到全部機器、啓動。具體步驟在這裏

配置文件conf/zoo.conf:

tickTime=2000
dataDir=/data/hadoop/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=hd2:2888:3888
server.2=hd3:2888:3888
server.3=hd4:2888:3888

hd2,hd3,hd4是主機名,至少須要三臺,這個在一臺機掛了整個系統還能用,ZK的數量通常是奇數。

而後要在hdfs-site.xml上添加配置:

<property>
    <name>dfs.ha.automatic-failover.enabled</name>
    <value>true</value>
</property>
<property>
    <name>ha.zookeeper.quorum</name>
    <value>hd2:2181,hd3:2181,hd4:2181</value>
</property>

而後就是在NameNode的機器上初始化NameNode在ZK的狀態了:

bin/hdfs zkfc -formatZK

重啓HDFS或手動啓動DFSZKFailoverController(ZKFC):

sbin/stop-dfs.sh # 重啓hdfs
sbin/start-dfs.sh
sbin/hadoop-daemon.sh start zkfc # 啓動ZKFC

在該HA方案中,每個NameNode都有一個對應的ZKFC。ZKFC會隨NameNode啓動。

測試

在當前NameNode運行jps看NameNode的進程ID,而後kill掉。經過Web頁面(http://hdx:50070),能夠看到standby的NameNode幾乎在kill的同時轉成active了。

相關文章
相關標籤/搜索