HDFS 原理、架構與特性

1:當前HDFS架構詳盡分析

對大數據開發HDFS 原理、架構與特性瞭解有多深刻,看懂了算你狠

HDFS架構

•NameNode

•DataNode

•Sencondary NameNode

數據存儲細節

對大數據開發HDFS 原理、架構與特性瞭解有多深刻,看懂了算你狠

NameNode 目錄結構

Namenode 的目錄結構:

${ dfs.name.dir}/current /VERSION

/edits

/fsimage

/fstime

dfs.name.dir 是 hdfs-site.xml 裏配置的若干個目錄組成的列表。

NameNode

Namenode 上保存着 HDFS 的名字空間。對於任何對文件系統元數據產生修改的操作, Namenode 都會使用一種稱爲 EditLog 的事務日誌記錄下來。例如,在 HDFS 中創建一個文件, Namenode 就會在 Editlog 中插入一條記錄來表示;同樣地,修改文件的副本系數也將往 Editlog 插入一條記錄。 Namenode 在本地操作系統的文件系統中存儲這個 Editlog 。整個文件系統的名 字空間,包括數據塊到文件的映射、文件的屬性等,都存儲在一個稱爲 FsImage 的文件中,這 個文件也是放在 Namenode 所在的本地文件系統上。

Namenode 在內存中保存着整個文件系統的名字空間和文件數據塊映射 (Blockmap) 的映像 。這個關鍵的元數據結構設計得很緊湊,因而一個有 4G 內存的 Namenode 足夠支撐大量的文件 和目錄。當 Namenode 啓動時,它從硬盤中讀取 Editlog 和 FsImage ,將所有 Editlog 中的事務作 用在內存中的 FsImage 上,並將這個新版本的 FsImage 從內存中保存到本地磁盤上,然後刪除 舊的 Editlog ,因爲這個舊的 Editlog 的事務都已經作用在 FsImage 上了。這個過程稱爲一個檢查 點 (checkpoint) 。在當前實現中,檢查點只發生在 Namenode 啓動時,在不久的將來將實現支持 週期性的檢查點。

HDFS NameSpace

HDFS 支持傳統的層次型文件組織結構。用戶或者應用程序可以創建目 錄,然後將文件保存在這些目錄裏。文件系統名字空間的層次結構和大多數 現有的文件系統類似:用戶可以創建、刪除、移動或重命名文件。當前, HDFS 不支持用戶磁盤配額和訪問權限控制,也不支持硬鏈接和軟鏈接。但 是 HDFS 架構並不妨礙實現這些特性。

Namenode 負責維護文件系統命名空間,任何對文件系統名字空間或屬 性的修改都將被 Namenode 記錄下來。應用程序可以設置 HDFS 保存的文件 的副本數目。文件副本的數目稱爲文件的副本系數,這個信息也是由 Namenode 保存的。

DataNode

Datanode 將 HDFS 數據以文件的形式存儲在本地的文件系統中,它並不知道有 關 HDFS 文件的信息。它把每個 HDFS 數據塊存儲在本地文件系統的一個單獨的文件 中。 Datanode 並不在同一個目錄創建所有的文件,實際上,它用試探的方法來確定 每個目錄的最佳文件數目,並且在適當的時候創建子目錄。在同一個目錄中創建所 有的本地文件並不是最優的選擇,這是因爲本地文件系統可能無法高效地在單個目 錄中支持大量的文件。

當一個 Datanode 啓動時,它會掃描本地文件系統,產生一個這些本地文件對應 的所有 HDFS 數據塊的列表,然後作爲報告發送到 Namenode ,這個報告就是塊狀態 報告。

配置Secondary NameNode

• conf/masters文件指定的爲Secondary NameNode節點

•修改在masters文件中配置了的機器上的conf/hdfs-site.xml文件,加上如下選項:

<property>

<name>dfs.http.address</name>

<value>namenode.hadoop-host.com:50070</value>

</property>

•core-site.xml:這裏有2個參數可配置,但一般來說我們不做修改。fs.checkpoint.period表示多長時間記錄一次hdfs的鏡像。默認是1小時。fs.checkpoint.size表示一次記錄多大的size,默認64M。

<property>

<name>fs.checkpoint.period</name>

<value>3600</value>

<description>The number of seconds between two periodic checkpoints. </description>

</property>

<property>

<name>fs.checkpoint.size</name>

<value>67108864</value>

<description>The size of the current edit log (in bytes) that triggers a periodic checkpoint even if the fs.checkpoint.period hasn't expired. </description>

