Hadoop 原理學(xué)習(xí)——HDFS 架構(gòu)與工作原理

一、目標(biāo)

HDFS 全稱?hadoop?分布式文件系統(tǒng),其最主要的作用是作為 Hadoop 生態(tài)中各系統(tǒng)的存儲(chǔ)服務(wù)。

面對(duì)大規(guī)模的數(shù)據(jù),HDFS 在設(shè)計(jì)上滿足了以下目標(biāo):

高度容錯(cuò)性:HDFS 可能由成百上千的服務(wù)器構(gòu)成,任何一個(gè)組件都可能失效,因此錯(cuò)誤檢測和快速、自動(dòng)的恢復(fù)時(shí) HDFS 最核心的架構(gòu)目標(biāo)。

支持大規(guī)模數(shù)據(jù)集:運(yùn)行在 HDFS 應(yīng)用具有很大的數(shù)據(jù)集,它應(yīng)該能提供整體上高的數(shù)據(jù)傳輸帶寬,并能支撐數(shù)以千萬計(jì)的文件。

支持流式讀取數(shù)據(jù):HDFS 的設(shè)計(jì)更多的考慮到了數(shù)據(jù)批處理,而不是用戶交互處理,比之?dāng)?shù)據(jù)訪問延遲的問題,更關(guān)鍵的是數(shù)據(jù)訪問的高吞吐量。

簡單的一致性模型:“一次寫入多次讀取”的文件訪問模型簡化了數(shù)據(jù)一致性的問題,并且是高吞吐量稱為可能。

移動(dòng)計(jì)算而非移動(dòng)數(shù)據(jù):一個(gè)應(yīng)用的請(qǐng)求,離它操作的數(shù)據(jù)越近就越高效,HDFS 提供了將它們自己移動(dòng)到數(shù)據(jù)附近的接口。

異構(gòu)軟硬件平臺(tái)間的可移植性:平臺(tái)的可移植性,方便用戶也方便 HDFS 作為大規(guī)模數(shù)據(jù)應(yīng)用平臺(tái)的推廣。

那么通過以上目標(biāo),HDFS 被設(shè)計(jì)成了什么樣的架構(gòu)呢?

二、架構(gòu)與原理

1. HDFS 服務(wù)

根據(jù) Cloudera Manager 安裝 hadoop 2.6.0-cdh5.8.3 版本后,得到如下的 HDFS 服務(wù):

如上圖所示,HDFS 使用單一的 NameNode 節(jié)點(diǎn)簡化了整體的設(shè)計(jì),同時(shí)使用 Master-Slave 模式,防止 NameNode 成為單點(diǎn)故障,F(xiàn)ailover Controller(故障切換器)的工作便是負(fù)責(zé)監(jiān)控 NameNode 的狀態(tài)與切換主從服務(wù)器。與此同時(shí),為了能夠快速從故障中恢復(fù),每一次的數(shù)據(jù)讀寫刪操作都會(huì)記錄在 NameNode 上的 EditLog 中并同步到每個(gè) JournalNode 節(jié)點(diǎn)。而 DataNode 節(jié)點(diǎn)則負(fù)責(zé)存儲(chǔ)物理數(shù)據(jù),為了應(yīng)對(duì)不確定的故障,每一份數(shù)據(jù)默認(rèn)被保存為 3 份,并分散在不同的 DataNode 中,而通過 Balancer 則可以平衡集群之間各節(jié)點(diǎn)的磁盤利用率,以防止某一個(gè) DataNode 節(jié)點(diǎn)存儲(chǔ)已滿但是其它 DataNode 節(jié)點(diǎn)卻可能為空的情況。

最后為了方便用戶操作,HDFS 提供了 HttpFS 服務(wù),用以通過 HTTP 方式訪問 HDFS 服務(wù)的功能。默認(rèn)的,你可以通過 http://[master namenode host]:50070/ 訪問這個(gè)功能。

總的來說,HDFS 主要包含了 6 個(gè)服務(wù),它們主要的功能如下:

NameNode:負(fù)責(zé)管理文件系統(tǒng)的 namespace 以及客戶端對(duì)文件的訪問;

DataNode:用于管理它所在節(jié)點(diǎn)上的存儲(chǔ);

FailoverController:故障切換控制器,負(fù)責(zé)監(jiān)控與切換 Namenode 服務(wù);

JournalNode:用于存儲(chǔ) EditLog;

Balancer:用于平衡集群之間各節(jié)點(diǎn)的磁盤利用率;

HttpFS:提供 HTTP 方式訪問 HDFS 的功能。

通常而言,在關(guān)注 HDFS 架構(gòu)時(shí),總是關(guān)注 Namenode 和 Datanode 的架構(gòu),因?yàn)樗鼈兪?HDFS 的核心,也是客戶端操作數(shù)據(jù)需要依賴的兩個(gè)服務(wù),所以再來看看 Namenode & Datanode 的架構(gòu)吧。

2. NameNode & DataNode

在 HDFS 中,Namenode 是 HDFS 中的主節(jié)點(diǎn),用于維護(hù)和管理 Datanode 上存在的 block。它是一個(gè)高度可用的服務(wù)器,用于管理文件的 namespace 并控制客戶端對(duì)文件的訪問。HDFS 體系的構(gòu)建方式是,用戶數(shù)據(jù)永遠(yuǎn)不會(huì)駐留在 Namenode 上,數(shù)據(jù)只會(huì)駐留在 Datanode 上。

Namenode 的功能:

它是維護(hù)和管理 Datanode 的主守護(hù)進(jìn)程;

它記錄存儲(chǔ)在集群中的所有文件的元數(shù)據(jù),例如 block 的位置、文件大小、權(quán)限、層次結(jié)構(gòu)等。有兩個(gè)文件與元數(shù)據(jù)關(guān)聯(lián):

FsImage:它包含自 Namenode 開始以來文件的 namespace 的完整狀態(tài);

EditLogs:它包含最近對(duì)文件系統(tǒng)進(jìn)行的與最新 FsImage 相關(guān)的所有修改。

它記錄了發(fā)生在文件系統(tǒng)元數(shù)據(jù)上的每個(gè)更改。例如,如果一個(gè)文件在 HDFS 中被刪除,Namenode 會(huì)立即在 EditLog 中記錄這個(gè)操作。

它定期從集群中的所有 Datanode 接收心跳信息和 block 報(bào)告,以確保 Datanode 處于活動(dòng)狀態(tài);

它保留了 HDFS 中所有 block 的記錄以及這些 block 所在的節(jié)點(diǎn);

它負(fù)責(zé)管理所有 block 的復(fù)制;

在 Datanode 失敗的情況下,Namenode 會(huì)為副本選擇新的 Datanode,平衡磁盤使用并管理到 Datanode 的通信流量。

Datanode 則是 HDFS 中的從節(jié)點(diǎn),與 Namenode 不同的是,Datanode 是一種商品硬件,它并不具有高質(zhì)量或高可用性。Datanode 是一個(gè)將數(shù)據(jù)存儲(chǔ)在本地文件 ext3 或 ext4 中的 block 服務(wù)器。

Datanode 功能:

這些是叢屬守護(hù)進(jìn)行或在每臺(tái)從屬機(jī)器上運(yùn)行的進(jìn)程;

實(shí)際的數(shù)據(jù)存儲(chǔ)在 Datanode 上;

執(zhí)行文件系統(tǒng)客戶端底層的讀寫請(qǐng)求;

定期向 Namenode 發(fā)送心跳報(bào)告 HDFS 的整體健康狀況,默認(rèn)頻率為 3 秒。

上面提到 HDFS 中的數(shù)據(jù)是以 block 的形式分散在 DataNode 中,那什么是 block ,它是如何形成的呢?

3. 數(shù)據(jù)塊(Block)

通常,在任何文件系統(tǒng)中,都將數(shù)據(jù)存儲(chǔ)為 block 的集合。block 是硬盤上存儲(chǔ)數(shù)據(jù)的最不連續(xù)的位置。在 hadoop 集群中,每個(gè) block 的默認(rèn)大小為 128M(此處指 hadoop 2.x 版本,hadoop 1.x 版本為 64M),您也可以通過如下配置配置 block 的大小:

dfs.block.size或 dfs.blocksize =64M

HDFS 不會(huì)將每個(gè)文件存儲(chǔ)在配置的 block 大小的確切倍數(shù)中,比如一個(gè) 514M 的文件 example.txt,如果上圖所示,假設(shè) block 大小為默認(rèn)的 128M,那么將會(huì)創(chuàng)建 5 個(gè)block,前 4 個(gè) block 大小為 128M,但是最后一個(gè) block 的大小則僅為 2M。

那么,為何需要將 block 的大小設(shè)置為如此大,比如 128M,而不是更小呢?

通常我們?cè)谡務(wù)?HDFS 的作用的時(shí),都會(huì)談?wù)摰骄薮蟮臄?shù)據(jù)集,即 Terabytes 和 PB 數(shù)據(jù),所以如果我們的 block 大小僅為 4KB,那么將會(huì)產(chǎn)生太多的 block,間接導(dǎo)致產(chǎn)生太多的元數(shù)據(jù),從而使管理這些 block 和 元數(shù)據(jù)會(huì)產(chǎn)生巨大的開銷,這樣無疑會(huì)增加 Namenode 和 Datanode 的負(fù)載,尤其 Namenode 是一個(gè)中心服務(wù)器,所以這并不會(huì)是我們想要的。

4. 數(shù)據(jù)復(fù)制

HDFS 提供了一種將大數(shù)據(jù)作為數(shù)據(jù)塊存儲(chǔ)在分布式環(huán)境中的可靠方法,即將這些 block 復(fù)制以容錯(cuò)。默認(rèn)的復(fù)制因子是 3,您也可以通過如下配置配置復(fù)制因子:

fs.replication = 3

因此,如下圖所示,每個(gè) block 被復(fù)制 3 次存儲(chǔ)在不同的 Datanode 中。

所以,如果使用默認(rèn)配置在 HDFS 中存儲(chǔ) 128M 的文件,則最終將占用 384M (3 * 128M)的空間,因?yàn)檫@些 block 將被復(fù)制 3 次,并且每個(gè)副本將駐留在不同的 Datanode 中。

注意:Namenode 會(huì)定期的 從 Datanode 中收集 block 報(bào)告以維護(hù)復(fù)制因子。因此,無論何時(shí) block 被過度復(fù)制或復(fù)制不足,Namenode 都會(huì)根據(jù)需要?jiǎng)h除或添加副本。

5. 元數(shù)據(jù)

我們知道,Namenode 對(duì)我們來說相當(dāng)?shù)闹匾绻×耍覀冏⒍ㄒ 2贿^ HDFS 有對(duì)它做高可用的解決方案,高可用的方案中,如何同步狀態(tài)是一個(gè)關(guān)鍵,所以這里再介紹一下那些保存在 Namenode 上的元數(shù)據(jù)。

注:以下元數(shù)據(jù)同步的方式使用的是通過JournalNode 節(jié)點(diǎn)同步的方式。

NameNode 將整個(gè) namespace ,包括 block 到文件的映射、文件的屬性等,都存儲(chǔ)在一個(gè)稱為 FsImage 的文件中,它被存放在內(nèi)存以及本地文件系統(tǒng)中。而任何對(duì)于 namespace 元數(shù)據(jù)產(chǎn)生修改的操作,NameNode 都會(huì)使用一種稱為 EditLog 的事務(wù)日志記錄下來。例如在 HDFS 中創(chuàng)建一個(gè)文件,NameNode 就會(huì)在 EditLog 中插入一條記錄來表示;同樣的,修改文件的副本系數(shù)也將往 EditLog 插入一條記錄。主 NameNode 會(huì)在本地文件系統(tǒng)中存儲(chǔ)這個(gè) EditLog,并同步到各個(gè) JournalNode 節(jié)點(diǎn)上,而從 NameNode 則通過在 JournalNode 節(jié)點(diǎn)中讀取 EditLog 來完成同步。

當(dāng) NameNode 啟動(dòng)時(shí),它會(huì)從硬盤中讀取 EditLog 和 FsImage,將所有 EditLog 中的事務(wù)作用在內(nèi)存中的 FsImage 上,并將這個(gè)新版本的 FsImage 從內(nèi)存中保存到本地磁盤上,然后刪除舊的 EditLog,這個(gè)過程也被稱為一個(gè) checkpoint。

那么通過 NameNode 上的元數(shù)據(jù)可以確定 block 到具體 DataNode 節(jié)點(diǎn)的一個(gè)映射,所以客戶端在讀取或者寫入數(shù)據(jù)到 HDFS 時(shí),都是先到 NameNode 上獲取元數(shù)據(jù),然后根據(jù)元數(shù)據(jù)中的地址直接與 DataNode 交互,與此同時(shí),客戶端會(huì)緩存一段時(shí)間的元數(shù)據(jù),從而減少與 NameNode 的交互。

那么一個(gè)完整的讀取和寫入流程是怎樣的呢?

6. 數(shù)據(jù)寫入原理

假如 HDFS 客戶端想要寫入一個(gè)名為 “example.txt” 的大小為 128MB 的文件。

假定系統(tǒng) block 的配置大小為 128MB(默認(rèn)),那么客戶端將把文件 “example.txt” 分成 2 個(gè) block - 128 MB(block A) + 128MB(block B)。

接下來,每當(dāng)客戶端將數(shù)據(jù)寫入 HDFS 時(shí),將遵循以下協(xié)議:

首先,HDFS 客戶端將與 NameNode 聯(lián)系以獲得針對(duì)兩個(gè) block(例如 block A 和 block B)的寫入請(qǐng)求;

然后,NameNode 將授予客戶端寫入權(quán)限,并將提供最終將復(fù)制文件的 DataNode 的 IP 地址。

根據(jù) HDFS 的可用性,復(fù)制因素和機(jī)架感知,DataNode IP 地址的選擇純碎是隨機(jī)的。

假設(shè)復(fù)制因子被設(shè)置成默認(rèn)值 3,那么對(duì)于每個(gè) block,NameNode 將向客戶端提供 3 個(gè) DataNode 的 IP 地址列表。該列表對(duì)于每個(gè) block 都是唯一的。假設(shè)分配結(jié)果如下:

對(duì)于 block A,列表 A = { DN 1 IP, DN 4 IP, DN 6 IP }

對(duì)于 block B,列表 B ={DN 3 IP, DN 7 IP, DN 9 IP}

每個(gè) block 將被復(fù)制到 3 個(gè)不同的 DataNode 中,以保持整個(gè)集群中復(fù)制因子的一致。

接下來,整個(gè)數(shù)據(jù)的復(fù)制將分為 3 個(gè)階段進(jìn)行: 1) 管道設(shè)置 2) 數(shù)據(jù)流和復(fù)制 3) 管道關(guān)閉與確認(rèn)階段

1) 管道設(shè)置

在寫入 block 之前,客戶端確認(rèn)每個(gè) IP 列表中的 DataNode 是否準(zhǔn)備好接受數(shù)據(jù),這樣做時(shí),客戶端會(huì)通過連接該 block 列表中的各個(gè) DataNode,為每個(gè) block 創(chuàng)建一個(gè)管道。比如 block A,它提供的 DataNode 列表是: 列表 A = { DN 1 IP, DN 4 IP, DN 6 IP }

因此,對(duì)于 block A,客戶端將創(chuàng)建以下步驟來創(chuàng)建管道:

客戶端將選擇列表中的第一個(gè) DataNode (DN1)并建立 TCP/IP 連接;

客戶端將通知 DN 1 準(zhǔn)備好接收該 block,它還會(huì)將下兩個(gè) DataNode(DN 4, 6)的 IP 地址提供給 DN 1;

DN 1 將連接 DN 4,并通知 DN 4 準(zhǔn)備好接受該 block,同時(shí)將 DN 6 的 IP 地址告知給 DN 4。然后 DN 4 將告訴 DN 6 準(zhǔn)備好接受數(shù)據(jù);

接下來,準(zhǔn)備就緒的確認(rèn)將遵循相反的順序,即從 DN 6 -> DB 4 -> DN 1;

最后 DN 1 將通知客戶端所有的 DataNode 都以準(zhǔn)備就緒,并且將在 DataNode 1,4 和 6 之間形成管道;

現(xiàn)在,管道設(shè)置完成,客戶端將最終的數(shù)據(jù)以流式方式處理。

2) 數(shù)據(jù)流

由于管道已經(jīng)創(chuàng)建,客戶端會(huì)將數(shù)據(jù)推送到管道中。不過不要忘記,在 HDFS 中,數(shù)據(jù)是基于復(fù)制因子進(jìn)行復(fù)制的,所以,在假設(shè)復(fù)制因子為 3 時(shí),block A 將存儲(chǔ)到 3 個(gè) DataNode 中。移動(dòng)到最前的,客戶端僅僅是將 block A 復(fù)制到 DN1。復(fù)制總是按照順序進(jìn)行的。

因此,在復(fù)制過程中將執(zhí)行以下的步驟:

一旦該 block 被客戶端寫入 DN 1,DN 1 將連接到 DN 4;

然后,DN 1 將推送管道中的 block,數(shù)據(jù)將被復(fù)制到 DN 4;

同樣的 DN 4 將連接到 DN 6 并將 block 復(fù)制為最后一個(gè)副本。

3) 管道關(guān)閉與確認(rèn)階段

一旦 block 被復(fù)制到所有的 3 個(gè) DataNode 中,就會(huì)發(fā)生一系列的確認(rèn)操作,以確保客戶端和 NameNode 確信數(shù)據(jù)已經(jīng)寫入成功。然后客戶端將最終關(guān)閉管道以結(jié)束 TCP 會(huì)話。

如下圖所示,確認(rèn)以相反的順序發(fā)生,即從 DN 6 到 DN 4,再到 DN 1。最后,DN 1 將把 3 個(gè)確認(rèn)(包括它自己的)推送到流水線中并發(fā)送給客戶端,客戶端將通知 NameNode 數(shù)據(jù)已經(jīng)成功寫入。此時(shí),NameNode 將更新元數(shù)據(jù),客戶端將關(guān)閉管道。

類似的,block B 也將被復(fù)制到與 block B 并行的 DataNode 中,因此,這里需要注意一下幾點(diǎn):

客戶端將同時(shí)將 block A 和 block B 復(fù)制到第一個(gè) DataNode 上;

因此,在這個(gè)示例下,將為兩個(gè) block 形成兩條管道,上述所有過程將在這兩天管道中并行發(fā)生;

客戶端將該 block 寫入第一個(gè) DataNode,然后 DataNode 將順序復(fù)制該 block

如上圖所示,客戶端為兩個(gè) block 一共創(chuàng)建了兩個(gè)管道,以下是各個(gè)管道中每個(gè) block 正在進(jìn)行的操作流程:

block A 的管道:1A -> 2A -> 3A -> 4A

block B 的管道:1B -> 2B -> 3B -> 4B -> 5B -> 6B

7. 數(shù)據(jù)寫入實(shí)現(xiàn)

寫入數(shù)據(jù)的詳細(xì)流程: 1) 客戶端通過在 DistributedFileSystem 上調(diào)用 create() 方法來創(chuàng)建文件(步驟1);

2) DistributedFileSystem 對(duì) NameNode 進(jìn)行 RPC 調(diào)用,以在文件系統(tǒng)的 namespace 中創(chuàng)建一個(gè)新的文件,此時(shí)沒有與之關(guān)聯(lián)的 block(步驟2)(NameNode 會(huì)執(zhí)行各種檢查以確保文件不存在,并且確保客戶端具有創(chuàng)建文件的正確權(quán)限。只有通過了這些檢查,才會(huì)創(chuàng)建新文件成功,否則客戶端拋出 IOException)

3) DistributedFileSystem 返回一個(gè) FSDataOutputStream 對(duì)象以開始寫入數(shù)據(jù)。與讀取數(shù)據(jù)一樣,F(xiàn)SDataOutputStream 封裝了一個(gè) DFSOutputStream 對(duì)象,它處理與DataNode 和 NameNode 的通信。當(dāng)客戶端開始寫入數(shù)據(jù)(步驟3)時(shí),DFSOutputStream 將其拆分成數(shù)據(jù)包(packet),寫入內(nèi)部的數(shù)據(jù)隊(duì)列,數(shù)據(jù)隊(duì)列由 DataStreamer 使用,它通過選擇合適的 DataNode 列表來存儲(chǔ)副本,從而要求 NameNode 分配新的 block。DataNode列表會(huì)形成一個(gè)管道(假設(shè)副本數(shù)為3),其中包含3個(gè)節(jié)點(diǎn)。

4) DataStreamer 將數(shù)據(jù)包以流式傳輸?shù)姆绞絺鬏數(shù)搅魉€中的第一個(gè) DataNode,該數(shù)據(jù)流將數(shù)據(jù)包存儲(chǔ)到第一個(gè) DataNode 中并將其轉(zhuǎn)發(fā)到流水線中的第二個(gè) DataNode。類似地,第二個(gè) DataNode 節(jié)點(diǎn)會(huì)將數(shù)據(jù)包轉(zhuǎn)發(fā)到流水線中的第三個(gè) DataNode 節(jié)點(diǎn)(步驟4);

5) DFSOutputStream 還維護(hù)了一個(gè)正在等待的數(shù)據(jù)包的內(nèi)部的 ack 隊(duì)列,由 DataNode 確認(rèn)。只有在流水線中的書友 DataNode 節(jié)點(diǎn)都確認(rèn)了數(shù)據(jù)包(步驟5)后才會(huì)將數(shù)據(jù)包從 ack 隊(duì)列中刪除;

6) 如果數(shù)據(jù)在寫入過程中發(fā)生故障,那么:(1) 首先關(guān)閉管道,并將 ack 隊(duì)列中的所有數(shù)據(jù)包添加到數(shù)據(jù)隊(duì)列的前端,以便故障節(jié)點(diǎn)下游的 DataNode 不會(huì)錯(cuò)過任何數(shù)據(jù)包。(2) 正常狀態(tài)的 DataNode 上的 block 會(huì)被賦予一個(gè)新的標(biāo)識(shí),以便如果失敗的 DataNode 稍后恢復(fù)后,刪除發(fā)生故障的 DataNode 上的部分 block。(3) 然后將失敗的 DataNode 從流水線中移除,并將該 block 的其余數(shù)據(jù)寫入流水線中的兩個(gè)良好的 DataNode。(4) 當(dāng) NameNode 注意到該 block 被復(fù)制不足時(shí),會(huì)安排它在另外一個(gè)節(jié)點(diǎn)上創(chuàng)建另一個(gè)副本。

如果多個(gè) DataNode 在寫入 block 發(fā)生故障,那么只要寫入 dfs.replication.min 最小副本數(shù),寫入操作也會(huì)成功,該 block 將異步復(fù)制,知道其目標(biāo)復(fù)制因子達(dá)到 dfs.replication 指定的數(shù)量。

