為啥集群小文件治理那么重要,你真的懂嗎?
小文件是 Hadoop 集群運維中的常見挑戰,尤其對于大規模運行的集群來說可謂至關重要。如果處理不好,可能會導致許多并發癥。Hadoop集群本質是為了TB,PB規模的數據存儲和計算應運而生的。為啥大數據開發都說小文件的治理重要,說HDFS 存儲小文件效率低下,比如增加namenode負載等,降低訪問效率等?究竟本質上為什么重要?以及如何從本質上剖析小文件,治理小文件呢?今天就帶你走進小文件的世界。
1.什么是小文件?
日常生產中HDFS上小文件產生是一個很正常的事情,有些甚至是不可避免,比如jar,xml配置文件,tmp臨時文件,流式任務等都是小文件的組成部分。當然更多的是因為集群設置不合理,造成一些意料之外的小文件產生。實際公司生產中對于小文件的大小沒有一個統一的定義。一般公司集群的blocksize的大小在128/256兩者居多。首先小文件大小肯定是要遠小于blocksize的文件。一般公司小文件的大小定義如1Mb,8Mb,甚至16Mb,32Mb更大。根據公司實際集群狀態定義,因為有些情況合并小文件需要消耗額外的資源。
既然剖析小文件,那么不可避免的要先剖析hdfs的存儲原理。眾多周知了,HDFS上文件的數據存儲分為namenode元數據管理和實際數據文件。hdfs上的數據文件被拆分成塊block,這些塊block在整個集群中的datanode的本地文件系統上存儲和復制,每個塊也維護者自己的blockmeta信息。namenode主要維護這些文件的元數據信息,具體namenode的解析參考我的其他博客。
如下一個某個文件的某個block在data上存儲的情況。
2.小文件的產生
1.流式數據,如flume,kafak,sparkstreaming,storm,flink等,流式增量文件,小窗口文件,如幾分鐘一次等。
2.MapReduce引擎任務:如果純map任務,大量的map;如果mapreduce任務,大量的reduce;兩者都會造成大量的文件。出現這種情況的原因很多,果分布表的過度分區,輸入大量的小文件,參數設置的不合理等,輸出沒有文件合并等。
3.spark任務過度并行化,Spark 分區越多,寫入的文件就越多。
4.文件的壓縮與存儲格式不合理;一般生產公司很少使用textfile這種低效的文件格式了。
使用壓縮,降低文件的大小,同時也會降低文件的總塊數。注意文件存儲格式和壓縮不合理只是加劇小文件問題,不是產生小文件的本質。
3.小文件的危害
3.1小文件對namenod的影響
如下圖1,一個文件192Mb,默認blocksize=128Mb,副本個數為3,存儲為2個block。
圖1
如下圖2,同樣一個文件192Mb,默認blocksize=128Mb,副本個數為3,存儲為192個block
圖2
namenode的namespace中主要占存儲對象是文件的目錄個數,文件(文件名長度)以及文件block數。根據namenode實際使用經驗來看,一個存儲對象大概占用150字節的空間。HDFS上存儲文件占用的namenode內存計算公式如下:
Memory=150bytes*(1個文件inode+(文件的塊數*副本個數))
如上圖1 ,一個文件192Mb,默認blocksize=128Mb,副本個數為3,存儲為2個block,需要namenode內存=150*(1+2*3)=1050 Bytes
同理,圖2 一個文件192Mb,默認blocksize=128Mb,副本個數為3,存儲為192個block,需要namenode內存=150 x (192 + (192 x 3)) = 115200 Bytes
尖叫總結:
1 .從上面可以看出,同樣的一個文件,大小不同形態的存儲占用namenode的內存之比相差了109倍之多。所以如果對于單namenode的集群來說,大量的小文件的會占用大量的namenode堆內存空間,給集群的存儲造成瓶頸。有些人可能會說我們聯邦,多組namenode不就沒有這個問題了,其實不然,且往下看
2.當 NameNode 重新啟動時(雖然生產上這種情況很少),它必須將文件系統元數據fsimage從本地磁盤加載到內存中。這意味著如果 namenode 元數據很大,重啟會更慢(以我們公司3億block,5萬多個文件對象來說,重啟一次1.5小時,期間應用不可用)其次,datanode 還通過網絡向 NameNode 報告塊更改;更多的塊意味著要通過網絡報告更多的變化,等待時間更長。
3.更多的文件,更多的block,意味著更多的讀取請求需要由 NameNode 提供服務,這將增加 RPC 隊列和處理延遲,進而導致namenode性能和響應能力下降。官方介紹說接近 40K~50K RPCs/s 人為是極高的負載。實際使用來看比這低時對于namenode來說性能都會打很大的折扣。
3.2 小文件對datanode影響
文件的block存儲是存儲在datanode本地系統上,底層的磁盤上,甚至不同的掛載目錄,不同的磁盤上。大量的小文件,意味著數據著尋址需要花費很多時間,尤其對于高負載的集群來說,磁盤使用率50%以上的集群,花費在尋址的時間比文件讀取寫入的時間更多。這種就違背了blocksize大小設計的初衷(實踐顯示最佳效果是:尋址時間僅占傳輸時間的1%)。這樣會造成磁盤的讀寫會很慢,擁有大量小文件會導致更多的磁盤搜索。如下磁盤延遲:
3.3小文件對計算的影響
基于HDFS文件系統的計算,blokc塊是最小粒度的數據處理單元。塊的多少往往影響應用程序的吞吐量。更多的文件,意味著更多的塊,以及更多的節點分布。
比如以MapReduce任務為例(hive等),在 MapReduce 中,會為每個讀取的塊生成一個單獨的 Map 任務,如果大量小文件,大量的塊,意味著著更多任務調度,任務創建開銷,以及更多的任務管理開銷(MapReduce 作業的 application master 是一個 Java 應用,它的主類是 MRAppMaster。它通過創建一定數量的bookkeeping object跟蹤作業進度來初始化作業,該對象接受任務報告的進度和完成情況)。雖然可以開啟map前文件合并,但是這也需要不停地從不同節點建立連接,數據讀取,網絡傳輸,然后進行合并,同樣會增加消耗資源和增加計算時間,成本也很高。
同樣,如果是spark計算引擎,executor的一次讀取和處理一個分區,默認情況下,每個分區是一個 HDFS 塊,如果大量的小文件,每個文件都在不同的分區中讀取,這將導致大量的任務調度開銷,同時每個 CPU 內核的吞吐量降低。
簡單總結一下:小文件對于計算的影響就是需要大量節點之間頻繁建立聯系,數據傳輸等,浪費資源,消耗時間長。其次小文件相關大量的任務初始化時間甚至比計算時間還長,造成計算資源的使用浪費,降低集群的吞吐量。
本文轉載自微信公眾號「滌生大數據」,作者「滌生大數據」,可以通過以下二維碼關注。
轉載本文請聯系「滌生大數據」公眾號。