1. 程式人生 > >Hadoop小檔案帶來的問題以及解決方案

Hadoop小檔案帶來的問題以及解決方案



       小檔案指的是那些size比HDFS的block size(預設64M)小的多的檔案。Hadoop適合處理少量的大檔案,而不是大量的
小檔案。

1, 小檔案導致的問題

       首先,在HDFS中,任何block,檔案或者目錄在記憶體中均以物件的形式儲存,每個物件約佔150byte,如果有1000 0000個小檔案,每個檔案佔用一個block,則namenode大約需要2G空間。如果儲存1億個檔案,則namenode需要20G空間。這樣namenode記憶體容量嚴重製約了叢集的擴充套件。
       其次,訪問大量小檔案速度遠遠小於訪問幾個大檔案。HDFS最初是為流式訪問大檔案開發的,如果訪問大量小檔案,需要不斷的從一個datanode跳到另一個datanode,嚴重影響效能。
       最後,處理大量小檔案速度遠遠小於處理同等大小的大檔案的速度。每一個小檔案要佔用一個slot,而task啟動將耗費大量時間甚至大部分時間都耗費在啟動task和釋放task上。


2,Hadoop自帶的解決方案

         對於小檔案問題,Hadoop本身也提供了幾個解決方案,分別為:Hadoop Archive,Sequence file和CombineFileInputFormat。

(1) Hadoop Archive

Hadoop Archive或者HAR,是一個高效地將小檔案放入HDFS塊中的檔案存檔工具,它能夠將多個小檔案打包成一個HAR檔案,這樣在減少namenode記憶體使用的同時,仍然允許對檔案進行透明的訪問。
對某個目錄/foo/bar下的所有小檔案存檔成/outputdir/ zoo.har:
hadoop archive -archiveName zoo.har -p /foo/bar /outputdir
當然,也可以指定HAR的大小(使用-Dhar.block.size)。
HAR是在Hadoop file system之上的一個檔案系統,因此所有fs shell命令對HAR檔案均可用,只不過是檔案路徑格式不一樣,HAR的訪問路徑可以是以下兩種格式:
har://scheme-hostname:port/archivepath/fileinarchive
har:///archivepath/fileinarchive(本節點)
可以這樣檢視HAR檔案存檔中的檔案:
hadoop dfs -ls har:///user/zoo/foo.har
輸出:
har:///user/zoo/foo.har/hadoop/dir1
har:///user/zoo/foo.har/hadoop/dir2


使用HAR時需要兩點,第一,對小檔案進行存檔後,原檔案並不會自動被刪除,需要使用者自己刪除;第二,建立HAR檔案的過程實際上是在執行一個mapreduce作業,因而需要有一個hadoop叢集執行此命令。
此外,HAR還有一些缺陷:第一,一旦建立,Archives便不可改變。要增加或移除裡面的檔案,必須重新建立歸檔檔案。第二,要歸檔的檔名中不能有空格,否則會丟擲異常,可以將空格用其他符號替換(使用-Dhar.space.replacement.enable=true 和-Dhar.space.replacement引數)。第三,存檔檔案不支援壓縮。

一個歸檔後的檔案,其儲存結構如下圖:


(2) Sequence file

Sequence file由一系列的二進位制key/value組成,如果為key小檔名,value為檔案內容,則可以將大批小檔案合併成一個大檔案。
Hadoop-0.21.0中提供了SequenceFile,包括Writer,Reader和SequenceFileSorter類進行寫,讀和排序操作。

HDFS小檔案處理解決方案總結+facebook(HayStack) + 淘寶(TFS)

建立sequence file的過程可以使用mapreduce工作方式完成,對於index,需要改進查詢演算法

優缺點:對小檔案的存取都比較自由,也不限制使用者和檔案的多少,但是該方法不能使用append方法,所以適合一次性寫入大量小檔案的場景


(3)CombineFileInputFormat

       CombineFileInputFormat是一種新的inputformat,用於將多個檔案合併成一個單獨的split,另外,它會考慮資料的儲存位置。