一、架構原理
HDFS 是Hadoop Distributed File System的簡稱,是HADOOP抽象文件系統的一種實現。Hadoop抽象文件系統可以與本地系統、Amazon S3等集成,甚至可以通過Web協議(webhsfs)來操作。
HDFS是由一個NAMENODE與多個DATANODE構成,如下圖。
其中NAMENODE負責管理分布式文件系統的命名空間(Namespace)。
DATANODE 數據節點,用來具體的存儲文件,維護了blockId 與 datanode本地文件的映射。
換個理解方法就是MASTER WORKER 模式,其中NAMENODE 對應是master,進所有datanode的datanode mate 信息的關聯以及監控等相關事情。而DATANODE只負責存儲數據。
HDFS基礎知識思維導圖如下:
二、寫文件過程
- Client 調用 DistributedFileSystem 對象的 create 方法,創建一個文件輸出流(FSDataOutputStream)對象;
- 通過 DistributedFileSystem 對象與集群的 NameNode 進行一次 RPC 遠程調用,在 HDFS 的 Namespace 中創建一個文件條目(Entry),此時該條目沒有任何的 Block,NameNode 會返回該數據每個塊需要拷貝的 DataNode 地址信息;
- 通過 FSDataOutputStream 對象,開始向 DataNode 寫入數據,數據首先被寫入 FSDataOutputStream 對象內部的數據隊列中,數據隊列由 DataStreamer 使用,它通過選擇合適的 DataNode 列表來存儲副本,從而要求 NameNode 分配新的 block;
- DataStreamer 將數據包以流式傳輸的方式傳輸到分配的第一個 DataNode 中,該數據流將數據包存儲到第一個 DataNode 中并將其轉發到第二個 DataNode 中,接著第二個 DataNode 節點會將數據包轉發到第三個 DataNode 節點;
- DataNode 確認數據傳輸完成,最后由第一個 DataNode 通知 client 數據寫入成功;
- 完成向文件寫入數據,Client 在文件輸出流(FSDataOutputStream)對象上調用 close 方法,完成文件寫入;
- 調用 DistributedFileSystem 對象的 complete 方法,通知 NameNode 文件寫入成功,NameNode 會將相關結果記錄到 editlog 中。
三、讀文件過程
- Client 通過 DistributedFileSystem 對象與集群的 NameNode 進行一次 RPC 遠程調用,獲取文件 block 位置信息;
- NameNode 返回存儲的每個塊的 DataNode 列表;
- Client 將連接到列表中最近的 DataNode;
- Client 開始從 DataNode 并行讀取數據;
- 一旦 Client 獲得了所有必須的 block,它就會將這些 block 組合起來形成一個文件。
四、問題
1、數據錯誤,hdfs是怎么解決的呢?
原因 :由于網絡傳輸與磁盤錯誤等因素。
解決辦法:在客戶端讀取到數據后,會采用MD5和sha1對數據塊進行校驗,以確定讀取到正確的數據。
具體流程:
- 在文件被創建的時候,客戶端對文件進行摘錄,并把這些信息寫入數據的同一路徑隱藏文件中。
- 當客戶端讀取文件的時候,會先讀取該信息文件,然后利用該信息文件對每個讀取的數據塊進行校驗,如果校驗出錯,客戶端就會請求到另外一個數據接地那讀取該文件快,并且向NAMENODE報告這個文件塊有錯誤,NAMENODE會定期檢查并且重新復制這個塊。
2、數據節點出錯
DATANODE 難免會造成不可用
解決思路主要是通過心跳的方式
解決流程:
- 每個數據節點會定期向NAMEnode 節點發送心跳,向namenode報告自己的狀態。
- 當數據節點發生故障或者網絡發生斷網時,namenode節點就無法收到來自以下數據節點的心跳信息。這些數據節點就會被標記為宕機,節點上面的所有數據都會標記為不可讀,namenode不會再給他們發送任何的IO請求。
- 這時,有可能出現一種情況,由于一些數據節點的不可用,會導致一些數據塊的副本量小于冗余因子。
- namenode 會定期檢查這些數據情況,一旦發現某些數據塊的副本數量小于冗余因子,就會啟動數據冗余復制,為它生產新的副本。
- HDFS和其他分布式文件系統最大的區別就是可以調整冗余數據的位置。
3、namenode 節點出錯(單點故障問題)
namenode節點保存了所有的元數據信息,其中最核心的兩大數據結構是FsImage 合Editlog,如果這兩個文件發生了損壞,那么整個HDFS實例降 失效。
因此,HDFS設置了備份機制,把這些核心文件同步復制到備份服務器SecondaryNameNode上。當namenode出錯時,就可以根據備份服務器SecondaryNameNode中的FsImage和Editlog數據進行恢復。
4、小文件問題以及DATANODE水平擴展極限問題
Hadoop中每個目錄、文件和block都會以對象的形式保存在NameNode的內存中。根據經驗每個對象在內存中大概占用150個字節。HDFS中保存2000萬個文件,每個文件都在同一個文件夾中,而且每個文件都只有一個block,則NameNode需要6GB內存。
小文件問題:
1、當NameNode重啟時,它都需要從本地磁盤讀取每個文件的元數據,意味著你要讀取300GB數據到內存中,不可避免導致NameNode啟動時間較長。
2、一般來說,NameNode會不斷跟蹤并檢查每個數據塊的存儲位置。這是通過DataNode的定時心跳上報其數據塊來實現的。數據節點需要上報的block越多,則也會消耗越多的網絡帶寬/時延。即使節點之間是高速網絡(萬兆/光纖),但不可避免的會帶來一些不好的影響。
3、NameNode本身使用300G內存,相當于JVM你需要配置300GB的heap,對于JVM來說本來就存在穩定性的風險,比如GC時間較長。
另外大量小文件意味著大量的隨機磁盤IO,磁盤IO通常是MapReduce性能的最大瓶頸之一,在HDFS中對于相同數量的數據,一次大的順序讀取往往優于幾次隨機讀取的性能。
5、HDFS為什么是128M這么大的一個數據塊呢?
在文件系統中,系統存儲文件時,需要定位該數據在磁盤中的位置,再進行傳輸處理。
定位在磁盤的位置需要時間,同樣文件傳輸也是需要時間的。
T(存儲時間)=T(定位時間)+T(傳輸時間)
如果每個要傳輸的塊設置得足夠大,那么從磁盤傳輸數據的時間可以明顯大于定位這個塊開始位置的時間。
假如文件太小,在namenode 的映射列表就會非常大,影響尋址時間,尋址時間如果大于傳輸時間,就沒有意義了。
但如果block 設置過太大,在MapReduce 任務中,Map或者Reduce任務的個數小于集群機器數量,會使得作業運行效率很低。
6、namenode還存在哪些問題以及怎么解決?
存在問題:
- 單點故障問題
- 不可以水平擴展(是否可以通過縱向擴展來解決?)
- 系統整體性能受限于單個名稱節點的吞吐量
- 單個名稱節點難以提供不同程序之間的隔離性
解決方案
熱備份 (HDFS HA)
HDFS HA(High Availability)是為了解決單點故障問題
HA集群設置兩個名稱節點,“活躍(Active)”和“待命(Standby)”
兩種名稱節點的狀態同步,可以借助于一個共享存儲系統來實現
一旦活躍名稱節點出現故障,就可以立即切換到待命名稱節點
Zookeeper確保一個名稱節點在對外服務
名稱節點維護映射信息,數據節點同時向兩個名稱節點匯報信息
存在的問題就有可能出現腦裂的問題。
Federation
多個命名空間。為了處理一個namenode的局限性,搞了幾個namanode大家一起來管理。就像編程中的命名空間一樣
在HDFS Federation中,設計了多個相互獨立的名稱節點,使得HDFS的命名服務能夠水平擴展,這些名稱節點分別進行各自命名空間和塊的管理,相互之間是聯盟(Federation)關系,不需要彼此協調。并且向后兼容
HDFS Federation中,所有名稱節點會共享底層的數據節點存儲資源,數據節點向所有名稱節點匯報
屬于同一個命名空間的塊構成一個“塊池
HDFS Federation設計可解決單名稱節點存在的以下幾個問題:
1. HDFS集群擴展性。多個名稱節點各自分管一部分目錄,使得一個集群可以擴展到更多節點,不再像HDFS1.0中那樣由于內存的限制制約文件存儲數目
2. 性能更高效。多個名稱節點管理不同的數據,且同時對外提供服務,將為用戶提供更高的讀寫吞吐率
3. 良好的隔離性。用戶可根據需要將不同業務數據交由不同名稱節點管理,這樣不同業務之間影響很小
參考文章
https://developer.ibm.com/zh/articles/os-cn-hadoop-name-node/
https://blog.csdn.net/xjz729827161/article/details/79463140