1、背景介紹
Hadoop2.0.0之前,在一個HDFS集群中,NameNode存在單節點故障(SPOF):因為集群中只有一個NameNode,所以在使用過程中,如果該NameNode出現故障或數據丟失,那么整個集群將癱瘓,故障NameNode節點故障無法恢復,將導致整個集群不能恢復,這也是Hadoop2.0.0之前版本不可靠的表現。
為了解決hadoop2.0.0之前的單點問題,在hadoop2通過在同一個集群上運行兩個NameNode的主動/被動配置熱備份,這樣集群允許在一個NameNode出現故障時轉移到另外一個NameNode來保證集群的正常運。兩個NameNode有相同的職能。在任何時候,一個是active狀態的,一個是standby狀態的。當集群運行時,只有active狀態的NameNode是正常工作的,standby狀態的NameNode是處於待命狀態的,時刻同步active狀態NameNode的數據。一旦active狀態的NameNode不能工作,通過手工或者自動切換,standby狀態的NameNode就可以轉變為active狀態的,就可以繼續工作了,這就是高可靠。
2、體系結構
在一個典型的HA集群中,需要選擇兩台單獨的機器作為NameNode,並且在任何時候,一個NameNode處於活躍狀態,另外一個則處於備用狀態;活躍的NameNode負責集群中所有客戶端操作,備用節點作為從節點,在活躍節點故障時提供一個快速的故障轉移。
為了備用節點能夠與活躍節點保持同步,兩個節點之間增加了一個守護進程“JournalNodes”(JNS),當任何namespace被活動節點所修改,JNS都會記錄edits及相應的操作日志,備用節點會從JNS上讀取edits,並將edits中所記錄操作應用在自己的namespace,在發生故障時,備用節點將能確保在自己成為活動節點之前通過JNS讀取了所有的edits,從而確保namespace在故障轉移前是完全同步的。
為了提供一個快速的故障轉移,備用節點有必要保存最新的集群中數據塊的位置,為了實現這一目的,datanode配置了兩個namenode,並給兩個namenode發送塊的信息及心跳。
需要確保集群中有且僅有一個namenode是活躍的,否則,兩個namenode之間的分歧很可能造成數據丟失或其他錯誤;為了防止該問題的出現,JNS只允許一個namenode(即 active node)存在寫權限,在故障轉移期間,新的活躍的namenode將接管寫權限,這將有效地防止其他NameNode持續處於活躍狀態,並允許新的活動節點安全的進行故障轉移。
3、環境介紹
linux系統:CentOS 7.0 (64位)
內存:8G
Hadoop版本:2.7.3
4、Hadoop集群結構說明
4.1 集群結構
IP | 主機名 | Hadoop角色 | Hadoop jps結果 |
---|---|---|---|
192.168.248.205 | hadoop01 | master | NameNode/ResourceManager/DFSZKFailoverController |
192.168.248.206 | hadoop02 | NameNode/DFSZKFailoverController | |
192.168.248.207 | hadoop03 | slaves | DataNode/JournalNode/NodeManager |
192.168.248.208 | hadoop04 | slaves | DataNode/JournalNode/NodeManager |
192.168.248.209 | hadoop05 | slaves | DataNode/JournalNode/NodeManager |
4.2 hosts文件配置
$ vi /etc/hosts 192.168.248.205 hadoop01 192.168
.248.206
hadoop02
...
192.168.248.209 hadoop05
5、Hadoop集群配置
Hadoop需要通過SSH來啟動Slave列表中主機的Hadoop守護進程,對於分布式,Hadoop會依次啟動$HADOOP_HOME/etc/hadoop/savles文件中配置的主機進程。
5.1、配置SSH免密碼登錄(略),安裝配置zookeeper略。
5.2、Hadoop分布式集群配置:
Hadoop的分布式安裝過程非常簡單,只需要將Hadoop安裝包解壓到指定的目錄就可以了,接下來對Hadoop的主要配置文件進行配置。
將Hadoop安裝包解壓到/usr/hadoop 目錄下:
然后針對/usr/hadoop/hadoop-2.7.3/etc/hadoop目錄下幾個主要文件進行配置:
hadoop-env.sh、yarn-env.sh 、core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml、slaves
5.2.1、配置hadoop-env.sh
編輯hadoop-env.sh,找到JAVA_HOME指定JDK的安裝配置
$vi hadoop-env.sh export JAVA_HOME=/opt/jdk1.8
5.2.2、配置yarn-env.sh
編輯yarn-env.sh,找到JAVA_HOME指定JDK的安裝配置
$vi yarn-env.sh
export JAVA_HOME=/opt/jdk1.8
5.2.3、配置core-site.xml
$vi core-site.xml
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <!-- 指定hdfs的nameservice為cluster --> <property> <name>fs.defaultFS</name> <value>hdfs://cluster</value> </property> <!-- 指定zookeeper地址--> <property> <name>ha.zookeeper.quorum</name> <value>192.168.248.205:2181,192.168.248.206:2181,192.168.248.207:2181,192.168.248.208:2181,192.168.248.209:2181</value> </property> <property> <name>ha.zookeeper.session-timeout.ms</name> <value>60000</value> </property> <!-- 故障檢查時間 --> <property> <name>ha.failover-controller.cli-check.rpc-timeout.ms</name> <value>60000</value> </property> <!-- ipc通訊超時時間 --> <property> <name>ipc.client.connect.timeout</name> <value>20000</value> </property> <!-- 指定hadoop臨時目錄 --> <property> <name>hadoop.tmp.dir</name> <value>file:/usr/hadoop/tmp</value> </property> </configuration>
5.2.4、配置hdfs-site.xml
Hadoop中的HDFS配置,主要配置備份方式,及NameNode、DataNode、NameSecondary存儲地址。
$vi hdfs-site.xml
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <!--指定hdfs的nameservice為cluster,需要和core-site.xml中的保持一致 --> <property> <name>dfs.nameservices</name> <value>cluster</value> </property> <!-- cluster下面有兩個NameNode,分別是nn1,nn2 --> <property> <name>dfs.ha.namenodes.cluster</name> <value>nn1,nn2</value> </property> <!-- nn1、nn2的RPC通信地址 --> <property> <name>dfs.namenode.rpc-address.cluster.nn1</name> <value>192.168.248.205:9000</value> </property> <property> <name>dfs.namenode.rpc-address.cluster.nn2</name> <value>192.168.248.206:9000</value> </property> <!-- nn1、nn2的http通信地址 --> <property> <name>dfs.namenode.http-address.cluster.nn1</name> <value>192.168.248.205:50070</value> </property> <property> <name>dfs.namenode.http-address.cluster.nn2</name> <value>192.168.248.206:50070</value> </property> <property> <name>dfs.namenode.servicerpc-address.cluster.nn1</name> <value>192.168.248.205:53310</value> </property> <property> <name>dfs.namenode.servicerpc-address.cluster.nn2</name> <value>192.168.248.206:53310</value> </property> <!-- 指定NameNode的元數據在JournalNode上的存放位置 --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://192.168.248.207:8485;192.168.248.208:8485;192.168.248.209:8485/cluster</value> </property> <!-- 指定JournalNode在本地磁盤存放數據的位置 --> <property> <name>dfs.journalnode.edits.dir</name> <value>/usr/hadoop/hdfs/journal/data</value> </property> <!-- 開啟NameNode失敗自動切換 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> <!-- 配置失敗自動切換實現方式 --> <property> <name>dfs.client.failover.proxy.provider.cluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider </value> </property> <!-- 配置隔離機制方法,多個機制用換行分割,即每個機制暫用一行 --> <property> <name>dfs.ha.fencing.methods</name> <value> sshfence shell(/bin/true) </value> </property> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property> <property> <name>dfs.webhdfs.enabled</name> <value>true</value> </property> <property> <name>dfs.permissions.enable</name> <value>false</value> </property> <property> <name>dfs.permissions</name> <value>false</value> </property> <property> <name>dfs.image.transfer.bandwidthPerSec</name> <value>1048576</value> </property> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:/usr/hadoop/hdfs/name</value> </property> <property> <name>dfs.datanode.name.dir</name> <value>file:/usr/hadoop/hdfs/data</value> </property> <property> <name>dfs.namenode.checkpoint.dir</name> <value>file:/usr/hadoop/hdfs/namesecondary</value> </property> </configuration>
5.2.5、配置mapred-site.xml
Hadoop的MapReduce框架配置,配置MapReduce框架名稱
$vi mapred-site.xml
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
5.2.6、配置yarn-site.xml
$vi yarn-site.xml
<?xml version="1.0"?> <configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>192.168.248.205</value> </property> </configuration>
5.2.7、配置slaves節點列表
對於分布式安裝,該文件中需要配置從節點機器名。
$vi slaves
192.168.248.207
192.168.248.208
192.168.248.209
(注解:slaves節點配置列表,偽分布式配置為:localhost)
到此,整個Hadoop偽分布式安裝完畢,接下來就可以格式HDFS文件系統,並啟動Hadoop系統。(將以上這些配置文件同步到其他所有主機)
5.3、啟動集群
5.3.1、啟動zookeeper集群(略)
5.3.2、啟動journal node(在hadoop03、04、05)
./sbin/hadoop-daemon.sh start journalnode
執行jps命令,可以查看到JournalNode的Java進程pid;
5.3.3、格式化HDFS(namenode)第一次要格式化(在hadoop01、02中任意一台,我選擇hadoop01)(這里直接復制會有問題,最好手動輸入)
./bin/hdfs namenode –format
5.3.4、格式化zk(在hadoop01即可)(這里直接復雜會有問題,最好手動輸入)
./bin/hdfs zkfc –formatZK
格式成功后,查看zookeeper中可以看到
[zk: localhost:2181(CONNECTED) 1] ls /hadoop-ha [cluster]
5.3.5、啟動zkfc來監控NN狀態(在hadoop01、02)
./sbin/hadoop-daemon.sh start zkfc
5.3.6、啟動HDFS(namenode)(在hadoop01即可)
./sbin/start-dfs.sh
#把NameNode的數據同步到hadoop02上(在hadoop02上執行) $ hdfs namenode –bootstrapStandby #啟動mhadoop02上的namenode作為standby $ sbin/hadoop-daemon.sh start namenode
5.3.8、啟動YARN
在hadoop01上執行如下命令
啟動YARN(MR)(在192.168.248.205即可)
6、測試HA
正常啟動后hadoop01的namenode與hadoop02的namenode狀態截圖如下:
此時在hadoop01上執行如下命令關閉namenode
$ sbin/hadoop-daemon.sh stop namenode
再次查看hadoop02上的namenode,發現自動切換為active了,結果如下: