大數據HDFS讀寫數據的過程探究
讀數據
- 跟namenode通信查詢元數據,找到文件塊所在的datanode服務器
- 挑選一臺datanode(就近原則,然后隨機)服務器,請求建立socket流
- datanode開始發送數據(從磁盤里面讀取數據放入流,以packet為單位來做校驗)
- 客戶端以packet為單位接收,現在本地緩存,然后寫入目標文件

寫數據
- 根namenode通信請求上傳文件,namenode檢查目標文件是否已存在,父目錄是否存在
- namenode返回是否可以上傳
- client請求第一個 block該傳輸到哪些datanode服務器上
- namenode返回3個datanode服務器ABC
- client請求3臺dn中的一臺A上傳數據(本質上是一個RPC調用,建立pipeline),A收到請求會繼續調用B,然后B調用C,將真個pipeline建立完成,逐級返回客戶端
- client開始往A上傳第一個block(先從磁盤讀取數據放到一個本地內存緩存),以packet為單位,A收到一個packet就會傳給B,B傳給C;A每傳一個packet會放入一個應答隊列等待應答
- 當一個block傳輸完成之后,client再次請求namenode上傳第二個block的服務器。

網絡故障,臟數據如何解決?
DataNode 失效等問題,這些問題 HDFS 在設計的時候都早已考慮到了。下面來介紹一下數據損壞處理流程:
- 當 DataNode 讀取 block 的時候,它會計算 checksum。
- 如果計算后的 checksum,與 block 創建時值不一樣,說明該 block 已經損壞。
- Client 讀取其它 DataNode上的 block。
- NameNode 標記該塊已經損壞,然后復制 block 達到預期設置的文件備份數 。
- DataNode 在其文件創建后驗證其 checksum。
讀寫過程,數據完整性如何保持?
通過校驗和。因為每個chunk中都有一個校驗位,一個個chunk構成packet,一個個packet最終形成block,故可在block上求校驗和。
HDFS 的client端即實現了對 HDFS 文件內容的校驗和 (checksum) 檢查。當客戶端創建一個新的HDFS文件時候,分塊后會計算這個文件每個數據塊的校驗和,此校驗和會以一個隱藏文件形式保存在同一個 HDFS 命名空間下。當client端從HDFS中讀取文件內容后,它會檢查分塊時候計算出的校驗和(隱藏文件里)和讀取到的文件塊中校驗和是否匹配,如果不匹配,客戶端可以選擇從其他 Datanode 獲取該數據塊的副本。
HDFS中文件塊目錄結構具體格式如下:
- ${dfs.datanode.data.dir}/
- ├── current
- │ ├── BP-526805057-127.0.0.1-1411980876842
- │ │ └── current
- │ │ ├── VERSION
- │ │ ├── finalized
- │ │ │ ├── blk_1073741825
- │ │ │ ├── blk_1073741825_1001.meta
- │ │ │ ├── blk_1073741826
- │ │ │ └── blk_1073741826_1002.meta
- │ │ └── rbw
- │ └── VERSION
- └── in_use.lock
in_use.lock表示DataNode正在對文件夾進行操作
rbw是“replica being written”的意思,該目錄用于存儲用戶當前正在寫入的數據。
Block元數據文件(*.meta)由一個包含版本、類型信息的頭文件和一系列校驗值組成。校驗和也正是存在其中。