</property>

Secondary NameNode

Secondary NameNode 定期合併 fsimage 和 edits 日誌,將 edits 日誌文件大小控制在一個限度下。

對大數據開發HDFS 原理、架構與特性瞭解有多深刻,看懂了算你狠

Secondary NameNode處理流程

(1) 、 namenode 響應 Secondary namenode 請求,將 edit log 推送給 Secondary namenode , 開始重新寫一個新的 edit log 。

(2) 、 Secondary namenode 收到來自 namenode 的 fsimage 文件和 edit log 。

(3) 、 Secondary namenode 將 fsimage 加載到內存,應用 edit log , 並生成一 個新的 fsimage 文件。

(4) 、 Secondary namenode 將新的 fsimage 推送給 Namenode 。

(5) 、 Namenode 用新的 fsimage 取代舊的 fsimage , 在 fstime 文件中記下檢查 點發生的時

HDFS通信協議

所有的 HDFS 通訊協議都是構建在 TCP/IP 協議上。客戶端通過一個可 配置的端口連接到 Namenode , 通過 ClientProtocol 與 Namenode 交互。而 Datanode 是使用 DatanodeProtocol 與 Namenode 交互。再設計上, DataNode 通過週期性的向 NameNode 發送心跳和數據塊來保持和 NameNode 的通信,數據塊報告的信息包括數據塊的屬性,即數據塊屬於哪 個文件,數據塊 ID ,修改時間等, NameNode 的 DataNode 和數據塊的映射 關係就是通過系統啓動時 DataNode 的數據塊報告建立的。從 ClientProtocol 和 Datanodeprotocol 抽象出一個遠程調用 ( RPC ), 在設計上, Namenode 不會主動發起 RPC , 而是是響應來自客戶端和 Datanode 的 RPC 請求。

HDFS的安全模式

Namenode 啓動後會進入一個稱爲安全模式的特殊狀態。處於安全模式 的 Namenode 是不會進行數據塊的複製的。 Namenode 從所有的 Datanode 接收心跳信號和塊狀態報告。塊狀態報告包括了某個 Datanode 所有的數據 塊列表。每個數據塊都有一個指定的最小副本數。當 Namenode 檢測確認某 個數據塊的副本數目達到這個最小值,那麼該數據塊就會被認爲是副本安全 (safely replicated) 的;在一定百分比(這個參數可配置)的數據塊被 Namenode 檢測確認是安全之後(加上一個額外的 30 秒等待時間), Namenode 將退出安全模式狀態。接下來它會確定還有哪些數據塊的副本沒 有達到指定數目,並將這些數據塊複製到其他 Datanode 上。

2:HDFS文件讀取的解析

文件讀取流程

對大數據開發HDFS 原理、架構與特性瞭解有多深刻,看懂了算你狠

流程分析

•使用HDFS提供的客戶端開發庫Client,向遠程的Namenode發起RPC請求;

• Namenode會視情況返回文件的部分或者全部block列表,對於每個block,Namenode都會返回有該block拷貝的DataNode地址;

•客戶端開發庫Client會選取離客戶端最接近的DataNode來讀取block;如果客戶端本身就是DataNode,那麼將從本地直接獲取數據.

•讀取完當前block的數據後,關閉與當前的DataNode連接,併爲讀取下一個block尋找最佳的DataNode;

•當讀完列表的block後,且文件讀取還沒有結束,客戶端開發庫會繼續向Namenode獲取下一批的block列表。

•讀取完一個block都會進行checksum驗證,如果讀取datanode時出現錯誤,客戶端會通知Namenode,然後再從下一個擁有該block拷貝的datanode繼續讀。

3:HDFS文件寫入的解析

文件寫入流程

對大數據開發HDFS 原理、架構與特性瞭解有多深刻,看懂了算你狠

流程分析

•使用HDFS提供的客戶端開發庫Client,向遠程的Namenode發起RPC請求;

•Namenode會檢查要創建的文件是否已經存在,創建者是否有權限進行操作,成功則會爲文件 創建一個記錄,否則會讓客戶端拋出異常;

•當客戶端開始寫入文件的時候,會將文件切分成多個packets,並在內部以數據隊列"data queue"的形式管理這些packets,並向Namenode申請新的blocks,獲取用來存儲replicas的合適的datanodes列表,列表的大小根據在Namenode中對replication的設置而定。

•開始以pipeline(管道)的形式將packet寫入所有的replicas中。把packet以流的方式寫入第一個datanode,該datanode把該packet存儲之後,再將其傳遞給在此pipeline中的下一個datanode,直到最後一個datanode,這種寫數據的方式呈流水線的形式。

•最後一個datanode成功存儲之後會返回一個ack packet,在pipeline裏傳遞至客戶端,在客戶端的開發庫內部維護着"ack queue",成功收到datanode返回的ack packet後會從"ack queue"移除相應的packet。

•如果傳輸過程中,有某個datanode出現了故障,那麼當前的pipeline會被關閉,出現故障的datanode會從當前的pipeline中移除,剩餘的block會繼續剩下的datanode中繼續以pipeline的形式傳輸,同時Namenode會分配一個新的datanode,保持replicas設定的數量。

流水線複製

當客戶端向 HDFS 文件寫入數據的時候,一開始是寫到本地臨時文件中。假設該文件的副 本系數設置爲 3 ,當本地臨時文件累積到一個數據塊的大小時,客戶端會從 Namenode 獲取一個 Datanode 列表用於存放副本。然後客戶端開始向第一個 Datanode 傳輸數據,第一個 Datanode 一小部分一小部分 (4 KB) 地接收數據,將每一部分寫入本地倉庫,並同時傳輸該部分到列表中 第二個 Datanode 節點。第二個 Datanode 也是這樣,一小部分一小部分地接收數據,寫入本地 倉庫,並同時傳給第三個 Datanode 。最後,第三個 Datanode 接收數據並存儲在本地。因此, Datanode 能流水線式地從前一個節點接收數據,並在同時轉發給下一個節點,數據以流水線的 方式從前一個 Datanode 複製到下一個

更細節的原理

客戶端創建文件的請求其實並沒有立即發送給 Namenode ,事實上,在剛開始階 段 HDFS 客戶端會先將文件數據緩存到本地的一個臨時文件。應用程序的寫操作被透 明地重定向到這個臨時文件。當這個臨時文件累積的數據量超過一個數據塊的大小 ,客戶端纔會聯繫 Namenode 。 Namenode 將文件名插入文件系統的層次結構中,並 且分配一個數據塊給它。然後返回 Datanode 的標識符和目標數據塊給客戶端。接着 客戶端將這塊數據從本地臨時文件上傳到指定的 Datanode 上。當文件關閉時,在臨 時文件中剩餘的沒有上傳的數據也會傳輸到指定的 Datanode 上。然後客戶端告訴 Namenode 文件已經關閉。此時 Namenode 纔將文件創建操作提交到日誌裏進行存儲 。如果 Namenode 在文件關閉前宕機了,則該文件將丟失。

4:副本機制

特點

1. 數據類型單一

2. 副本數比較多

3. 寫文件時副本的放置方法

4. 動態的副本創建策略

5. 弱化的副本一致性要求

副本擺放策略

對大數據開發HDFS 原理、架構與特性瞭解有多深刻,看懂了算你狠

修改副本數

1.集羣只有三個Datanode,hadoop系統replication=4時,會出現什麼情況?

對於上傳文件到hdfs上時,當時hadoop的副本系數是幾,這個文件的塊數副本數就會有幾份,無論以後你怎麼更改系統副本系統,這個文件的副本數都不會改變,也就說上傳到分佈式系統上的文件副本數由當時的系統副本數決定,不會受replication的更改而變化,除非用命令來更改文件的副本數。因爲dfs.replication實質上是client參數,在create文件時可以指定具體replication,屬性dfs.replication是不指定具體replication時的採用默認備份數。文件上傳後,備份數已定,修改dfs.replication是不會影響以前的文件的,也不會影響後面指定備份數的文件。隻影響後面採用默認備份數的文件。但可以利用hadoop提供的命令後期改某文件的備份數:hadoop fs -setrep -R 1。如果你是在hdfs-site.xml設置了dfs.replication,這並一定就得了,因爲你可能沒把conf文件夾加入到你的 project的classpath裏,你的程序運行時取的dfs.replication可能是hdfs-default.xml裏的 dfs.replication,默認是3。可能這個就是造成你爲什麼dfs.replication老是3的原因。你可以試試在創建文件時,顯式設定replication。replication一般到3就可以了,大了意義也不大。

5:HDFS負載均衡

HDFS的數據也許並不是非常均勻的分佈在各個DataNode中。一個常見的原因是在現有的集羣上經常會增添新的DataNode節點。當新增一個數據塊(一個文件的數據被保存在一系列的塊中)時,NameNode在選擇DataNode接收這個數據塊之前,會考慮到很多因素。其中的一些考慮的是:

•將數據塊的一個副本放在正在寫這個數據塊的節點上。

•儘量將數據塊的不同副本分佈在不同的機架上,這樣集羣可在完全失去某一機架的情況下還能存活。

•一個副本通常被放置在和寫文件的節點同一機架的某個節點上,這樣可以減少跨越機架的網絡I/O。

•儘量均勻地將HDFS數據分佈在集羣的DataNode中。

6:HDFS機架感知

HDFS機架感知

通常,大型 Hadoop 集羣是以機架的形式來組織的,同一個機架上不同 節點間的網絡狀況比不同機架之間的更爲理想。 另外, NameNode 設法將 數據塊副本保存在不同的機架上以提高容錯性。

而 HDFS 不能夠自動判斷集羣中各個 datanode 的網絡拓撲情況 Hadoop 允 許集羣的管理員通過配置 dfs.network.script 參數來確定節點所處的機架。 文 件提供了 IP->rackid 的翻譯。 NameNode 通過這個得到集羣中各個 datanode 機器的 rackid 。 如果 topology.script.file.name 沒有設定,則每個 IP 都會翻譯 成 / default-rack 。

對大數據開發HDFS 原理、架構與特性瞭解有多深刻,看懂了算你狠

有了機架感知, NameNode 就可以畫出上圖所示的 datanode 網絡拓撲圖。 D1,R1 都是交換機,最底層是 datanode 。 則 H1 的 rackid=/D1/R1/H1 , H1 的 parent 是 R1 , R1 的是 D1 。 這些 rackid 信息可以通過 topology.script.file.name 配置。有了這些 rackid 信息就可以計算出任意兩臺 datanode 之間的距離。

distance(/D1/R1/H1,/D1/R1/H1)=0 相同的 datanode

distance(/D1/R1/H1,/D1/R1/H2)=2 同一 rack 下的不同 datanode

distance(/D1/R1/H1,/D1/R1/H4)=4 同一 IDC 下的不同 datanode

distance(/D1/R1/H1,/D2/R3/H7)=6 不同 IDC 下的 datanode

7:HDFS訪問

訪問方式

HDFS 給應用提供了多種訪問方式。用戶可以通過 Java API 接口訪問,也 可以通過 C 語言的封裝 API 訪問,還可以通過瀏覽器的方式訪問 HDFS 中的文件。

8:HDFS 健壯性

HDFS 的主要目標就是即使在出錯的情況下也要保證數據存儲的可靠性。 常見的三種出錯情況是: Namenode 出錯 , Datanode 出錯和網絡割裂 ( network partitions) 。

磁盤數據錯誤,心跳檢測和重新複製

每個 Datanode 節點週期性地向 Namenode 發送心跳信號。網絡割裂可能 導致一部分 Datanode 跟 Namenode 失去聯繫。 Namenode 通過心跳信號的缺 失來檢測這一情況,並將這些近期不再發送心跳信號 Datanode 標記爲宕機 ,不會再將新的 IO 請求發給它們。任何存儲在宕機 Datanode 上的數據將不 再有效。 Datanode 的宕機可能會引起一些數據塊的副本系數低於指定值, Namenode 不斷地檢測這些需要複製的數據塊,一旦發現就啓動複製操作。 在下列情況下,可能需要重新複製:某個 Datanode 節點失效,某個副本遭 到損壞, Datanode 上的硬盤錯誤,或者文件的副本系數增大。

數據完整性

從某個 Datanode 獲取的數據塊有可能是損壞的,損壞可能是由 Datanode 的存儲設備錯誤、網絡錯誤或者軟件 bug 造成的。 HDFS 客戶端軟 件實現了對 HDFS 文件內容的校驗和 (checksum) 檢查。當客戶端創建一個新 的 HDFS 文件,會計算這個文件每個數據塊的校驗和,並將校驗和作爲一個 單獨的隱藏文件保存在同一個 HDFS 名字空間下。當客戶端獲取文件內容後 ,它會檢驗從 Datanode 獲取的數據跟相應的校驗和文件中的校驗和是否匹 配,如果不匹配,客戶端可以選擇從其他 Datanode 獲取該數據塊的副本。

元數據磁盤錯誤

