http://www.cnblogs.com/forfuture1978/archive/2010/03/14/1685351.html
1.1、數據塊(block)
- HDFS(Hadoop Distributed File System)默認的最基本的存儲單位是64M的數據塊。
- 和普通文件系統相同的是,HDFS中的文件是被分成64M一塊的數據塊存儲的。
- 不同於普通文件系統的是,HDFS中,如果一個文件小於一個數據塊的大小,並不佔用整個數據塊存儲空間。
1.2、元數據節點(Namenode)和數據節點(datanode)
- 元數據節點用來管理文件系統的命名空間
- 其將所有的文件和文件夾的元數據保存在一個文件系統樹中。
- 這些信息也會在硬盤上保存成以下文件:命名空間鏡像(namespace image)及修改日誌(edit log)
- 其還保存了一個文件包括哪些數據塊,分佈在哪些數據節點上。然而這些信息並不存儲在硬盤上,而是在系統啓動的時候從數據節點收集而成的。
- 數據節點是文件系統中真正存儲數據的地方。
- 客戶端(client)或者元數據信息(namenode)可以向數據節點請求寫入或者讀出數據塊。
- 其週期性的向元數據節點回報其存儲的數據塊信息。
- 從元數據節點(secondary namenode)
- 從元數據節點並不是元數據節點出現問題時候的備用節點,它和元數據節點負責不同的事情。
- 其主要功能就是週期性將元數據節點的命名空間鏡像文件和修改日誌合併,以防日誌文件過大。這點在下面會相信敘述。
- 合併過後的命名空間鏡像文件也在從元數據節點保存了一份,以防元數據節點失敗的時候,可以恢復。
1.2.1、元數據節點文件夾結構
- VERSION文件是java properties文件,保存了HDFS的版本號。
- layoutVersion是一個負整數,保存了HDFS的持續化在硬盤上的數據結構的格式版本號。
- namespaceID是文件系統的唯一標識符,是在文件系統初次格式化時生成的。
- cTime此處爲0
- storageType表示此文件夾中保存的是元數據節點的數據結構。
namespaceID=1232737062 cTime=0 storageType=NAME_NODE layoutVersion=-18 |
1.2.2、文件系統命名空間映像文件及修改日誌
- 當文件系統客戶端(client)進行寫操作時,首先把它記錄在修改日誌中(edit log)
- 元數據節點在內存中保存了文件系統的元數據信息。在記錄了修改日誌後,元數據節點則修改內存中的數據結構。
- 每次的寫操作成功之前,修改日誌都會同步(sync)到文件系統。
- fsimage文件,也即命名空間映像文件,是內存中的元數據在硬盤上的checkpoint,它是一種序列化的格式,並不能夠在硬盤上直接修改。
- 同數據的機制相似,當元數據節點失敗時,則最新checkpoint的元數據信息從fsimage加載到內存中,然後逐一重新執行修改日誌中的操作。
- 從元數據節點就是用來幫助元數據節點將內存中的元數據信息checkpoint到硬盤上的
- checkpoint的過程如下:
- 從元數據節點通知元數據節點生成新的日誌文件,以後的日誌都寫到新的日誌文件中。
- 從元數據節點用http get從元數據節點獲得fsimage文件及舊的日誌文件。
- 從元數據節點將fsimage文件加載到內存中,並執行日誌文件中的操作,然後生成新的fsimage文件。
- 從元數據節點獎新的fsimage文件用http post傳回元數據節點
- 元數據節點可以將舊的fsimage文件及舊的日誌文件,換爲新的fsimage文件和新的日誌文件(第一步生成的),然後更新fstime文件,寫入此次checkpoint的時間。
- 這樣元數據節點中的fsimage文件保存了最新的checkpoint的元數據信息,日誌文件也重新開始,不會變的很大了。
1.2.3、從元數據節點的目錄結構
1.2.4、數據節點的目錄結構
- 數據節點的VERSION文件格式如下:
namespaceID=1232737062 storageID=DS-1640411682-127.0.1.1-50010-1254997319480 cTime=0 storageType=DATA_NODE layoutVersion=-18 |
- blk_<id>保存的是HDFS的數據塊,其中保存了具體的二進制數據。
- blk_<id>.meta保存的是數據塊的屬性信息:版本信息,類型信息,和checksum
- 當一個目錄中的數據塊到達一定數量的時候,則創建子文件夾來保存數據塊及數據塊屬性信息。
二、數據流(data flow)
2.1、讀文件的過程
- 客戶端(client)用FileSystem的open()函數打開文件
- DistributedFileSystem用RPC調用元數據節點,得到文件的數據塊信息。
- 對於每一個數據塊,元數據節點返回保存數據塊的數據節點的地址。
- DistributedFileSystem返回FSDataInputStream給客戶端,用來讀取數據。
- 客戶端調用stream的read()函數開始讀取數據。
- DFSInputStream連接保存此文件第一個數據塊的最近的數據節點。
- Data從數據節點讀到客戶端(client)
- 當此數據塊讀取完畢時,DFSInputStream關閉和此數據節點的連接,然後連接此文件下一個數據塊的最近的數據節點。
- 當客戶端讀取完畢數據的時候,調用FSDataInputStream的close函數。
- 在讀取數據的過程中,如果客戶端在與數據節點通信出現錯誤,則嘗試連接包含此數據塊的下一個數據節點。
- 失敗的數據節點將被記錄,以後不再連接。
2.2、寫文件的過程
- 客戶端調用create()來創建文件
- DistributedFileSystem用RPC調用元數據節點,在文件系統的命名空間中創建一個新的文件。
- 元數據節點首先確定文件原來不存在,並且客戶端有創建文件的權限,然後創建新文件。
- DistributedFileSystem返回DFSOutputStream,客戶端用於寫數據。
- 客戶端開始寫入數據,DFSOutputStream將數據分成塊,寫入data queue。
- Data queue由Data Streamer讀取,並通知元數據節點分配數據節點,用來存儲數據塊(每塊默認複製3塊)。分配的數據節點放在一個pipeline裏。
- Data Streamer將數據塊寫入pipeline中的第一個數據節點。第一個數據節點將數據塊發送給第二個數據節點。第二個數據節點將數據發送給第三個數據節點。
- DFSOutputStream爲發出去的數據塊保存了ack queue,等待pipeline中的數據節點告知數據已經寫入成功。
- 如果數據節點在寫入的過程中失敗:
- 關閉pipeline,將ack queue中的數據塊放入data queue的開始。
- 當前的數據塊在已經寫入的數據節點中被元數據節點賦予新的標示,則錯誤節點重啓後能夠察覺其數據塊是過時的,會被刪除。
- 失敗的數據節點從pipeline中移除,另外的數據塊則寫入pipeline中的另外兩個數據節點。
- 元數據節點則被通知此數據塊是複製塊數不足,將來會再創建第三份備份。
- 當客戶端結束寫入數據,則調用stream的close函數。此操作將所有的數據塊寫入pipeline中的數據節點,並等待ack queue返回成功。最後通知元數據節點寫入完畢。