《深入理解大数据:大数据处理与编程实践》一一3.3 HDFS文件存储组织与读写...
本節書摘來自華章計算機《深入理解大數據:大數據處理與編程實踐》一書中的第3章,第3.3節,作者 主 編:黃宜華(南京大學)副主編:苗凱翔(英特爾公司),更多章節內容可以訪問云棲社區“華章計算機”公眾號查看。
3.3 HDFS文件存儲組織與讀寫
作為一個分布式文件系統,HDFS內部的數據與文件存儲機制、讀寫過程與普通的本地文件系統有較大的差別。下面具體介紹HDFS中數據的存儲組織和讀寫過程。
3.3.1 文件數據的存儲組織
如前所述,HDFS中最主要的部分就是NameNode和DataNode。NameNode存儲了所有文件元數據、文件與數據塊的映射關系,以及文件屬性等核心數據,DataNode則存儲了具體的數據塊。那么,在HDFS中,具體的文件存儲組織結構是怎樣的呢?
1.?NameNode目錄結構
圖3-3是NameNode的目錄結構和內容。NameNode借助本地文件系統來保存數據,保存的文件夾位置由配置選項{dfs.name.dir}決定(未配置此選項,則為hadoop安裝目錄下的/tmp/dfs/name),所以,這里我們以${dfs.name.dir}代表NameNode節點管理的根目錄。目錄下的文件和子目錄則以${dfs.name.dir}/file和${dfs.name.dir}/subdir的格式表示。
在NameNode的${dfs.name.dir}之下有3個文件夾和1個文件:
1)current目錄:主要包含如下的內容和結構:
a)文件VERSION:保存了當前運行的HDFS版本信息。
b)FsImage:是整個系統的空間鏡像文件。
c)Edit:EditLog編輯日志。
d)Fstime:上一次檢查點的時間。
2)previous.checkpoint目錄:和current內容結構一致,不同之處在于,此目錄保存的是上一次檢查點的內容。
3)image目錄:舊版本(版本<0.13)的FsImage存儲位置。
4)in_use.lock:NameNode鎖,只有在NameNode有效(啟動并且能和DataNode正常交互)時存在;不滿足上述情況時,該文件不存在。這一文件具有“鎖”的功能,可以防止多個NameNode共享同一目錄(如果一個機器上只有一個NameNode,這也是最常見的情況,那么這個文件基本不需要)。
2.?DataNode目錄結構
圖3-4是DataNode的目錄結構和內容。DataNode借助本地文件系統來保存數據,一般情況下,保存的文件夾位置由配置選項{dfs.data.dir}決定(未配置此選項,則為hadoop安裝目錄下的/tmp/dfs/data)。所以,這里我們以${dfs.data.dir}代表DataNode節點管理的數據目錄的根目錄,目錄下的文件和子目錄則以${dfs.data.dir}/file和${dfs.data.dir}/subdir的格式表示。
圖3-4 HDFS DataNode目錄結構
一般來說,在${dfs.data.dir}之下有4個子目錄和2個文件:
1)current目錄:已經成功寫入的數據塊,以及一些系統需要的文件。包括以下內容:
a)文件VERSION:保存了當前運行的HDFS版本信息。
b)Blk_XXXXX和Blk_XXXXX.Meta:分別是數據塊和數據塊對應的元數據(比如校驗信息等)。
c)subdirXX:當同一目錄下文件數超過一定限制(比如64)時,會新建一個subdir目錄,保存多出來的數據塊和元數據;這樣可以保證同一目錄下目錄+文件數不會太多,可以提高搜索效率。
2)tmp目錄和blocksBeingWritten目錄:正在寫入的數據塊,tmp目錄保存的是用戶操作引發的寫入操作對應的數據塊,blocksBeingWritten目錄是HDFS系統內部副本創建時(當出現副本錯誤或者數量不夠等情況時)引發的寫入操作對應的數據塊。
3)detach目錄:用于DataNode升級。
4)storage文件:由于舊版本(版本<0.13)的存儲目錄是storage,因此如果在新版本的DataNode中啟動舊版的HDFS,會因為無法打開storage目錄而啟動失敗,這樣可以防止因版本不同帶來的風險。
5)in_use.lock文件:DataNode鎖,只有在DataNode有效(啟動并且能和NameNode正常交互)時存在;不滿足上述情況時,該文件不存在。這一文件具有“鎖”的功能,可以防止多個DataNode共享同一目錄(如果一個機器上只有一個DataNode,這也是最常見的情況,那么這個文件基本不需要)。
3.?CheckPointNode目錄結構
圖3-5是CheckPointNode的目錄結構和內容。CheckPointNode和舊版本的SecondaryName
Node作用類似,所以目錄結構也十分相近。
圖3-5 HDFS CheckPointNode目錄結構
CheckPointNode借助本地文件系統來保存數據,一般情況下,保存的文件夾位置由配置選項{dfs.checkpoint.dir}決定(未配置此選項,則為hadoop安裝目錄下的/tmp/dfs/namesecondary)。所以,這里我們以${dfs.checkpoint.dir}代表CheckPointNode節點管理的數據目錄的根目錄,目錄下的文件和子目錄則以${dfs.checkpoint.dir}和file,${dfs.checkpoint.dir}/subdir的格式表示。
CheckPointNode目錄下的文件和NameNode目錄下的同名文件作用基本一致,不同之處在于CheckPointNode保存的是自上一個檢查點之后的臨時鏡像和日志。
3.3.2 數據的讀寫過程
數據的讀寫過程與數據的存儲是緊密相關的,以下介紹HDFS數據的讀寫過程。
1.?數據讀取過程
一般的文件讀取操作包括open、read、close等,具體可參見3.5節的HDFS編程接口介紹。這里介紹一下客戶端連續調用open、read、close時,HDFS內部的整個執行過程。圖3-6可以幫助我們更好地理解這個過程。
圖3-6 HDFS數據讀取過程
以下是客戶端讀取數據的過程,其中1、3、6步由客戶端發起:
客戶端首先要獲取FileSystem的一個實例,這里就是HDFS對應的實例。
1)首先,客戶端調用FileSystem實例的open方法,獲得這個文件對應的輸入流,在HDFS中就是DFSInputStream。
2)構造第1步中的輸入流DFSInputStream時,通過RPC遠程調用NameNode可以獲得NameNode中此文件對應的數據塊保存位置,包括這個文件的副本的保存位置(主要是各DataNode的地址)。注意,在輸入流中會按照網絡拓撲結構,根據與客戶端距離對DataNode進行簡單排序。
3~4)獲得此輸入流之后,客戶端調用read方法讀取數據。輸入流DFSInputStream會根據前面的排序結果,選擇最近的DataNode建立連接并讀取數據。如果客戶端和其中一個DataNode位于同一機器(比如MapReduce過程中的mapper和reducer),那么就會直接從本地讀取數據。
5)如果已到達數據塊末端,那么關閉與這個DataNode的連接,然后重新查找下一個數據塊。
不斷執行第2~5步直到數據全部讀完,然后調用close。
6)客戶端調用close,關閉輸入流DFSInputStream。
另外,如果DFSInputStream和DataNode通信時出現錯誤,或者是數據校驗出錯,那么DFSInputStream就會重新選擇DataNode傳輸數據。
2.?數據寫入過程
一般的文件寫入操作不外乎create、write、close幾種,具體可參見3.5節的HDFS編程接口介紹。這里介紹一下客戶端連續調用create、write、close時,HDFS內部的整個執行過程,見圖3-7。
以下是客戶端寫入數據的過程,其中1、3、6步由客戶端發起:
客戶端首先要獲取FileSystem的一個實例,這里就是HDFS對應的實例。
1~2)客戶端調用FileSystem實例的create方法,創建文件。NameNode通過一些檢查,比如文件是否存在,客戶端是否擁有創建權限等;通過檢查之后,在NameNode添加文件信息。注意,因為此時文件沒有數據,所以NameNode上也沒有文件數據塊的信息。創建結束之后,HDFS會返回一個輸出流DFSDataOutputStream給客戶端。
3)客戶端調用輸出流DFSDataOutputStream的write方法向HDFS中對應的文件寫入數據。數據首先會被分包,這些分包會寫入一個輸出流的內部隊列Data隊列中,接收完數據分包,輸出流DFSDataOutputStream會向NameNode申請保存文件和副本數據塊的若干個DataNode,這若干個DataNode會形成一個數據傳輸管道。
4)DFSDataOutputStream會(根據網絡拓撲結構排序)將數據傳輸給距離上最短的DataNode,這個DataNode接收到數據包之后會傳給下一個DataNode。數據在各DataNode之間通過管道流動,而不是全部由輸出流分發,這樣可以減少傳輸開銷。
5)因為各DataNode位于不同機器上,數據需要通過網絡發送,所以,為了保證所有DataNode的數據都是準確的,接收到數據的DataNode要向發送者發送確認包(ACK Packet)。對于某個數據塊,只有當DFSDataOutputStream收到了所有DataNode的正確ACK,才能確認傳輸結束。DFSDataOutputStream內部專門維護了一個等待ACK隊列,這一隊列保存已經進入管道傳輸數據、但是并未被完全確認的數據包。
不斷執行第3~5步直到數據全部寫完,客戶端調用close關閉文件。
6)客戶端調用close方法,DFSDataInputStream繼續等待直到所有數據寫入完畢并被確認,調用complete方法通知NameNode文件寫入完成。
7)NameNode接收到complete消息之后,等待相應數量的副本寫入完畢后,告知客戶端即可。
在傳輸數據的過程中,如果發現某個DataNode失效(未聯通,ACK超時),那么HDFS執行如下操作:
1)關閉數據傳輸的管道。
2)將等待ACK隊列中的數據放到Data隊列的頭部。
3)更新正常DataNode中所有數據塊的版本;當失效的DataNode重啟之后,之前的數據塊會因為版本不對而被清除。
4)在傳輸管道中刪除失效的DataNode,重新建立管道并發送數據包。
以上就是HDFS中數據讀寫的大致過程。
總結
以上是生活随笔為你收集整理的《深入理解大数据:大数据处理与编程实践》一一3.3 HDFS文件存储组织与读写...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 7月份计划-----dream
- 下一篇: 越南黑客组织APT32正对NSA网络武器