檔案壓縮主要有兩個好處,一是減少了存儲檔所占空間,另一個就是為數據傳輸提速。 在hadoop大資料的背景下,這兩點尤為重要,那麼我現在就先來瞭解下hadoop中的檔案壓縮。
hadoop裡支援很多種壓縮格式,我們看一個表格:
DEFLATE是同時使用了LZ77演算法與哈夫曼編碼(Huffman HTTP://www.aliyun.com/zixun/aggregation/1552.html">Coding)的一個無損資料壓縮演算法, 原始程式碼可以在zlib庫中找到。 gzip是以DEFLATE演算法為基礎擴展出來的一種演算法。
所有的壓縮演算法都是空間和時間的轉換,更快壓縮時間還是更小的壓縮比,可以通過參數來指定,-1意味著速度,-9意味著空間。 拿gzip做個例子,下面就意味著更快速的壓縮:
[plain] view plaincopy
gzip -1 file
gzip在時間和空間上的取捨比較折中,bzip2壓縮比gzip更有效,但是速度更慢。 bzip2的解壓速度比它的壓縮速度要快。 但是和其他壓縮格式比又是最慢的,但是壓縮效果明顯是最好的。 snappy和lz4的解壓速度比lzo好很多。
splittable表示壓縮格式是否可以被分割,也就是說是否支援隨即讀。 壓縮資料是否能被mapreduce使用,壓縮資料是否能被分割就很關鍵了。
舉個例子,一個未壓縮的檔有1GB大小,hdfs預設的block大小是64MB,那麼這個檔就會被分為16個block作為mapreduce的輸入,每一個單獨使用一個map任務。 如果這個檔是已經使用gzip壓縮的呢,如果分成16個塊,每個塊做成一個輸入,顯然是不合適的,因為gzip壓縮流的隨即讀是不可能的。 實際上,當mapreduce處理壓縮格式的檔的時候它會認識到這是一個gzip的壓縮檔,而gzip又不支援隨即讀,它就會把16個塊分給一個map去處理,這裡就會有很多非本地處理的map任務,整個過程耗費的時間就會相當長。
lzo壓縮格式也會是同樣的問題,但是通過使用hadoop lzo庫的索引工具以後,lzo就可以支援splittable。 bzip2也是支援splittable的。
那麼如何選擇壓縮格式呢? 這取決於檔的大小,你使用的壓縮工具,下面是幾條選擇建議,效率由高到低排序:
1.用一些包含了壓縮並且支援splittable的檔案格式,比如Sequence File,RCFile或者Avro檔,這些檔案格式我們之後都會講到。 如果為了快速壓縮可以使用lzo,lz4或者snappy壓縮格式。
2.使用提供splittable的壓縮格式,比如,bzip2和索引後可以支援splittable的lzo。
3.提前把檔分成幾個塊,每個塊單獨壓縮,這樣就無需考慮splittable的問題了
4.不要壓縮檔
以不支援splittable的壓縮格式存儲一個很大的資料檔案是不合適的,非本地處理效率會非常之低。
感謝Tom White,此文章大部分來自于大神的definitive guide,奈何中文版翻譯太爛,就在英文原版的基礎上和官方的一些文檔加入一些自己的理解。
全當是讀書筆記吧,畫蛇添足之舉。