摘 要:論文將通過具體設計,提出一個行之有效的處理分析Hadoop中海量小文件的應用方法。
關鍵詞:Hadoop 海量小文件 索引 算法
中圖分類號:TP391 文獻標識碼:A 文章編號:1672-3791(2012)10(a)-0013-01
目前,國內外很多大型企業和機構都采用Hadoop技術處理規模巨大的數據,但是如何高效穩定地處理好伴隨大數據而產生的各類海量小文件就成了一個決定系統穩定、數據可靠與否的重要依據。本文將根據個人研究淺談一下海量小文件的處理分析。
1 Hadoop中海量小文件處理存在的問題
1.1 海量的小文件堆積造成系統節點內存不足
我們知道在HDFS整合數據時,是將數據分割成若干塊存儲在多個數據節點上的。因此,HDFS存儲的大文件都是被分成許多塊分攤出去的。由此,不可避免的就會產生很多尺寸小,甚至比Hadoop應用中默認分塊小很多的小文件,這些文件被認為是不可以分塊的而被保留在了各個數據節點上。當這些海量小文件達到一定規模后就會淹沒數據節點的內存從而造成硬件內存供應不足的現象。
1.2 海量小文件的檢索效率低
由于Hadoop的分布式存儲對象是海量的廉價計算機,因此存儲系統中數據節點的內存限制也對可存放的文件數量造成了制約,從而增加了系統管理的難度。一但某一數據節點上出現了海量小文件,文件的檢索效率就會急劇下降,當小文件的數量達到一定規模后,甚至可能導致數據節點崩潰。
2 Hadoop中海量小文件的處理分析方法
2.1 構建海量小文件分析處理架構
文件→合并→建立索引→分布存儲。
將數據節點中的數據分成兩種塊形式。一種是存儲小文件的文件塊,一種是存儲索引的檢索塊。本架構的核心主要是處理分布式存儲小文件的單位數據。主要實現的一個過程是,先將數據節點上的海量小文件合并,寫入數據節點,再利用Map/Reduce對存儲在塊中的小文件分類并創建索引,然后將索引分布式存儲在數據節點上。
2.2 設計海量小文件合并算法
以時間作為合并的依據,創建以時間作為文件名字段的大文件,就能有效地應用Hadoop技術合理地生成系統可處理的塊文件。合并的設計算法如下:
小文件結構:LFile
String LFile_Name//小文件名
String LFile_Content//小文件內容,以字符型存儲
DateTime LFile_Time//小文件創建時間
Int Flag //小文件結尾標志符,如果為1,表示文件被刪除;如果為0則表示文件存在,標志符初始值為0
合并文件結構:CFile
String CFile_Name//合并文件名,含創建文件的時間信息
String CFile_Content//合并文件內容,包含每個小文件的名字、創建時間、內容及結尾標志符
DateTime CFile_Time//合并文件創建時間
Input: 小文件的結構體
Output:
Open(CFile[0]);
int i=0;//用于小文件的計數
While (T1 //定義時間字段T1,獲取小文件的生成時間;合并文件的創建時間其實就是我們定義的小文件合并的結束時間,一般取時間區間為1小時,即:T2=T1+3600s {WriteLine(LFile[i]); If(!LFile[i]. Flag) {Write the rest of LFile[i];} i++;} Close(CFile[0]); CFile.CFile_Name=(Char)T1; Return; 如上算法,每寫入一個小文件都有時間閥的判斷,則1小時內所需合并的n個小文件就有n次while的循環。其時間復雜度為n,空間復雜度為1。 2.3 設計海量小文件索引方法 由于海量小文件的增長是動態、不規律的,因此在無法確定每個父節點下的孩子數量的情況下,使用節省內存的孩子兄弟表示法就無法滿足要求。而Trie樹型的每個節點都有唯一的父節點,如果選擇雙親表示法就能唯一確定節點的指針域,從而便于磁盤存儲,使得內存分配更為規則。 要提高海量小文件的索引效率,僅僅建立一級索引是遠遠不夠的,因此在將一級索引建立在數據節點的基礎上,為了避免在調用索引時的頁面頻繁替換所造成的磁盤損壞和大量耗時,我們在一級索引的基礎上在數據節點內存中保存二級索引。這樣就能在每個數據節點上調用一個二級索引,而不會出現每個數據塊都建立二級索引。從而提高索引效率。 索引的構建過程主要分為三大塊。 (1)利用Map任務對海量小文件創建并行索引; (2)利用Reduce任務對所有小索引進行合并整理,形成能夠索引小文件的大索引。 (3)將文件擴展名放入名稱節點,并將擴展名下的索引文件分塊寫入對應的數據節點中。 2.4 設計海量小文件分塊方法 海量小文件分塊就是將全局索引根據數據節點上塊的大小進行分割,確保每個索引的完整性,使得文件查找過程中盡可能的節省索引次數。根據每個分割好的索引合理分配塊的位置,使其存儲在對應文件的相鄰節點上,減少通訊過長造成的代價損失。分塊遵循“塊中所有文件都具有相同擴展名”這一原則。具體算法如下: Int c1=0;//計數器 Int S;//樹的大小 Int BMax;//塊的最大值 Int BMin;//塊的最小值 If (S { If (S { While(c1 { Read next tree;//讀取下一顆樹 c1+=S;//合并樹 If (c1>=BMax) {Split(type 1,tree T,int Offset);//分裂樹} } Write into Block; //將樹放進塊中 } } Else {Split(type 1,tree T,int Offset);//分裂樹} 如上分塊算法能將某個擴展名下的樹都寫入塊中,不論同一擴展名下的樹是否寫滿都不再寫入,這樣才能使索引效率最大化。 3 結語 本文的研究工作有一定的借鑒作用,同時也存在了諸多不足之處。在未來的研究過程中,將探索Hadoop中小文件的更新方法,尤其是基于批量索引的更新將是一個復雜的過程。并結合實際環境進行真實系統測試。 參考文獻 [1] ZDNet,Nasuni Cloud Storage Gateway By Dan Kusnetzky,June 1,2010. [2] Hussam Abu-Libdeh,Lonnie Princehouse,Hakim Weatherspoon, RACS:a case for cloud storage diversity,2010. [3] Cong Wang,Qian Wang,Kui Ren, Wenjing Lou,Ensuring data storage security in Cloud Computing,2009.