Hadoop源碼分析-HDFS架構(gòu)演進(jìn)

[TOC]

本文嘗試說明下面三個問題

  1. HDFS 如何實現(xiàn)有狀態(tài)的高可用架構(gòu)
  2. HDFS 如何解決單機(jī)內(nèi)存受限問題
  3. HDFS 支持億級流量的密碼
  4. SecondaryNameNode 作用

1. HDFS 如何實現(xiàn)有狀態(tài)的高可用架構(gòu)

1.1 HDFS 架構(gòu)演進(jìn)之路

Hadoop 大版本有三個,Hadoop1、hadoop2、Hadoop3,對應(yīng)的HDFS 也有三個版本 HDFS1、HDFS2、HDFS3,本文會介紹 三個版本之間的架構(gòu)區(qū)別


1

1.2 HDFS1 架構(gòu)

HDFS 是一個分布式的文件系統(tǒng), 它是一個主從式的架構(gòu),其核心組件就是 NameNode(主節(jié)點,一個) 和 DataNode(從節(jié)點,多個)。

Namenode 主要是接收客戶端的請求和負(fù)責(zé)元數(shù)據(jù)管理,而 Datanode 主要就是負(fù)責(zé)存儲數(shù)據(jù)。Datanode 中存儲的數(shù)據(jù)都是一個個的塊,每個塊大小默認(rèn) 64M

具體使用一個客戶端上傳數(shù)據(jù)的示例來說明:

  1. HDFS 會把用戶上傳的文件切分成很多個 block,默認(rèn) 每個 block 大小是64M,
  2. 然后把這些 block 存儲在不同的 datanode 上,并且為每個 block 生成 3 個副本。
  3. 而每個 block 存在哪個 datanode上以及哪些 block 屬于一個文件這些信息都存儲在 Namanode 上,這些數(shù)據(jù)就是元數(shù)據(jù)
  4. Namanode 為了快速響應(yīng)用戶的請求,還會把這些元數(shù)據(jù)放到內(nèi)存中。

下面是一個簡單的 HDFS1 的架構(gòu)圖


2

1.3 HDFS2 架構(gòu)-實現(xiàn)有狀態(tài)的高可用架構(gòu)

雖然 HDFS1 解決了分布式存儲的問題,但是他的設(shè)計還是有一些缺陷,比如:

  1. 單點問題:因為 HDFS1 中只有一個 Namenode ,而所有的元數(shù)據(jù)信息都存儲在 Namenode 上,而一旦 Namenode 出現(xiàn)問題,所有的元數(shù)據(jù)就會丟失,而整個集群也就無法使用了
  2. 內(nèi)存受限問題:Namenode 為了快速響應(yīng)用戶的請求,會把所有元數(shù)據(jù)信息放到內(nèi)存中,隨著時間的推移,元數(shù)據(jù)信息增多,必然會撐爆內(nèi)存

基于這個兩個問題,HDFS2 誕生了,HDFS2 使用 HA 解決單點問題,使用 聯(lián)邦 解決內(nèi)存受限問題。

1.3.1 HDFS2 架構(gòu)-實現(xiàn)有狀態(tài)的高可用架構(gòu)

其實解決單點的問題,最直接的辦法就是在引入一個主節(jié)點(Namenode)唄。只要有兩個 Namenode,并且兩個Namenode的數(shù)據(jù)一致,當(dāng)其中一個壞掉時,使用另一個替換就可以了。其實HDFS2就是這么解決的。

image

HDFS2 又引入了一個 Namenode 并且給 Namenode 增加了狀態(tài),一個是 Active 狀態(tài)的,一個 Standby 狀態(tài)的,工作中由 Active 的 Namenode 負(fù)責(zé)接受用戶的操作請求,當(dāng) Active 的 Namenode 異常時,Standby 狀態(tài)的 Namenode 會切換狀態(tài)變?yōu)?Active 狀態(tài)。

但是這樣就會引入另外幾個問題:

  1. 一個是 Namenode 間的數(shù)據(jù)同步
  2. 一個是 Namenode 間的狀態(tài)自動切換

下面具體講解下,HDFS2 如何解決這兩個問題:

1.3.2 Namenode 間的數(shù)據(jù)同步

兩個 Namenode 要能達(dá)到切換的條件,必然是兩個 Namenode 的元數(shù)據(jù)要一直,那么如何保證兩個 Namenode 的元數(shù)據(jù)一致呢。HDFS 引入了 JournalNode 集群(類似zookeeper),該集群能保證數(shù)據(jù)的一致性。

在工作中, Active 的 Namenode 會向 JournalNode 同步新的元數(shù)據(jù)信息,而 Standby 的 Namenode 回讀 JournalNode 的元數(shù)據(jù)信息。一旦 Active 的 Namenode 出現(xiàn)異常,Standby 的 Namenode 會隨時切換為 Active。

1.3.3 Namenode 間的狀態(tài)自動切換

那么 Standby 的 Namenode 如何切換 Active 呢?HDFS 又引入了 zookeeper 集群,并且為每個 Namenode 增加了一個 zkfc 的服務(wù)。
zkfc 會定時監(jiān)控 Namenode 的狀態(tài),一旦 Namenode 狀態(tài)異常就會退出 zk的選舉列表。

HDFS2 具體的架構(gòu)圖如下:

image

