在Hadoop2.x以後的版本,提出瞭解決單點問題的方案--HA(High Available 高可用)。這篇博客闡述如何搭建高可用的HDFS和YARN,執行步驟以下:java
下面咱們給出下載包的連接地址:node
zookeeper下載地址linux
JDK下載地址
apache
注:若JDK沒法下載,請到Oracle的官網下載JDK。bootstrap
到這裏安裝包都準備好了,接下來咱們開始搭建與配置。安全
useradd hadoop passwd hadoop
而後根據提示,設置密碼。接着我給hadoop用戶設置面免密碼權限,也可自行添加其餘權限。服務器
chmod +w /etc/sudoers hadoop ALL=(root)NOPASSWD:ALL chmod -w /etc/sudoers
將下載好的安裝包解壓到 /usr/java/jdk1.7,而後設置環境變量,命令以下:架構
sudo vi /etc/profile
而後編輯配置,內容以下:oracle
export JAVA_HOME=/usr/java/jdk1.7 export PATH=$PATH:$JAVA_HOME/bin
而後使環境變量當即生效,命令以下:
source /etc/profile
而後驗證JDK是否配置成功,命令以下:
java -version
若顯示對應版本號,即表示JDK配置成功。不然,配置無效!
集羣中全部機器的hosts配置要要相同(推薦)。能夠避免沒必要要的麻煩,用域名取代IP,方便配置。配置信息以下:
10.211.55.12 nna # NameNode Active 10.211.55.13 nns # NameNode Standby 10.211.55.14 dn1 # DataNode1 10.211.55.15 dn2 # DataNode2 10.211.55.16 dn3 # DataNode3
而後用scp命令,將hosts配置分發到各個節點。命令以下:
# 這裏以NNS節點爲例子 scp /etc/hosts hadoop@nns:/etc/
輸入以下命令:
ssh-keygen –t rsa
而後一路按回車鍵,最後在將id_rsa.pub寫到authorized_keys,命令以下:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
在hadoop用戶下,須要給authorized_keys賦予600的權限,否則免密碼登錄無效。在其餘節點只須要使用 ssh-keygen –t rsa 命令,生產對應的公鑰,而後將各個節點的id_rsa.pub追加到nna節點的authorized_keys中。最後,將nna節點下的authorized_keys文件經過scp命令,分發到各個節點的 ~/.ssh/ 目錄下。目錄以下:
# 這裏以NNS節點爲例子 scp ~/.ssh/authorized_keys hadoop@nns:~/.ssh/
而後使用ssh命令相互登陸,看是否實現了免密碼登陸,登陸命令以下:
# 這裏以nns節點爲例子 ssh nns
若登陸過程當中木有提示須要輸入密碼,即表示密碼配置成功。
因爲hadoop的節點之間須要通訊(RPC機制),這樣一來就須要監聽對應的端口,這裏我就直接將防火牆關閉了,命令以下:
chkconfig iptables off
注:若是用於生產環境,直接關閉防火牆是存在安全隱患的,咱們能夠經過配置防火牆的過濾規則,即將hadoop須要監聽的那些端口配置到防火牆接受規則中。關於防火牆的規則配置參見「linux防火牆配置」,或者通知公司的運維去幫忙配置管理。
同時,也須要關閉SELinux,可修改 /etc/selinux/config 文件,將其中的 SELINUX=enforcing 改成 SELINUX=disabled便可。
各個節點的時間若是不一樣步,會出現啓動異常,或其餘緣由。這裏將時間統一設置爲Shanghai時區。命令以下:
# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime cp: overwrite `/etc/localtime'? yes 修改成中國的東八區 # vi /etc/sysconfig/clock ZONE="Asia/Shanghai" UTC=false ARC=false
將下載好的安裝包,解壓到指定位置,這裏爲直接解壓到當前位置,命令以下:
tar -zxvf zk-{version}.tar.gz
修改zk配置,將zk安裝目錄下conf/zoo_sample.cfg重命名zoo.cfg,修改其中的內容:
# The number of milliseconds of each tick # 服務器與客戶端之間交互的基本時間單元(ms) tickTime=2000 # The number of ticks that the initial # synchronization phase can take # zookeeper所能接受的客戶端數量 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. # 保存zookeeper數據,日誌的路徑 dataDir=/home/hadoop/data/zookeeper # the port at which the clients will connect # 客戶端與zookeeper相互交互的端口 clientPort=2181 server.1= dn1:2888:3888 server.2= dn2:2888:3888 server.3= dn3:2888:3888 #server.A=B:C:D 其中A是一個數字,表明這是第幾號服務器;B是服務器的IP地址;C表示服務器與羣集中的「領導者」交換信息的端口;當領導者失效後,D表示用來執行選舉時服務器相互通訊的端口。
接下來,在配置的dataDir目錄下建立一個myid文件,裏面寫入一個0-255之間的一個隨意數字,每一個zk上這個文件的數字要是不同的,這些數字應該是從1開始,依次寫每一個服務器。文件中序號要與dn節點下的zk配置序號一直,如:server.1=dn1:2888:3888,那麼dn1節點下的myid配置文件應該寫上1。
分別在各個dn節點啓動zk進程,命令以下:
bin/zkServer.sh start
而後,在各個節點輸入jps命令,會出現以下進程:
QuorumPeerMain
上面說的輸入jps命令,若顯示對應的進程,即表示啓動成功,一樣咱們也能夠輸入zk的狀態命令查看,命令以下:
bin/zkServer.sh status
會出現一個leader和兩個follower。
HDFS配置HA的結構圖以下所示:
上圖大體架構包括:
1. 利用共享存儲來在兩個NN間同步edits信息。之前的HDFS是share nothing but NN,如今NN又share storage,這樣實際上是轉移了單點故障的位置,但中高端的存儲設備內部都有各類RAID以及冗餘硬件,包括電源以及網卡等,比服務器的可靠性仍是略有提升。經過NN內部每次元數據變更後的flush操做,加上NFS的close-to-open,數據的一致性獲得了保證。
2. DN同時向兩個NN彙報塊信息。這是讓Standby NN保持集羣的最新狀態的必須步驟。
3. 用於監視和控制NN進程的FailoverController進程。顯然,咱們不能在NN進程內部進行心跳等信息同步,最簡單的緣由,一次FullGC就可讓NN掛起十幾分鍾,因此,必需要有一個獨立的短小精悍的watchdog來專門負責監控。這也是一個鬆耦合的設計,便於擴展或更改,目前版本里是用ZooKeeper(簡稱ZK)來作同步鎖,但用戶能夠方便的把這個Zookeeper FailoverController(簡稱ZKFC)替換爲其餘的HA方案或leader選舉方案。
4. 隔離(Fencing),防止腦裂,就是保證在任什麼時候候只有一個主NN,包括三個方面:
共享存儲fencing,確保只有一個NN能夠寫入edits。
客戶端fencing,確保只有一個NN能夠響應客戶端的請求。
DN fencing,確保只有一個NN向DN下發命令,譬如刪除塊,複製塊等等。
名稱 |
Host |
職責 |
NNA |
10.211.55.12 |
zkfc |
NNS |
10.211.55.13 |
zkfc |
DN1 |
10.211.55.14 |
zookeeper |
DN2 |
10.211.55.15 |
zookeeper |
DN3 |
10.211.55.16 |
zookeeper |
這裏列出了全部的配置,後面配置其餘組件,能夠參考這裏的配置。 配置完成後,輸入:. /etc/profile(或source /etc/profile)使之當即生效。驗證環境變量配置成功與否,輸入:echo $HADOOP_HOME,若輸出對應的配置路徑,便可認定配置成功。
注:hadoop2.x之後的版本conf文件夾改成etc文件夾了
配置內容以下所示:
export JAVA_HOME=/usr/java/jdk1.7 export HADOOP_HOME=/home/hadoop/hadoop-2.6.0 export ZK_HOME=/home/hadoop/zookeeper-3.4.6 export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOM
注:這裏特別提醒,配置文件中的路徑在啓動集羣以前,得存在(若不存在,請事先建立)。下面爲給出本篇文章須要建立的路徑腳本,命令以下:
mkdir -p /home/hadoop/tmp mkdir -p /home/hadoop/data/tmp/journal mkdir -p /home/hadoop/data/dfs/name mkdir -p /home/hadoop/data/dfs/data mkdir -p /home/hadoop/data/yarn/local mkdir -p /home/hadoop/log/yarn
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://cluster1</value> </property> <property> <name>io.file.buffer.size</name> <value>131072</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/tmp</value> </property> <property> <name>hadoop.proxyuser.hadoop.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.hadoop.groups</name> <value>*</value> </property> <property> <name>ha.zookeeper.quorum</name> <value>dn1:2181,dn2:2181,dn3:2181</value> </property> </configuration>
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property> <name>dfs.nameservices</name> <value>cluster1</value> </property> <property> <name>dfs.ha.namenodes.cluster1</name> <value>nna,nns</value> </property> <property> <name>dfs.namenode.rpc-address.cluster1.nna</name> <value>nna:9000</value> </property> <property> <name>dfs.namenode.rpc-address.cluster1.nns</name> <value>nns:9000</value> </property> <property> <name>dfs.namenode.http-address.cluster1.nna</name> <value>nna:50070</value> </property> <property> <name>dfs.namenode.http-address.cluster1.nns</name> <value>nns:50070</value> </property> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://dn1:8485;dn2:8485;dn3:8485/cluster1</value> </property> <property> <name>dfs.client.failover.proxy.provider.cluster1</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/hadoop/.ssh/id_rsa</value> </property> <property> <name>dfs.journalnode.edits.dir</name> <value>/home/hadoop/data/tmp/journal</value> </property> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/home/hadoop/data/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/home/hadoop/data/dfs/data</value> </property> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.webhdfs.enabled</name> <value>true</value> </property> <property> <name>dfs.journalnode.http-address</name> <value>0.0.0.0:8480</value> </property> <property> <name>dfs.journalnode.rpc-address</name> <value>0.0.0.0:8485</value> </property> <property> <name>ha.zookeeper.quorum</name> <value>dn1:2181,dn2:2181,dn3:2181</value> </property> </configuration>
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.jobhistory.address</name> <value>nna:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>nna:19888</value> </property> </configuration>
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property> <name>yarn.resourcemanager.connect.retry-interval.ms</name> <value>2000</value> </property> <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <property> <name>ha.zookeeper.quorum</name> <value>dn1:2181,dn2:2181,dn3:2181</value> </property> <property> <name>yarn.resourcemanager.ha.automatic-failover.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>nna</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>nns</value> </property> <!--在namenode1上配置rm1,在namenode2上配置rm2,注意:通常都喜歡把配置好的文件遠程複製到其它機器上,但這個在YARN的另外一個機器上必定要修改 --> <property> <name>yarn.resourcemanager.ha.id</name> <value>rm1</value> </property> <!--開啓自動恢復功能 --> <property> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <!--配置與zookeeper的鏈接地址 --> <property> <name>yarn.resourcemanager.zk-state-store.address</name> <value>dn1:2181,dn2:2181,dn3:2181</value> </property> <property> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> <property> <name>yarn.resourcemanager.zk-address</name> <value>dn1:2181,dn2:2181,dn3:2181</value> </property> <property> <name>yarn.resourcemanager.cluster-id</name> <value>cluster1-yarn</value> </property> <!--schelduler失聯等待鏈接時間 --> <property> <name>yarn.app.mapreduce.am.scheduler.connection.wait.interval-ms</name> <value>5000</value> </property> <!--配置rm1 --> <property> <name>yarn.resourcemanager.address.rm1</name> <value>nna:8132</value> </property> <property> <name>yarn.resourcemanager.scheduler.address.rm1</name> <value>nna:8130</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm1</name> <value>nna:8188</value> </property> <property> <name>yarn.resourcemanager.resource-tracker.address.rm1</name> <value>nna:8131</value> </property> <property> <name>yarn.resourcemanager.admin.address.rm1</name> <value>nna:8033</value> </property> <property> <name>yarn.resourcemanager.ha.admin.address.rm1</name> <value>nna:23142</value> </property> <!--配置rm2 --> <property> <name>yarn.resourcemanager.address.rm2</name> <value>nns:8132</value> </property> <property> <name>yarn.resourcemanager.scheduler.address.rm2</name> <value>nns:8130</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm2</name> <value>nns:8188</value> </property> <property> <name>yarn.resourcemanager.resource-tracker.address.rm2</name> <value>nns:8131</value> </property> <property> <name>yarn.resourcemanager.admin.address.rm2</name> <value>nns:8033</value> </property> <property> <name>yarn.resourcemanager.ha.admin.address.rm2</name> <value>nns:23142</value> </property> <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.nodemanager.local-dirs</name> <value>/home/hadoop/data/yarn/local</value> </property> <property> <name>yarn.nodemanager.log-dirs</name> <value>/home/hadoop/log/yarn</value> </property> <property> <name>mapreduce.shuffle.port</name> <value>23080</value> </property> <!--故障處理類 --> <property> <name>yarn.client.failover-proxy-provider</name> <value>org.apache.hadoop.yarn.client.ConfiguredRMFailoverProxyProvider</value> </property> <property> <name>yarn.resourcemanager.ha.automatic-failover.zk-base-path</name> <value>/yarn-leader-election</value> </property> </configuration>
# The java implementation to use. export JAVA_HOME=/usr/java/jdk1.7
# some Java parameters export JAVA_HOME=/usr/java/jdk1.7
修改hadoop安裝目錄下的slave文件:
dn1
dn2
dn3
因爲咱們配置了QJM,因此咱們須要先啓動QJM的服務,啓動順序以下所示:
15/02/21 10:30:59 INFO common.Storage: Storage directory /home/hadoop/data/dfs/name has been successfully formatted.
15/02/21 10:30:59 WARN common.Util: Path /home/hadoop/data/dfs/name should be specified as a URI in configuration files. Please update hdfs configuration.
15/02/21 10:30:59 WARN common.Util: Path /home/hadoop/data/dfs/name should be specified as a URI in configuration files. Please update hdfs configuration.
15/02/21 10:31:00 INFO namenode.TransferFsImage: Opening connection to http://nna:50070/imagetransfer?getimage=1&txid=0&storageInfo=-60:1079068934:0:CID-1dd0c11e-b27e-4651-aad6-73bc7dd820bd
15/02/21 10:31:01 INFO namenode.TransferFsImage: Image Transfer timeout configured to 60000 milliseconds
15/02/21 10:31:01 INFO namenode.TransferFsImage: Transfer took 0.01s at 0.00 KB/s
15/02/21 10:31:01 INFO namenode.TransferFsImage: Downloaded file fsimage.ckpt_0000000000000000000 size 353 bytes.
15/02/21 10:31:01 INFO util.ExitUtil: Exiting with status 0
15/02/21 10:31:01 INFO namenode.NameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at nns/10.211.55.13 ************************************************************/
因爲我配置的是自動切換,若NNA節點宕掉,NNS節點會當即由standby狀態切換爲active狀態。如果配置的手動狀態,能夠輸入以下命令進行人工切換:
hdfs haadmin -failover --forcefence --forceactive nna nns
這條命令的意思是,將nna變成standby,nns變成active。並且手動狀態下須要重啓服務。
這篇文章就贅述到這裏,若在配置過程當中有什麼疑問或問題,能夠加入QQ羣討論或發送郵件給我,我會盡我所能爲您解答,與君共勉!