FsImage 和 Editlog 是 HDFS 的核心數據結構。如果這些文件損壞了,整個 HDFS 實例都將失效。因而, Namenode 可以配置成支持維護多個 FsImage 和 Editlog 的副本。任何對 FsImage 或者 Editlog 的修改,都將同步到它們的副 本上。這種多副本的同步操作可能會降低 Namenode 每秒處理的名字空間事 務數量。然而這個代價是可以接受的,因爲即使 HDFS 的應用是數據密集的 ,它們也非元數據密集的。當 Namenode 重啓的時候,它會選取最近的完整 的 FsImage 和 Editlog 來使用。

Namenode 是 HDFS 集羣中的單點故障 (single point of failure) 所在。如果 Namenode 機器故障,是需要手工干預的。目前,自動重啓或在另一臺機器 上做 Namenode 故障轉移的功能還沒實現。

快照

快照支持某一特定時刻的數據的複製備份。利用快照,可以讓 HDFS 在 數據損壞時恢復到過去一個已知正確的時間點。 HDFS 目前還不支持快照功 能,但計劃在將來的版本進行支持。

9:HDFS 文件刪除恢復機制

當用戶或應用程序刪除某個文件時,這個文件並沒有立刻從 HDFS 中刪 除。實際上, HDFS 會將這個文件重命名轉移到 /trash 目錄。只要文件還在 /trash 目錄中,該文件就可以被迅速地恢復。文件在 /trash 中保存的時間是可 配置的,當超過這個時間時, Namenode 就會將該文件從名字空間中刪除。 刪除文件會使得該文件相關的數據塊被釋放。注意,從用戶刪除文件到 HDFS 空閒空間的增加之間會有一定時間的延遲。

只要被刪除的文件還在 /trash 目錄中,用戶就可以恢復這個文件。如果 用戶想恢復被刪除的文件,他 / 她可以瀏覽 /trash 目錄找回該文件。 /trash 目 錄僅僅保存被刪除文件的最後副本。 /trash 目錄與其他的目錄沒有什麼區別 ,除了一點:在該目錄上 HDFS 會應用一個特殊策略來自動刪除文件。目前 的默認策略是刪除 /trash 中保留時間超過 6 小時的文件。將來,這個策略可以 通過一個被良好定義的接口配置。

開啓回收站

hdfs-site.xml

<configuration>

<property>

<name>fs.trash.interval</name>

<value> 1440 </value>

<description>Number ofminutes between trash checkpoints.

If zero, the trashfeature is disabled.

</description>

</property>

</configuration>

1, fs.trash.interval參數設置保留時間爲 1440 分鐘(1天)

2, 回收站的位置:在HDFS上的 /user/$USER/.Trash/Current/

10:HDFS 分佈式緩存(DistributedCache )

(1)在HDFS上準備好要共享的數據(text、archive、jar),你拼路徑的時候必須加前綴"file://"說明是本地路徑,否則hadoop默認訪問的路徑是hdfs。

(2)DistributedCache 在 Mapper 或者 Reducer 啓動時會被 copy to local,然後被 DistributedCache.getLocalCacheFiles() 調用,運行完 job 後 local cache file 會被刪掉,如果另一個 job 也需要這樣一份文件,需要重新添加、重新緩存,因爲在分佈式場景下 task 並不知道該 node 是否存在 cache file。如果在同臺機器已經有了dist cache file,不會再次download,DistributedCache 根據緩存文檔修改的時間戳進行追蹤。 在作業執行期間,當前應用程序或者外部程序不能修改緩存文件,所以分佈式緩存一般用來緩存只讀文件。

(3)DistributedCache 在添加的時候注意要添加具體的文件,如果你添加目錄,DistributedCache 將不會自動遍歷、識別目錄下的文件。

11:HDFS缺點

大量小文件

因爲 Namenode 把文件系統的元數據放置在內存中,所以文件系統所能 容納的文件數目是由 Namenode 的內存大小來決定。一般來說,每一個文件 、文件夾和 Block 需要佔據 150 字節左右的空間,所以,如果你有 100 萬個文 件,每一個佔據一個 Block ,你就至少需要 300MB 內存。當前來說,數百萬 的文件還是可行的,當擴展到數十億時,對於當前的硬件水平來說就沒法實 現了。還有一個問題就是,因爲 Map task 的數量是由 splits 來決定的,所以 用 MR 處理大量的小文件時,就會產生過多的 Maptask ,線程管理開銷將會 增加作業時間。舉個例子,處理 10000M 的文件,若每個 split 爲 1M ,那就會 有 10000 個 Maptasks ,會有很大的線程開銷;若每個 split 爲 100M ,則只有 100 個 Maptasks ,每個 Maptask 將會有更多的事情做,而線程的管理開銷也 將減小很多

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章