壓縮概述
? ? 壓縮技術(shù)能夠有效減少底層存儲(chǔ)系統(tǒng)(HDFS)讀寫字節(jié)數(shù)百框。壓縮提高了網(wǎng)絡(luò)帶寬和磁盤空間的效率魂那。在運(yùn)行MR程序時(shí)奇钞,I/O操作 網(wǎng)絡(luò)數(shù)據(jù)傳輸 Shuffle和Merge要花大量的時(shí)間忽刽,尤其是數(shù)據(jù)規(guī)模很大和工作負(fù)載密集的情況下鲜侥,因此使用數(shù)據(jù)壓縮顯得非常重要褂始。
? ? 鑒于磁盤I/O和網(wǎng)絡(luò)帶寬是Hadoop的寶貴資源,數(shù)據(jù)壓縮對(duì)于節(jié)省資源描函,最小化磁盤I/O和網(wǎng)絡(luò)傳輸非常有幫助崎苗。可以在任意MapReduce階段啟用壓縮舀寓。不過(guò)盡管壓縮與解壓操作的CPU開銷不高胆数,其性能的提升和資源的節(jié)省并非沒(méi)有代價(jià)。
壓縮策略
? ? 壓縮是提高Hadoop運(yùn)行效率的一種優(yōu)化策略互墓。
? ? 通過(guò)對(duì)Mapper Reducer運(yùn)行過(guò)程的數(shù)據(jù)進(jìn)行壓縮必尼,以減少磁盤IO,提高M(jìn)R程序運(yùn)行速度篡撵。
? ? 注意:采用壓縮技術(shù)減少了磁盤IO判莉,但同時(shí)增加了CPU運(yùn)算負(fù)擔(dān)。所以壓縮特性運(yùn)用得當(dāng)能提高性能育谬,但運(yùn)用不當(dāng)也可能降低性能券盅。
壓縮基本原則
? ? 1)運(yùn)算密集型的job,少用壓縮
? ? 2)IO密集型的job膛檀,多用壓縮
MR支持的壓縮編碼
壓縮方式選擇
Gzip壓縮
? ? 優(yōu)點(diǎn):壓縮率比較高锰镀,而且壓縮/解呀速度也比較快;Hadoop本身支持咖刃,在應(yīng)用中處理Gzip格式的文件和直接處理文本一樣泳炉;大部分Linux系統(tǒng)都自帶Gzip命令,使用方便嚎杨。
? ? 缺點(diǎn):不支持Split
? ? 應(yīng)用場(chǎng)景:當(dāng)每個(gè)文件壓縮之后在130M以內(nèi)的(1個(gè)塊大小內(nèi))花鹅,都可以考慮用Gzip壓縮格式。例如說(shuō)一天或者一個(gè)小時(shí)的日志壓縮成一個(gè)Gzip文件磕潮。
Bzip2壓縮
? ? 優(yōu)點(diǎn):支持Split翠胰;具有很高的壓縮率容贝,比Gzip壓縮率都高;Hadoop本身自帶之景,使用方便斤富。
? ? 缺點(diǎn):壓縮/解壓速度慢。
? ? 應(yīng)用場(chǎng)景:適合對(duì)速度要求不高锻狗,但需要較高的壓縮率的時(shí)候满力;或者輸出之后的數(shù)據(jù)比較大,處理之后的數(shù)據(jù)需要壓縮存檔減少磁盤空間并且以后數(shù)據(jù)用得比較少的情況轻纪;或者對(duì)單個(gè)很大的文本文件想壓縮減少存儲(chǔ)空間油额,同時(shí)又需要支持Split,而且兼容之前的應(yīng)用程序的情況刻帚。
Lzo壓縮
? ? 優(yōu)點(diǎn):壓縮/解壓速度也比較快潦嘶,合理的壓縮率;支持Split崇众,是Hadoop中最流行的壓縮格式掂僵;可以在Linux系統(tǒng)下安裝lzop命令,使用方便顷歌。
? ? 缺點(diǎn):壓縮率比Gzip要低一些锰蓬;Hadoop本身不支持,需要安裝眯漩;在應(yīng)用中對(duì)Lzo格式的文件需要做一些特殊處理(為了支持Split需要建索引芹扭,還需要指定InputFormat為L(zhǎng)zo格式)。
? ? 應(yīng)用場(chǎng)景:一個(gè)很大的文本文件赦抖,壓縮之后還大于200M以上的可以考慮舱卡,而且單個(gè)文件越大,Lzo優(yōu)點(diǎn)越明顯摹芙。
Snappy壓縮
? ? 優(yōu)點(diǎn):高速壓縮速度和合理的壓縮率
? ? 缺點(diǎn):不支持Split灼狰;壓縮率比Gzip要低;Hadoop本身不支持浮禾,需要安裝交胚。
? ? 應(yīng)用場(chǎng)景:當(dāng)MapReduce作業(yè)的Map輸出的數(shù)據(jù)比較大的時(shí)候,作為Map到Reduce中間數(shù)據(jù)的壓縮格式盈电;或者作為一個(gè)MapReduce作業(yè)的輸出和另外一個(gè)MapReduce作業(yè)的輸入蝴簇。
壓縮位置選擇
? ? 壓縮可以在MapReduce作用的任意階段啟用
壓縮參數(shù)配置
壓縮實(shí)操案例
? ? 數(shù)據(jù)流的壓縮和解壓縮
????????CompressionCodec有兩個(gè)方法可以用于輕松地壓縮或解壓縮數(shù)據(jù)。
? ? ? ? 要想對(duì)一個(gè)正在被寫入一個(gè)輸出流的數(shù)據(jù)進(jìn)行壓縮匆帚,我們可以使用createOutputStream(OutputStreamout)方法創(chuàng)建一個(gè)CompressionOutputStream熬词,將其以壓縮格式寫入底層的流。
? ? ? ? 相反,要想對(duì)從輸入流讀取而來(lái)的數(shù)據(jù)進(jìn)行解壓縮互拾,則調(diào)用createInputStream(InputStreamin)函數(shù)歪今,從而獲得一個(gè)CompressionInputStream,從而從底層的流讀取未壓縮的數(shù)據(jù)颜矿。
Map輸出端采用壓縮
? ? 即使你的MapReduce的輸入輸出文件都是未壓縮的文件寄猩,你仍然可以對(duì)Map任務(wù)的中間結(jié)果輸出做壓縮,因?yàn)樗獙懺谟脖P并且通過(guò)網(wǎng)絡(luò)傳輸?shù)絉educe節(jié)點(diǎn)骑疆,對(duì)其壓縮可以提高很多性能田篇。
Configuration conf = new Configuration();
// 開啟map端輸出壓縮
conf.setBoolean("mapreduce.map.output.compress", true);
// 設(shè)置map端輸出壓縮方式
conf.setClass(“mapreduce.map.output.compress.codec”, BZip2Codec.class, CompressionCodec.class);
Reduce輸出端采用壓縮
// 設(shè)置reduce端輸出壓縮開啟
FileOutputFormat.setCompressOutput(job, true);
// 設(shè)置壓縮的方式
FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class);