張 璐 楊東芳
(1.駐馬店職業技術學院信息工程系,河南 駐馬店463000;2.黃河交通學院機電工程學院,河南 焦作454950)
隨著計算機科學技術的飛速發展,信息逐漸被數據化,海量小文件的存儲給系統帶來巨大的壓力。首先文件系統在存儲小文件時需要反復請求存儲的地址,分配存儲空間,海量的小文件一起存儲就會占用服務器的內存從而超出計算機硬件的極限;其次,海量小文件的存儲使檢索效率降低。現有的存儲系統由于內存的現狀,當存放文件積累到一定數量,就沒法做到有效管理,從而導致檢索效率降低,甚至導致系統崩潰。因此,解決小文件訪問性能瓶頸的問題越來越迫切。
結構化存儲是在數據庫中將小文件整合成一個大文件一次性寫入,將小文件的內容作為二進制字符串的大字段存入數據庫中,由于每個字段都是固定的,而小文件則是在一定范圍內變化的,為了保證數據不因字段長度不夠而丟失,故在設計數據庫時會將字段設計得相對比較大,這樣就使小文件內容的存儲占據了大量的空白數據,造成磁盤資源的浪費,也會使數據庫在進行I/O操作時操作時間變長[1]。
歸檔文件是將文件合并后放入文件存檔設備,在文件系統上創建一個文件系統進行工作,雖然采用創建歸檔文件來處理小文件能夠降低內存的使用效率,但創建歸檔文件的同時會創建一個副本,需要同樣大小的磁盤空間,而且一旦創建后,歸檔文件就不能再改變,所以要增加或刪除文件時必須重新創建文件。
在分布式文件系統上設計一個小文件優化器,將小文件在優化器中進行合并,并且建立索引,這樣所有操作都在優化器中完成,而大文件直接存儲在文件系統,雖然避免了海量小文件存儲的麻煩,但如果小文件索引多到無法估計,就對優化器磁盤的容量提出挑戰。
構建結構體是將相同擴展名的小文件進行合并,元數據存儲于結構體的成員中,通過建立結構體中各文件間的存儲索引[2]。訪問時只需讀取要查找文件的擴展名,然后訪問名稱節點,名稱節點根據該擴展名返回一個索引塊列表;最后用戶根據這個塊列表訪問相應的數據結構體,在數據結構體中根據元數據進行截取,查找到原先的小文件進行截取并返回。雖然將多個小文件合并成一個大文件的方案能使原先小文件占用的名稱節點服務器的內存成倍數地降低,但是由于結構體在定義時已經設定了成員的大小,所以對于同類型但大小不一的小文件,傳統的合并方法會浪費大量的存儲空間。
在歸檔文件方法和文件優化器處理思想的基礎上進行改進,能夠使文件優化器的功能由傳統的結構化數據庫來實現。數據庫能存儲海量塊小的元數據,能快速建立索引,檢索速度比較快;而分布式文件系統可以多個存儲磁頭并行讀寫,文件的存儲和讀取帶寬較大,能夠突破數據庫存取的I/O瓶頸問題。文件系統與數據庫系統各盡其能,彌補了對方的不足[3-4]。由于實時存儲系統在這一時刻和下一時刻傳入的文件類型可能不同,不屬于同一個業務,可以根據他們不同的訪問字段來對部分常用字段建立非聚集索引,在不過分影響插入效率的前提下提高用戶查找文件的速度。
在合并文件時需要創建文件頭,記錄大文件中包含的小文件個數以及每個小文件的大小,并且與小文件放置在同一塊大緩存內,在數據庫中記錄文件的元數據信息及相應的大文件和在大文件中的具體位置,與構建結構體進行文件合并的方法相比,創建文件頭的合并機制更適合于文件大小有變動的海量小文件的合并,在進行文件讀取時通過查詢數據庫來獲取文件的邏輯地址并且對文件進行訪問。
首先,創建一個PingFile的類,其中包括:Name:大文件的文件名稱;size[count]:用于記錄每個小文件的大小;*addr[count]:用于記錄每個小文件的內存地址;timecount:用于記錄當前PingFile存在的時間;current:用于記錄當前狀態傳入的參數,要求存入PingFile的相對位置。count表示大文件中小文件數量的上限,timelimit表示等待時間的上限,當等待時間或數量達到上限時,開啟線程將PingFile中小文件的緩存按照表1的結構形式合并為一個大緩存并存入到文件系統中,提交本次數據庫的事務,完成一次小文件的合并及其元數據的入庫。程序接收到傳入的小文件,根據傳入的相關參數將文件塊存入大的緩存區內,并將小文件在大文件中的相對位置和大文件的命名作為元數據,放在數據庫事務中,以便保持數據庫和文件系統的一致性,然后繼續等待下一文件的傳入。當緩存區的文件達到合成條件時,將緩存塊生成數據文件存放在文件系統中,數據庫再次提交事務(見表1)。

表1 大文件緩存結構
在讀取文件時,首先根據查找信息在數據庫中查找相應的數據條目,如果找不到就直接返回,如果找到就遍歷所有的結果集,找到大文件的地址以及小文件在大文件中的相對位置,然后對大文件進行解析,根據小文件的存儲位置在緩存中取出小文件并返回給用戶,完成文件的讀取操作。

表2 合并文件個數與合并、讀取時間關系表

圖1 合并文件個數與合并、讀取時間關系圖
使用本地文件系統將300個不同的圖形文件(32KB至512KB不等)進行合并,之后對其進行逐一讀取,最后得到的圖形文件與原文件完全相同,其可行性得到了驗證。表2為512KB大小不同數目的小文件合并讀取的時間對比(時間為十次測試的平均值,每次讀取的是第30個小文件)。從圖1可以看出,合并與讀取所用時間基本和合并個數呈線性關系。
針對文件系統實時存儲海量小文件不方便,提出了基于數據庫的小文件合并方法,即對大量小文件的數據進行批量處理,在保證存取前后系統的穩定性和文件正確性的前提下,大幅度提高了文件系統對小文件存儲效率。通過文件系統與數據庫的結合,解決了文件系統的檢索瓶頸和數據庫I/O瓶頸問題,減少了存儲時間。但是需要指出的是,由于進行了文件合并,如果要對單個小文件進行修改操作,則需要對大文件中的片段進行解析、擴展或者縮減,會造成單個小文件更新操作的不方便。所以,該方法適用于量多塊小、時間分布均勻且更新頻度較小的數據倉庫類的工作業務流程。
[1]江柳.HDFS下小文件存儲優化相關技術研究[D],北京郵電大學,2010.
[2]http://hadoop.apache.org/mapreduce/docs/r0.21.0/hadoopp_archives.html.
[3]劉小俊,徐正全,潘少明.一種結合RDBMS和Hadoop的海量小文件存儲方法[J].武漢大學學報,2013(1):27-31.
[4]泰冬雪.基于Hadoop的海量小文件處理方法的研究[D].遼寧大學,2011.