相比於 Hadoop 1.0,Hadoop 2.0 中的 HDFS 增長了兩個重大特性,HA 和 Federaion。HA 即爲 High Availability,用於解決 NameNode 單點故障問題,該特性經過熱備的方式爲主 NameNode 提供一個備用者,一旦主 NameNode 出現故障,能夠迅速切換至備 NameNode, 從而實現不間斷對外提供服務。Federation 即爲「聯邦」,該特性容許一個 HDFS 集羣中存在 多個 NameNode 同時對外提供服務,這些 NameNode 分管一部分目錄(水平切分),彼此之 間相互隔離,但共享底層的 DataNode 存儲資源。html
本文檔重點介紹 HDFS HA 和 Federation 的安裝部署方法。 node
在一個典型的 HDFS HA 場景中,一般由兩個 NameNode 組成,一個處於 active 狀態, 另外一個處於 standby 狀態。Active NameNode 對外提供服務,好比處理來自客戶端的 RPC 請 求,而 Standby NameNode 則不對外提供服務,僅同步 active namenode 的狀態,以便可以在 它失敗時快速進行切換。
爲了可以實時同步 Active 和 Standby 兩個 NameNode 的元數據信息(實際上 editlog), 需提供一個共享存儲系統,能夠是 NFS、QJM(Quorum Journal Manager)或者 Bookeeper, Active Namenode 將數據寫入共享存儲系統,而 Standby 監聽該系統,一旦發現有新數據寫 入,則讀取這些數據,並加載到本身內存中,以保證本身內存狀態與 Active NameNode 保持 基本一致,如此這般,在緊急狀況下 standby 即可快速切爲 active namenode。web
注意,在 Hadoop 2.0 中,再也不須要 secondary namenode 或者 backup namenode,它們的 工做由 Standby namenode 承擔。
本文將重點介紹基於 QJM 的 HA 解決方案。在該方案中,主備 NameNode 之間經過一組 JournalNode 同步元數據信息,一條數據只要成功寫入多數 JournalNode 即認爲寫入成功。 一般配置奇數個(2N+1)個 JournalNode,這樣,只要 N+1 個寫入成功就認爲數據寫入成功, 此時最多容忍 N-1 個 JournalNode 掛掉,好比 3 個 JournalNode 時,最多容許 1 個 JournalNode 掛掉,5 個 JournalNode 時,最多容許 2 個 JournalNode 掛掉。基於 QJM 的 HDFS 架構以下 所示:shell
NameNode 機器:推薦主備 NameNode 具備相同的硬件配置,且內存要足夠大。apache
JournalNode:一般準備 3 或 5 個 JournalNode,考慮到 JournalNode 很是輕量級,能夠與 Hadoop 其餘服務共用機器,好比 ResourceManager,TaskTracker 等。bootstrap
Zookeeper:因爲 Hadoop 多個服務用到了 Zookeeper,可搭建一個 3 或者 5 個節點的Zookeeper 實例做爲公共服務。Zookeeper 實例也能夠與其餘服務共用機器。安全
NameNode 機器:推薦主備 NameNode 具備相同的硬件配置,且內存要足夠大。session
JournalNode:一般準備 3 或 5 個 JournalNode,考慮到 JournalNode 很是輕量級,能夠與 Hadoop 其餘服務共用機器,好比 ResourceManager,TaskTracker 等。架構
Zookeeper:因爲 Hadoop 多個服務用到了 Zookeeper,可搭建一個 3 或者 5 個節點的Zookeeper 實例做爲公共服務。Zookeeper 實例也能夠與其餘服務共用機器。ssh
NameNode 機器:推薦主備 NameNode 具備相同的硬件配置,且內存要足夠大。
JournalNode:一般準備 3 或 5 個 JournalNode,考慮到 JournalNode 很是輕量級,能夠與 Hadoop 其餘服務共用機器,好比 ResourceManager,TaskTracker 等。
Zookeeper:因爲 Hadoop 多個服務用到了 Zookeeper,可搭建一個 3 或者 5 個節點的Zookeeper 實例做爲公共服務。Zookeeper 實例也能夠與其餘服務共用機器。
<property> <name>dfs.nameservices</name> <value>nn</value> <description>Logical name for this new nameservice</description> </property>
hdfs-federation配置,可同時有多個namenode服務:
<property> <name>dfs.federation.nameservices</name> <value>nn1,nn2</value> <description>Logical name for this new nameservice</description> </property>
某個命名服務下包含的 NameNode 列表,可爲每一個 NameNode 指定一個自定義的 ID 名稱,好比命名服務 nn 下有兩個 NameNode,分別命名爲 nn1 和 nn2,則配置以下:
<property> <name>dfs.ha.namenodes.nn</name> <value>nn1,nn2</value> <description>Unique identifiers for each NameNode in the nameservice </description> </property>
注意,目前每一個命名服務最多配置兩個 NameNode
爲每一個 NameNode 設置 RPC 地址,之前面的實例爲例,可進行以下配置:
<property> <name>dfs.namenode.rpc-address.nn.nn1</name> <value>nn1:9000</value> </property> <property> <name>dfs.namenode.rpc-address.nn.nn2</name> <value>nn2:9000</value> </property>
爲每一個 NameNode 設置對外的 HTTP 地址,之前面的實例爲例,可進行以下配置:
<property> <name>dfs.namenode.http-address.nn.nn1</name> <value>192.168.10.110:50070</value> </property> <property> <name>dfs.namenode.http-address.nn.nn2</name> <value>192.168.10.111:50070</value> </property>
設置一組 journalNode 的 URI 地址,active NameNode 將 edit log 寫入這些JournalNode,而 standby NameNode 讀取這些 edit log,並做用在內存中的目錄樹中,該屬性 值應符合如下格式:
qjournal://host1:port1;host2:port2;host3:port3/journalId
其中,journalId 是該命名空間的惟一 ID。假設你有三臺 journalNode,即 dn1, dn2 和 dn3,則可進行以下配置:
<property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://dn1:8485;dn2:8485; dn3:8485;dn4:8485;dn6:8485/nn</value> </property>
注意,JournalNode 默認端口號爲 8485
設置客戶端與 active NameNode 進行交互的 Java 實現類,DFS 客戶端經過該類尋找當前的 active NameNode。該類可由用戶本身實現,默認實現爲 ConfiguredFailoverProxyProvider。
<property> <name>dfs.client.failover.proxy.provider.nn</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>
你能夠配置一個 ssh 用戶和端口號,並設置一個超時時間,一旦 ssh 超過該時間,則認爲執 行失敗。
<property> <name>dfs.ha.fencing.methods</name> <value>sshfence([[username][:port]])</value> </property> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property>
2) shell
執行任意一個 shell 命令隔離舊的 active NameNode,配置方法以下:
<property> <name>dfs.ha.fencing.methods</name> <value>shell(/path/to/my/script.sh arg1 arg2 ...)</value> (這裏沒搞懂) </property>
注意,Hadoop 中全部參數將以環境變量的形似提供給該 shell,但全部的「.」被替換成了「_」, 好比「dfs.namenode.rpc-address.ns1.nn1」變爲「dfs_namenode_rpc-address」
設置缺省的目錄前綴,需在 core-site.xml 中設置,好比命名服務的 ID 爲 mycluster(參 數 dfs.nameservices 指定的),則配置以下:
<property> <name>fs.defaultFS</name> <value>hdfs://nn</value> </property>
JournalNode 所在節點上的一個目錄,用於存放 editlog 和其餘狀態信息。該參數只能設置一個目錄,你能夠對磁盤作 RIAD 提升數據可靠性。
<property> <name>dfs.journalnode.edits.dir</name> <value>/opt/journal/node/local/data</value> </property>