HDFS 讀寫解析
HDFS 讀數據流程
- 客戶端通過 FileSystem 向 NameNode 發起請求下載文件,NameNode 通過查詢元數據找到文件所在的 DataNode 地址
- 挑選一臺 DataNode(就近原則)服務器,發送讀取數據請求
- DataNode 開始傳輸數據給客戶端
- 客戶端以 Packet 爲單位接收,先在本地緩存,然後寫入目標文件
HDFS 寫數據流程
- 客戶端通過 FileSystem 模塊向 NameNode 發送上傳文件請求,NameNode 檢查目標文件是否已存在,父目錄是否存在
- NameNode 返回是否可以上傳
- 客戶端請求詢問第一個 Block 上傳到哪幾個 DataNode 服務器
- NameNode 返回 n 個 DataNode 節點,如 dn1、dn2、nd3
- 客戶端通過 FSDataOutputStream 模塊請求 dn1 上傳數據,dn1 收到請求會繼續調用 dn2,然後 dn2 調用 dn3,將這個通信管道建立完成
- dn1、dn2、nd3 逐級應答客戶端
- 客戶端開始往 dn1 上傳第一個 Block(先從磁盤讀取數據放到一個本地內存緩存),以 Packet 爲單位,dn1 收到一個 Packet 就會傳給 dn2,dn2 傳給 dn3,dn1 每傳一個 packet 會放入一個確認隊列等待確認
- 當一個 Block 傳輸完成之後,客戶端再次請求 NameNode 上傳第二個 Block 的服務器。(重複執行 3-7 步)
默認情況下每 64kb 一個 Packet
代碼驗證:最開始會有一個輸出,也就是一個 64k 的文件會輸出兩次。
@Test
public void testUploadPacket() throws IOException {
FileInputStream fis = new FileInputStream(new File("e://11.txt"));
FSDataOutputStream fos = fs.create(new Path("bbb.txt"), () -> System.out.println("每傳輸一個packet就會執行一次"));
IOUtils.copyBytes(fis,fos,new Configuration());
}
NameNode 和 SecondNamenode
元數據管理機制解析
- NameNode 如何管理和存儲元數據?
我們一般計算機存儲數據無非兩種方式:內存或磁盤。內存處理數據快,但斷電數據會丟失。磁盤數據處理慢,但是安全性高。
綜合以上兩點,NameNode 元數據的管理採用的是:內存+磁盤(FsImage 文件)的方式。
- 磁盤和內存中元數據怎麼劃分?
假設 1:如果要保持磁盤和元數據數據一致,那麼對元數據增刪改操作的時候,需要同步操作磁盤,這樣效率也不高。
假設 2:兩個數據合起來纔是完整的數據。NameNode 引入了 edits 文件(日誌文件,只能追加寫入),記錄增刪改操作。
具體流程如下:
1)第一階段:NameNode 啓動
- 第一次啓動 NameNode 格式化後,會創建 Fsimage 和 Edits 文件。如果部署第一次啓動,直接加載編輯日誌和鏡像文件到內存
- 客戶端對元數據增刪改的請求
- NameNode 記錄操作日誌,更新滾動日誌
- NameNode 在內存中對數據進行增刪改
2)第二階段:Secondary NameNode 工作
- Secondary NameNode 詢問 NameNode 是否需要 CheckPoint。直接帶回 NameNode 是否執行檢查點操作結果
- Secondary NameNode 請求執行 CheckPoint
- NameNode 滾動正在寫的 Edits 日誌
- 將滾動前的 Edits 日誌和鏡像文件拷貝到 Secondary NameNode
- Secondary NameNode 加載 Edits 日誌和鏡像文件到內存,進行合併
- 生成新的鏡像文件 fsimage.chkpint
- 拷貝 fsimage.chkpoint 到 NameNode
- NameNode 將 fsimage.chkpoint 重新命名爲 fsimage
Edits 文件和鏡像文件(Fsimage)解析
這兩個文件位於${hadoop.tmp.dir}/dfs/name/current/下
- Fsimage 文件:是 NameNode 中元數據的鏡像,包含了 HDFS 文件系統的所有目錄及文件信息(Block 數量、副本數量、權限等)
- Edits 文件:存儲了客戶端對 HDFS 文件系統的所有增刪改操作
- seen_txid:該文件保存了一個數字,對應最後一個 Edits 文件名的數字
- VERSION:記錄 NameNode 的一些版本號信息
1. Fsimage 文件內容查看
這些文件本身打開是亂碼不可查看的,好在官方給我們提供了查看這些文件的命令。
語法:
hdfs oiv -p 文件類型(xml) -i 鏡像文件 -o 轉換後文件輸出路徑
示例:
hdfs oiv -p XML -i fsimage_0000000000000000409 -o ./fsimage.xml
我們打開 xml 文件:
裏面包含了類型、文件名、副本數、權限等等信息。注意沒有保存塊對應的 DataNode 的信息。
因爲這個節點信息由 DataNode 自己彙報有哪些文件,而不是文件裏記錄屬於哪個節點。否則如果每個節點宕機了,那麼所有的文件都需要進行變更信息。
2. Edits 文件內容
基本語法:
hdfs oev -p 文件類型 -i編輯日誌 -o 轉換後文件輸出路徑
示例:
hdfs oev -p XML -i edits_inprogress_0000000000000000420 -o ./edits.xml
這個文件記錄了我們的增刪改的一些操作。我們如何確認哪些 Edits 文件沒有被合併過呢?
可以通過 fsimage 文件自身的編號來確定。大於這個編號的 edits 文件就是沒有合併的。
3. chekpoint 週期
週期配置我們可以在默認配置文件 hdfs-default.xml 裏找到。
<!-- 定時一小時 -->
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
<!-- 一分鐘檢查一次操作次數,當操作次數達到1百萬時,SecondaryNameNode執行一次 -->
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>操作動作次數</description>
</property>
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
<description> 1分鐘檢查一次操作次數</description>
</property >
4. NameNode 故障處理
NameNode 保存着所有的元數據信息,如果故障,整個 HDFS 集羣都無法正常工作。
如果元數據出現丟失或損壞怎麼恢復呢?
- 將 2nn 的元數據拷貝到 nn 下(存在一定數量的元數據丟失)
- 搭建 HDFS 的高可用集羣,藉助 Zookeeper 實現 HA,一個 Active 的 NameNode,一個是 Standby 的 NameNode,解決 NameNode 單點故障問題。
Hadoop 高級命令
1. HDFS 文件限額配置
HDFS 文件的限額配置允許我們以文件的大小或文件的個數來限制我們在某個目錄上傳的文件數量或文件大小。
- 數量限額
#設置2個的數量限制,代表只能上傳一個文件
hdfs dfsadmin -setQuota 2 /west
上傳第二個的時候報錯:
put: The NameSpace quota (directories and files) of directory /west is exceeded: quota=2 file count=3
清除數量限制
hdfs dfsadmin -clrQuota /west
- 空間限額
#限定1k的空間
hdfs dfsadmin -setSpaceQuota 1k /west
# 清除限額
hdfs dfsadmin -clrSpaceQuota /west
#查看限額
hdfs dfs -count -q -h /west
2. HDFS 的安全模式
安全模式是 HDFS 所處的一種特殊狀態,這種狀態下,文件系統只能接受讀請求。
在 NameNode 主節點啓動時,HDFS 首先進入安全模式,DataNode 在啓動的時候會向 NameNode 彙報可用的 block 等狀態,當整個系統達到安全標準時,HDFS 自動離開安全模式。如果 HDFS 出於安全模式下,則文件 block 不能進行任何的副本複製操作,因此達到最小的副本數量要求是基於 DataNode 啓動的狀態來判定的。啓動時不會再做任何複製,HDFS 集羣剛啓動的時候,默認 30S 的時間是處於安全期的,只有過了安全期,纔可以對集羣進行操作。
#進入安全模式
hdfs dfsadmin -safemode enter
#離開安全模式
hdfs dfsadmin -safemode leave
3. Hadoop 歸檔技術
主要解決 HDFS 集羣存在大量小文件的問題。由於大量小文件佔用 NameNode 的內存,因此對於 HDFS 來說存儲大量小文件造成 NameNode 內存資源的浪費。
Hadoop 存檔文件 HAR 文件,是一個更高效的文件存檔工具,HAR 文件是由一組文件通過 archive 工具創建而來,在減少了 NameNode 的內存使用的同時,可以對文件進行透明的訪問,通俗來說就是 HAR 文件對 NameNode 來說是一個文件減少了內存的浪費,對於實際操作處理文件依然是一個個獨立的文件。
示例:
- 先啓動 yarn
start-yarn.sh
- 歸檔文件
hadoop archive -archiveName input.har -p /west /westAr
- 查看歸檔
hadoop fs -lsr /user/root/output/input.har
- 解歸檔文件
hadoop fs -cp har:/// user/root/output/input.har/* /user/root