背景概述
單 NameNode 的架構使得 HDFS 在集群擴展性和性能上都有潛在的問題,當集群大到一定程度后,NameNode 進程使用的內存可能會達到上百 G,NameNode 成為了性能的瓶頸。因
而提出了 namenode 水平擴展方案-- Federation。
Federation 中文意思為聯邦,聯盟,是 NameNode 的 Federation,也就是會有多個NameNode。多個 NameNode 的情況意味着有多個 namespace(命名空間),區別於 HA 模式下的多 NameNode,它們是擁有着同一個 namespace。既然說到了 NameNode 的命名空間的概念,這里就看一下現有的 HDFS 數據管理架構,如下圖所示:
從上圖中,我們可以很明顯地看出現有的 HDFS 數據管理,數據存儲 2 層分層的結構.也就是說,所有關於存儲數據的信息和管理是放在 NameNode 這邊,而真實數據的存儲則是在各個 DataNode 下。而這些隸屬於同一個 NameNode 所管理的數據都是在同一個命名空間下的。而一個 namespace 對應一個 block pool。Block Pool 是同一個 namespace 下的 block 的集合.當然這是我們最常見的單個 namespace 的情況,也就是一個 NameNode 管理集群中所有元數據信息的時候.如果我們遇到了之前提到的 NameNode 內存使用過高的問題,這時候怎么辦?元數據空間依然還是在不斷增大,一味調高 NameNode 的 jvm 大小絕對不是一個持久的辦法.這時候就誕生了 HDFS Federation 的機制.
Federation 架構設計
HDFS Federation 是解決 namenode 內存瓶頸問題的水平橫向擴展方案。
Federation 意味着在集群中將會有多個 namenode/namespace。這些 namenode 之間是聯合的,也就是說,他們之間相互獨立且不需要互相協調,各自分工,管理自己的區域。分布式的 datanode 被用作通用的數據塊存儲存儲設備。每個 datanode 要向集群中所有的namenode 注冊,且周期性地向所有 namenode 發送心跳和塊報告,並執行來自所有 namenode的命令。
Federation 一個典型的例子就是上面提到的 NameNode 內存過高問題,我們完全可以將上面部分大的文件目錄移到另外一個NameNode上做管理. 更重要的一點在於,, 這些 NameNode是共享集群中所有的 e DataNode 的 , 它們還是在同一個集群內的 。
這時候在DataNode上就不僅僅存儲一個Block Pool下的數據了,而是多個(在DataNode的 datadir 所在目錄里面查看 BP-xx.xx.xx.xx 打頭的目錄)。
概括起來:
多個 NN 共用一個集群里的存儲資源,每個 NN 都可以單獨對外提供服務。
每個 NN 都會定義一個存儲池,有單獨的 id,每個 DN 都為所有存儲池提供存儲。
DN 會按照存儲池 id 向其對應的 NN 匯報塊信息,同時,DN 會向所有 NN 匯報本地存儲可用資源情況。
HDFS Federation不足
HDFS Federation 並沒有完全解決單點故障問題。雖然 namenode/namespace 存在多個,但是從單個 namenode/namespace 看,仍然存在單點故障:如果某個 namenode 掛掉了,其管理的相應的文件便不可以訪問。Federation中每個namenode仍然像之前HDFS上實現一樣,配有一個 secondary namenode,以便主 namenode 掛掉一下,用於還原元數據信息。
所以一般集群規模真的很大的時候,會采用 HA+Federation 的部署方案。也就是每個聯合的 namenodes 都是 ha 的。
Federation 示例配置
這是一個包含兩個 Namenode 的 Federation 示例配置:
<configuration>
<property>
<name>dfs.nameservices</name>
<value>ns1,ns2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1</name>
<value>nn-host1:rpc-port</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1</name>
<value>nn-host1:http-port</value>
</property>
<property>
<name>dfs.namenode.secondaryhttp-address.ns1</name>
<value>snn-host1:http-port</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns2</name>
<value>nn-host2:rpc-port</value>
</property>
<property>
<name>dfs.namenode.http-address.ns2</name>
<value>nn-host2:http-port</value>
</property>
<property>
<name>dfs.namenode.secondaryhttp-address.ns2</name>
<value>snn-host2:http-port</value>
</property>
.... Other common configuration ...
</configuration>