7) 當(dāng)客戶端完成寫入數(shù)據(jù)后,它會(huì)在流上調(diào)用 close() 方法(步驟6)。

8) close() 操作會(huì)將所有剩余的數(shù)據(jù)包刷新到 DataNode 管道,并聯(lián)系 NameNode 以表示文件以傳輸完成(步驟7),并等待確認(rèn)。

9) NameNode 已經(jīng)知道該文件由哪些 block 組成(因?yàn)橥ㄟ^ DataStreamer 分配的 block),所以它只需要等待 block 最小程度(dfs.replication.min)的被復(fù)制,便可以返回成功,也是此時(shí),NameNode 才會(huì)將文件創(chuàng)建操作提交到 EditLog 中。

8. 數(shù)據(jù)讀取原理

HDFS 讀取原理比較簡單,參考上面的例子,假如 HDFS 客戶端現(xiàn)在想要讀取“example.txt“。

現(xiàn)在,讀取數(shù)據(jù)將發(fā)生以下步驟:

客戶端將與 NameNode 聯(lián)系,詢問文件”example.txt“的 block 元數(shù)據(jù);

NameNode 返回存儲(chǔ)的每個(gè)塊(block A 和 block B)的 DataNode 列表;

然后,客戶端將連接到列表中最近的 DataNode;

客戶端開始從 DataNode 并行讀取數(shù)據(jù)(DN 1 的 block A 和 DN 3 的 block B)

一旦客戶端獲得了所有必須的 block,它就會(huì)將這些 block 組合起來形成一個(gè)文件。

在提供給客戶端讀取請(qǐng)求時(shí),HDFS 選擇最接近客戶端的副本,這減少了讀取延遲和帶寬消耗。因此,如果可能,會(huì)選擇與閱讀節(jié)點(diǎn)位于同一個(gè)機(jī)架上的副本。

9. 數(shù)據(jù)讀取實(shí)現(xiàn)

讀取數(shù)據(jù)的詳細(xì)流程:

1) 客戶端通過調(diào)用 FileSystem 對(duì)象的 open() 方法來打開它希望讀取的文件,其實(shí)就是創(chuàng)建了一個(gè) DistributedFileSystem 對(duì)象(步驟1);

2) DistributedFileSystem 使用 RPC 調(diào)用 NameNode 來確定文件中前幾個(gè) block 的位置,同時(shí)對(duì)于每個(gè) block,NameNode 返回具有該 block 副本的 DataNode 的地址,此外,DataNode 根據(jù)它們與客戶端的接近程度進(jìn)行排序(根據(jù)集群網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu)),如果客戶端本身就是一個(gè) DataNode,那么它將從本地直接讀取(步驟2)。

3) DistributedFileSystem 返回一個(gè) FSDataInputStream(支持文件搜索的輸入流)給客戶端,供其從中讀取數(shù)據(jù);

4) FSDataInputStream 依次包裝一個(gè) DFSInputStream,它們用于管理 DataNode 和 NameNode 的 I/O 讀寫;

5) 客戶端調(diào)用 stream 上的 read() 方法(步驟3);

6) DFSInputStream 中存儲(chǔ)了文件中前幾個(gè) block 所在 DataNode 的地址,根據(jù)這些信息連接到文件中離 block 的最近的DataNode。數(shù)據(jù)從 DataNode 返回至客戶端,客戶端在數(shù)據(jù)流上重復(fù)調(diào)用 read() 方法(不同 block 并行讀取)(步驟4,5);

7) 當(dāng) block 全部傳輸完成后,DFSInputStream 將關(guān)閉與 DataNode 的連接;

8) 當(dāng)客戶端完成數(shù)據(jù)讀取后,調(diào)用 FSDataInputStream 上 close() 方法以關(guān)閉流(步驟6);

