Hadoop HA架構詳解html
HDFS HA背景java
影響HDFS集羣不可用主要包括如下兩種狀況:一是NameNode機器宕機,將致使集羣不可用,重啓NameNode以後纔可以使用;二是計劃內的NameNode節點軟件或硬件升級,致使集羣在短期內不可用。node
爲了解決上述問題,Hadoop給出了HDFS的高可用HA方案:HDFS一般由兩個NameNode組成,一個處於active狀態,另外一個處於standby狀態。Active NameNode對外提供服務,好比處理來自客戶端的RPC請求,而Standby NameNode則不對外提供服務,僅同步Active NameNode的狀態,以便可以在它失敗時快速進行切換。linux
HDFS HA架構vim
一個典型的HA集羣,NameNode會被配置在兩臺獨立的機器上,在任什麼時候間上,一個NameNode處於活動狀態,而另外一個NameNode處於備份狀態,活動狀態的NameNode會響應集羣中全部的客戶端,備份狀態的NameNode只是做爲一個副本,保證在必要的時候提供一個快速的轉移。bash
爲了讓Standby Node與Active Node保持同步,這兩個Node都與一組稱爲JNS的互相獨立的進程保持通訊(Journal Nodes)。當Active Node上更新了namespace,它將記錄修改日誌發送給JNS的多數派。Standby noes將會從JNS中讀取這些edits,並持續關注它們對日誌的變動。Standby Node將日誌變動應用在本身的namespace中,當failover發生時,Standby將會在提高本身爲Active以前,確保可以從JNS中讀取全部的edits,即在failover發生以前Standy持有的namespace應該與Active保持徹底同步。服務器
爲了支持快速failover,Standby node持有集羣中blocks的最新位置是很是必要的。爲了達到這一目的,DataNodes上須要同時配置這兩個Namenode的地址,同時和它們都創建心跳連接,並把block位置發送給它們。網絡
任什麼時候刻,只有一個Active NameNode是很是重要的,不然將會致使集羣操做的混亂,那麼兩個NameNode將會分別有兩種不一樣的數據狀態,可能會致使數據丟失,或者狀態異常,這種狀況一般稱爲「split-brain」(腦裂,三節點通信阻斷,即集羣中不一樣的Datanodes卻看到了兩個Active NameNodes)。對於JNS而言,任什麼時候候只容許一個NameNode做爲writer;在failover期間,原來的Standby Node將會接管Active的全部職能,並負責向JNS寫入日誌記錄,這就阻止了其餘NameNode基於處於Active狀態的問題。session
基於QJM的HDFS HA方案如上圖所示,其處理流程爲:集羣啓動後一個NameNode處於Active狀態,並提供服務,處理客戶端和DataNode的請求,並把editlog寫到本地和share editlog(這裏是QJM)中。另一個NameNode處於Standby狀態,它啓動的時候加載fsimage,而後週期性的從share editlog中獲取editlog,保持與Active節點的狀態同步。爲了實現Standby在Active掛掉後迅速提供服務,須要DataNode同時向兩個NameNode彙報,使得Stadnby保存block to DataNode信息,由於NameNode啓動中最費時的工做是處理全部DataNode的blockreport。爲了實現熱備,增長FailoverController和Zookeeper,FailoverController與Zookeeper通訊,經過Zookeeper選舉機制,FailoverController經過RPC讓NameNode轉換爲Active或Standby。架構
HDFS HA配置要素
NameNode機器:兩臺配置對等的物理機器,它們分別運行Active和Standby Node。
JouralNode機器:運行JouralNodes的機器。JouralNode守護進程至關的輕量級,能夠和Hadoop的其餘進程部署在一塊兒,好比NameNode、DataNode、ResourceManager等,至少須要3個且爲奇數,若是你運行了N個JNS,那麼它能夠容許(N-1)/2個JNS進程失效而且不影響工做。
在HA集羣中,Standby NameNode還會對namespace進行checkpoint操做(繼承Backup Namenode的特性),所以不須要在HA集羣中運行SecondaryNameNode、CheckpointNode或者BackupNode。
HDFS HA配置參數
須要在hdfs.xml中配置以下參數:
dfs.nameservices:HDFS NN的邏輯名稱,例如myhdfs。
dfs.ha.namenodes.myhdfs:給定服務邏輯名稱myhdfs的節點列表,如nn一、nn2。
dfs.namenode.rpc-address.myhdfs.nn1:myhdfs中nn1對外服務的RPC地址。
dfs.namenode.http-address.myhdfs.nn1:myhdfs中nn1對外服務http地址。
dfs.namenode.shared.edits.dir:JournalNode的服務地址。
dfs.journalnode.edits.dir:JournalNode在本地磁盤存放數據的位置。
dfs.ha.automatic-failover.enabled:是否開啓NameNode失敗自動切換。
dfs.ha.fencing.methods :配置隔離機制,一般爲sshfence。
HDFS自動故障轉移
HDFS的自動故障轉移主要由Zookeeper和ZKFC兩個組件組成。
Zookeeper集羣做用主要有:一是故障監控。每一個NameNode將會和Zookeeper創建一個持久session,若是NameNode失效,那麼此session將會過時失效,此後Zookeeper將會通知另外一個Namenode,而後觸發Failover;二是NameNode選舉。ZooKeeper提供了簡單的機制來實現Acitve Node選舉,若是當前Active失效,Standby將會獲取一個特定的排他鎖,那麼獲取鎖的Node接下來將會成爲Active。
ZKFC是一個Zookeeper的客戶端,它主要用來監測和管理NameNodes的狀態,每一個NameNode機器上都會運行一個ZKFC程序,它的職責主要有:一是健康監控。ZKFC間歇性的ping NameNode,獲得NameNode返回狀態,若是NameNode失效或者不健康,那麼ZKFS將會標記其爲不健康;二是Zookeeper會話管理。當本地NaneNode運行良好時,ZKFC將會持有一個Zookeeper session,若是本地NameNode爲Active,它同時也持有一個「排他鎖」znode,若是session過時,那麼次lock所對應的znode也將被刪除;三是選舉。當集羣中其中一個NameNode宕機,Zookeeper會自動將另外一個激活。
YARN HA架構
YARN的HA架構和HDFSHA相似,須要啓動兩個ResourceManager,這兩個ResourceManager會向ZooKeeper集羣註冊,經過ZooKeeper管理它們的狀態(Active或Standby)並進行自動故障轉移。
高可用集羣規劃
集羣規劃
根據Hadoop的HA架構分析,規劃整個集羣由5臺主機組成,具體狀況以下表所示:
須要說明如下幾點:
HDFS HA一般由兩個NameNode組成,一個處於Active狀態,另外一個處於Standby狀態。Active NameNode對外提供服務,而Standby NameNode則不對外提供服務,僅同步Active NameNode的狀態,以便可以在它失敗時快速進行切換。
Hadoop 2.0官方提供了兩種HDFS HA的解決方案,一種是NFS,另外一種是QJM。這裏咱們使用簡單的QJM。在該方案中,主備NameNode之間經過一組JournalNode同步元數據信息,一條數據只要成功寫入多數JournalNode即認爲寫入成功。一般配置奇數個JournalNode,這裏還配置了一個Zookeeper集羣,用於ZKFC故障轉移,當Active NameNode掛掉了,會自動切換Standby NameNode爲Active狀態。
YARN的ResourceManager也存在單點故障問題,這個問題在hadoop-2.4.1獲得瞭解決:有兩個ResourceManager,一個是Active,一個是Standby,狀態由zookeeper進行協調。
YARN框架下的MapReduce能夠開啓JobHistoryServer來記錄歷史任務信息,不然只能查看當前正在執行的任務信息。
Zookeeper的做用是負責HDFS中NameNode主備節點的選舉,和YARN框架下ResourceManaer主備節點的選舉。
軟件版本
操做系統:CentOS Linux release 7.0.1406
JDK:Java(TM)SE Runtime Environment (build 1.7.0_79-b15)
Hadoop:Hadoop 2.6.0-cdh5.7.1
ZooKeeper:zookeeper-3.4.5-cdh5.7.1
Linux環境準備
集羣各節點進行以下修改配置:
建立用戶並添加權限
// 切換root用戶 $ su root // 建立hadoop用戶組 # groupadd hadoop // 在hadoop用戶組中建立hadoop用戶 # useradd -g hadoop hadoop // 修改用戶hadoop密碼 # passwd hadoop // 修改sudoers配置文件給hadoop用戶添加sudo權限 # vim /etc/sudoers hadoop ALL=(ALL) ALL // 測試是否添加權限成功 # exit $ sudo ls /root
修改IP地址和主機名
// 切換root用戶 $ su root // 修改本機IP地址 # vim /etc/sysconfig/network-scripts/ifcfg-eth0 // 重啓網絡服務 # service network restart // 修改主機名 # hostnamectl set-hostname 主機名 // 查看主機名 # hostnamectl status
設置IP地址與主機名映射
// 切換root用戶 $ su root // 編輯hosts文件 # vim /etc/hosts 172.16.20.81 hadoop-master1 172.16.20.82 hadoop-master2 172.16.20.83 hadoop-slave1 172.16.20.84 hadoop-slave2 172.16.20.85 hadoop-slave3
關閉防火牆和Selinux
// 切換root用戶 $ su root // 中止firewall防火牆 # systemctl stop firewalld.service // 禁止firewall開機啓動 # systemctl disable firewalld.service // 開機關閉Selinux # vim /etc/selinux/config SELINUX=disabled // 重啓機器後root用戶查看Selinux狀態 # getenforce
配置SSH免密碼登陸
// 在hadoop-master1節點生成SSH密鑰對 $ ssh-keygen -t rsa // 將公鑰複製到集羣全部節點機器上 $ ssh-copy-id hadoop-master1 $ ssh-copy-id hadoop-master2 $ ssh-copy-id hadoop-slave1 $ ssh-copy-id hadoop-slave2 $ ssh-copy-id hadoop-slave3 // 經過ssh登陸各節點測試是否免密碼登陸成功 $ ssh hadoop-master2 備註:在其他節點上執行一樣的操做,確保集羣中任意節點均可以ssh免密碼登陸到其它各節點。
安裝JDK
// 卸載系統自帶的openjdk $ suroot # rpm-qa | grep java # rpm-e --nodeps java-1.7.0-openjdk-1.7.0.75-2.5.4.2.el7_0.x86_64 # rpm-e --nodeps java-1.7.0-openjdk-headless-1.7.0.75-2.5.4.2.el7_0.x86_64 # rpm-e --nodeps tzdata-java-2015a-1.el7_0.noarch # exit // 解壓jdk安裝包 $ tar-xvf jdk-7u79-linux-x64.tar.gz // 刪除安裝包 $ rmjdk-7u79-linux-x64.tar.gz // 修改用戶環境變量 $ cd ~ $ vim.bash_profile exportJAVA_HOME=/home/hadoop/app/jdk1.7.0_79 exportPATH=$PATH:$JAVA_HOME/bin // 使修改的環境變量生效 $ source.bash_profile // 測試jdk是否安裝成功 $ java-version
集羣時間同步
若是集羣節點時間不一樣步,可能會出現節點宕機或引起其它異常問題,因此在生產環境中通常經過配置NTP服務器實現集羣時間同步。本集羣在hadoop-master1節點設置ntp服務器,具體方法以下:
// 切換root用戶 $ su root // 查看是否安裝ntp # rpm -qa | grep ntp // 安裝ntp # yum install -y ntp // 配置時間服務器 # vim /etc/ntp.conf # 禁止全部機器鏈接ntp服務器 restrict default ignore # 容許局域網內的全部機器鏈接ntp服務器 restrict 172.16.20.0 mask 255.255.255.0 nomodify notrap # 使用本機做爲時間服務器 server 127.127.1.0 // 啓動ntp服務器 # service ntpd start // 設置ntp服務器開機自動啓動 # chkconfig ntpd on 集羣其它節點經過執行crontab定時任務,天天在指定時間向ntp服務器進行時間同步,方法以下: // 切換root用戶 $ su root // 執行定時任務,天天00:00向服務器同步時間,並寫入日誌 # crontab -e 0 0 * * * /usr/sbin/ntpdate hadoop-master1>> /home/hadoop/ntpd.log // 查看任務 # crontab -l
本文地址:http://www.linuxprobe.com/hadoop-high-available.html