提示:

  1. JournalNode 集群多少臺合適?
    JournalNode 在實際工作中的壓力很小,一般 200 臺以上使用 3 臺 Journalnode 足夠了,200臺以上使用5臺基本都解決了
  2. JournalNode 集群是否可以使用 zookeeper 替代
    其實是可以的,當(dāng)時這個具體要自己該源碼去實現(xiàn)

2. HDFS 如何解決單機(jī)內(nèi)存受限問題

其實解決內(nèi)存受限跟解決單點的思路類似,既然一臺主機(jī)不行就引入多臺

image

乍一看圖跟 HA 的第一個圖是一樣的,但是實現(xiàn)不同,HA里的兩個 Namenode 數(shù)據(jù)是要一致的,而這里的 Namenode 數(shù)據(jù)必須是不一樣的 (雖然圖上看不出區(qū)別),否則就沒有解決內(nèi)存受限的問題。這個就是 Namenode 的聯(lián)邦。

那 Namenode HA + 聯(lián)邦 后的架構(gòu)圖就如下:

image

可以看到我們需要為 聯(lián)邦 內(nèi)的每個 Namenode 提供 HA.

但這樣就會又引入一個問題,就是用戶訪問數(shù)據(jù)的時候到底應(yīng)該訪問哪個 Namenode 呢?

  1. 其實這個就類似數(shù)據(jù)庫的分庫分表一樣,需要提供一個路由的方案來解決訪問的問題,這個路由 Hadoop 并沒有提供,需要自己封裝。
  2. 或者可以 分業(yè)務(wù)存儲,比如 A 業(yè)務(wù)都存儲到 Namenode1 ,B 業(yè)務(wù)都使用 Namenode2,這樣就簡單解決了。

提示:

  1. 一般沒有必要的話,不建議使用聯(lián)邦(規(guī)模 1萬臺以下的集群)

3. HDFS 支持億級流量的密碼

3.1 HDFS 支持的億級流量具體什么?

這里所屬的支持億級流量具體是指客戶端的請求,因為 Namenode 管理元數(shù)據(jù),所有任務(wù)在執(zhí)行的時候都要請求 Namenode 的元數(shù)據(jù),而一旦任務(wù)多了這個請求量還是很可觀的。因為像大的企業(yè)上動不動就幾十萬,甚至上百萬的任務(wù),每個任務(wù)再有幾十個請求,那每天幾千萬的訪問量還是有的。

所以 Namenode 必須可以應(yīng)對 億級 的元數(shù)據(jù)請求,為了應(yīng)對這么大流量的訪問所以 Namenode 才把所有的元數(shù)據(jù)信息都放到內(nèi)存中了。但是又為了數(shù)據(jù)安全,Namenode 又會把 元數(shù)據(jù)信息放到磁盤上,且為了 HA 元數(shù)據(jù)還得寫到 JournalNode 集群中。

那問題就來了,如果元數(shù)據(jù)只內(nèi)存中,當(dāng)然能夠支持億級的請求,但是又要寫磁盤,又要寫 JournalNod ,Namenode 如何解決的呢?其實 Namenode 在管理元數(shù)據(jù)的時候,使用了兩個方法來解決此問題:
那就是 雙緩沖分端加鎖

3.2 雙緩沖

雙緩沖其實就是兩塊內(nèi)存(代碼里其實就是兩個list)

image

Namenode 在接收客戶端的元數(shù)據(jù)操作請求時,是先把數(shù)據(jù)寫入內(nèi)存1中,當(dāng)內(nèi)存1中的數(shù)據(jù)寫到一定程度的時候,把內(nèi)存1內(nèi)存2交換(這里是指針交換,不是內(nèi)存的copy),然后把交換后的內(nèi)存刷新到磁盤或者Journalnode中。

具體的實現(xiàn)大概如圖:


image

3.3 分段加鎖

在 Namenode 元數(shù)據(jù)管理這塊,HDFS 使用了多線程去實現(xiàn)的,很多地方加了使用 synchronized 加了鎖,但是它并沒有對所有代碼加鎖,而是只對有線程安全問題的地方加鎖。

這塊具體的需要看源碼。

4. SecondaryNameNode 作用

在 HDFS 中 還有一個 服務(wù)叫 SecondaryNameNode,在HDFS1中,他的作用很重要,主要是為了合并 Fsimage 和 Editlog 的。
在講 SecondaryNameNode 之前,先說下 Fsimage 和 Editlog 。
在上面我們介紹過,其實 Namendoe 的元數(shù)據(jù)是存儲在磁盤上的,實際上所有的歷史元數(shù)據(jù)都會在 Fsimage 文件中,而新增的元數(shù)據(jù)信息是存儲在 Editlog 中的。當(dāng) Namenode 啟動的時候是會合并 Fsimage 和 Editlog 文件,并且把他們都讀入內(nèi)存中。
這就有個問題,如果 Editlog 文件過多(Editlog 可以有很多個)了,在合并的時候就會很耗時,然后拖慢 Namenode 的啟動,所以防止 Editlog 文件過多,就引入 SecondaryNameNode 服務(wù),定期合并 Fsimage 和 Edit 文件。

具體的合并流程如圖:


image

SecondaryNameNode 本地最開始也有一個與Namenode一樣的 Fsimage 文件,然后定期去拉取 Editlog 文件到本地,然后與自己的 Fsimage 合并,合并成功后,去替換 Namenode 中的 Fsimage ,并刪除已經(jīng)合并的 Editlog 文件

點擊這里查看原文地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容