心跳檢測、block 狀態(tài)報(bào)告與數(shù)據(jù)重新復(fù)制

文件以 block 形式寫入 DataNode 后,其副本數(shù)必須滿足系統(tǒng)配置的數(shù)量(dfs.replication),即使是在之后 DataNode 發(fā)生了故障,比如磁盤錯(cuò)誤或者宕機(jī),HDFS 都應(yīng)該有能力來處理這樣的情況。所以這里就涉及到了幾個(gè)問題:

1) HDFS 如果確定 Datanode 的狀態(tài)

2) 如何確定哪些 block 出現(xiàn)了丟失

3) Datanode 發(fā)生故障后,如何保障數(shù)據(jù)的安全

在 HDFS 中,Datanode 以及 block 的元信息都通過 Namenode 來管理。Namenode 會(huì)周期性地從集群中的每個(gè) Datanode 接收心跳信號(hào)和 block 狀態(tài)報(bào)告(Blockreport)。接收到心跳信號(hào)意味著該 Datanode 節(jié)點(diǎn)工作正常,而 block 狀態(tài)報(bào)告則包含了一個(gè)該 Datanode 上所有 block 的列表。

那么根據(jù)心跳信號(hào)以及 block 狀態(tài)報(bào)告,Namenode 可以知道每一個(gè) Datanode 是否正常工作,以及哪些 block 被損壞了。如果一個(gè) Datanode 宕機(jī)了,那么任何存儲(chǔ)在它之上的所有 block 將不再有效。Namenode 不斷地檢測這些 block 是否滿足副本系數(shù),一旦發(fā)現(xiàn)某個(gè) block 的副本系數(shù)低于指定值,就會(huì)啟動(dòng)復(fù)制操作。可能需要重新復(fù)制的操作有:某個(gè) Datanode 節(jié)點(diǎn)失效、某個(gè)副本遭到破壞、Datanode 上的磁盤錯(cuò)誤、或者文件的副本系數(shù)變大。

10. 存儲(chǔ)空間回收

文件的刪除和恢復(fù)

當(dāng)用戶或應(yīng)用程序刪除某個(gè)文件時(shí),這個(gè)文件并沒有立刻從 HDFS 中刪除。實(shí)際上 HDFS 會(huì)將這個(gè)文件重命名并轉(zhuǎn)移到 /trash 目錄,所以只要該文件在 /trash 目錄中,就可以被迅速恢復(fù)。文件在 /trash 中保存的時(shí)間通過 fs.trash.interval 配置,當(dāng)超過這個(gè)時(shí)間時(shí),Namenode 就會(huì)將文件從 namespace 中刪除。刪除文件會(huì)使得該文件的 block 被釋放。

Namenode 在做類似的常規(guī)掃描時(shí),Namenode 找點(diǎn)孤兒 block(不被任何文件包含的 block)并刪除它們的元數(shù)據(jù)。然后 Datanode 在和 Namenode 交互心跳信息中,報(bào)告它所擁有的 block 子集的信息,Namenode 回復(fù) Datanode 哪些 block 在元數(shù)據(jù)中已經(jīng)不存在了,Datanode 便可以任意刪除這些 block 副本了。

減少副本系數(shù)

同樣的,當(dāng)一個(gè)文件的副本系數(shù)被減小后,Namenode 會(huì)選擇過剩的副本刪除。其原理與上面的類似。


想學(xué)習(xí)大數(shù)據(jù)或者想學(xué)習(xí)大數(shù)據(jù)的朋友,我整理了一套大數(shù)據(jù)的學(xué)習(xí)視頻免費(fèi)分享給大家,從入門到實(shí)戰(zhàn)都有,大家可以加微信:Lxiao_28獲取,還可以入微信群交流!(備注領(lǐng)取資料,真實(shí)有效哦)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,273評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,527評(píng)論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,010評(píng)論 1 322
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,250評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,769評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,656評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,853評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,103評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評(píng)論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,487評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,815評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容