您好,登錄后才能下訂單哦!
? 壓縮技術(shù)可以減少底層hdfs的讀寫字節(jié)數(shù)。并且能夠降低在數(shù)據(jù)傳輸過(guò)程中占用的網(wǎng)絡(luò)帶寬資源,以及降低占用的磁盤空間。而在MapReduce中,shuffle以及merge過(guò)程都面臨著巨大的IO壓力。但是要注意增加了壓縮,另外一方面會(huì)增加cpu的負(fù)載。所以在要權(quán)衡好是否采用壓縮,以及采用的壓縮算法的特性。
運(yùn)算密集型的job,少用壓縮。因?yàn)閴嚎s占用cpu。
IO密集型的job,可用壓縮減少數(shù)據(jù)量。
選擇壓縮算法時(shí),要注意壓縮比,壓縮比越大,壓縮以及解壓時(shí)間越長(zhǎng)。
壓縮格式 | hadoop是否自帶 | 算法 | 文件擴(kuò)展名 | 可否可切分 | 換成壓縮格式后,原來(lái)的程序是否需要修改 |
---|---|---|---|---|---|
DEFAULT | 是 | DEFAULT | .deflate | 否 | 與普通文本處理一樣,不需要修改 |
gzip | 是 | DEFAULT | .gz | 否 | 與普通文本處理一樣,不需要修改 |
bzip2 | 是 | bzip2 | .bz2 | 是 | 與普通文本處理一樣,不需要修改 |
LZO | 需另外安裝 | lzo | .lzo | 是 | 需要建立索引文件,還需要指定輸出格式 |
snappy | 需另外安裝 | snappy | .snappy | 否 | 與普通文本處理一樣,不需要修改 |
壓縮格式 | 對(duì)應(yīng)編解碼器 |
---|---|
DEFAULT | org.apache.hadoop.io.compress.DefaultCodec |
gzip | org.apache.hadoop.io.compress.GzipCodec |
bzip2 | org.apache.hadoop.io.compress.BZip2Codec |
lzo | com.hadoop.compression.lzo.LzopCodec |
snappy | org.apache.hadoop.io.compress.SnappyCodec |
優(yōu)點(diǎn):
壓縮率高,解壓、壓縮速度也必比較快。hadoop本身自帶,在應(yīng)用中處理gzip格式的文件就和直接處理文本一樣。大部分Linux自帶gzip命令,使用方便。
缺點(diǎn):不支持split
適用場(chǎng)景:
當(dāng)每個(gè)文件壓縮之后在一個(gè)block左右的大?。ㄒ?yàn)闊o(wú)法分片),都可以考慮使用gzip將原數(shù)據(jù)壓縮。例如可以將一天或者一小時(shí)的日志壓縮成一個(gè)gzip文件,運(yùn)行MapReduce的時(shí)候就可以并行處理多個(gè)gzip。hive,streaming,MapReduce程序處理壓縮文件時(shí),無(wú)需修改程序,就像處理文本文件一樣。
優(yōu)點(diǎn):
支持split;高壓縮比,比gzip高。hadoop自帶,Linux下自帶bzip2命令
缺點(diǎn):壓縮、解壓速度慢,不支持native(java和C交互的api接口)
適用場(chǎng)景:
適合對(duì)速度要求不高,但需要較高的壓縮率的時(shí)候,可以作為mapreduce作業(yè)的輸出格式;或者輸出之后的數(shù)據(jù)比較大,處理之后的數(shù)據(jù)需要壓縮存檔減少磁盤空間并且以后數(shù)據(jù)用得比較少的情況;或者對(duì)單個(gè)很大的文本文件想壓縮減少存儲(chǔ)空間,同時(shí)又需要支持split,而且兼容之前的應(yīng)用程序(即應(yīng)用程序不需要修改)的情況。
優(yōu)點(diǎn):
壓縮/解壓速度比較快,壓縮率合理(比gzip和bzip2?。?。支持split,是hadoop中最流行的壓縮格式??梢栽贚inux下可以通過(guò)安裝lzop命令來(lái)使用
缺點(diǎn):
壓縮率比gzip要低一些;hadoop本身不支持,需要安裝;在應(yīng)用中對(duì)lzo格式的文件需要做一些特殊處理(為了支持split需要建索引,還需要指定inputformat為lzo格式)。
適用場(chǎng)景:
一個(gè)很大的文本文件,壓縮之后還大于200M以上的可以考慮,而且單個(gè)文件越大,lzo優(yōu)點(diǎn)越越明顯。
優(yōu)點(diǎn):壓縮和解壓速度快,合理的壓縮率
缺點(diǎn):不支持的split,壓縮率比gzip要低;hadoop本身不支持,需要安裝
適用場(chǎng)景:
當(dāng)Mapreduce作業(yè)的Map輸出的數(shù)據(jù)比較大的時(shí)候,作為Map到Reduce的中間數(shù)據(jù)的壓縮格式;或者作為一個(gè)Mapreduce作業(yè)的輸出和另外一個(gè)Mapreduce作業(yè)的輸入。
可以用在MapReduce的任意階段輸出、原始數(shù)據(jù)的壓縮、reduce的輸出等
參數(shù) | 默認(rèn)值 | 階段 | 建議 |
---|---|---|---|
io.compression.codecs (在core-site.xml中配置) | org.apache.hadoop.io.compress.DefaultCodec, org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.BZip2Codec | 輸入壓縮 | Hadoop使用文件擴(kuò)展名判斷是否支持某種編解碼器 |
mapreduce.map.output.compress(在mapred-site.xml中配置) | false | map輸出 | 這個(gè)參數(shù)設(shè)為true啟用壓縮 |
mapreduce.map.output.compress.codec(在mapred-site.xml中配置) | org.apache.hadoop.io.compress.DefaultCodec | mapper輸出 | 使用LZO或snappy編解碼器在此階段壓縮數(shù)據(jù) |
mapreduce.output.fileoutputformat.compress(在mapred-site.xml中配置) | false | reduce輸出 | 這個(gè)參數(shù)設(shè)為true啟用壓縮 |
mapreduce.output.fileoutputformat.compress.codec(在mapred-site.xml中配置) | org.apache.hadoop.io.compress. DefaultCodec | reduce輸出 | 使用gzip或者bzip2來(lái)壓縮 |
mapreduce.output.fileoutputformat.compress.type(在mapred-site.xml中配置) | RECORD | reduce輸出 | SequenceFile輸出使用的壓縮類型:NONE和BLOCK |
package JavaCompress;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.CompressionCodecFactory;
import org.apache.hadoop.io.compress.CompressionInputStream;
import org.apache.hadoop.io.compress.CompressionOutputStream;
import org.apache.hadoop.util.ReflectionUtils;
import java.io.*;
public class TestCompress {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//compress("G:\\Fly Away-梁靜茹.mp3", "org.apache.hadoop.io.compress.GzipCodec");
deCompress("G:\\Fly Away-梁靜茹.mp3.gz", "mp3");
}
//壓縮
public static void compress(String filename, String method) throws IOException, ClassNotFoundException {
//創(chuàng)建輸入流
FileInputStream fis = new FileInputStream(new File(filename));
//通過(guò)反射獲取壓縮類的Class 對(duì)象
Class codecClass = Class.forName(method);
//通過(guò)反射獲取壓縮對(duì)象
CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(codecClass, new Configuration());
//創(chuàng)建普通輸出流對(duì)象
FileOutputStream fos = new FileOutputStream(new File(filename + codec.getDefaultExtension()));
//通過(guò)壓縮對(duì)象創(chuàng)建壓縮輸出流,類似于將普通輸出流封裝成壓縮輸出流
CompressionOutputStream cos = codec.createOutputStream(fos);
//流拷貝
IOUtils.copyBytes(fis, cos, 1024 * 1024 * 5, false);
fis.close();
cos.close();
fos.close();
}
//解壓
public static void deCompress(String filename, String decode) throws IOException {
CompressionCodecFactory factory = new CompressionCodecFactory(new Configuration());
//獲取文件的壓縮算法類型對(duì)象,返回值可用于檢查文件是否可解壓
CompressionCodec codec = factory.getCodec(new Path(filename));
if (codec == null) {
System.out.println("不支持解壓縮:" + filename);
return;
}
//根據(jù)壓縮文件的壓縮類型,返回的對(duì)象用于創(chuàng)建壓縮輸入流
CompressionInputStream cis = codec.createInputStream(new FileInputStream(new File(filename)));
//創(chuàng)建輸出流
FileOutputStream fos = new FileOutputStream(new File(filename + decode));
IOUtils.copyBytes(cis, fos, 1024 * 1024 * 5, false);
cis.close();
fos.close();
}
}
用法很簡(jiǎn)單,只需在driver中給job配置以下參數(shù)即可
Configuration configuration = new Configuration();
// 開啟map端輸出壓縮
configuration.setBoolean("mapreduce.map.output.compress", true);
// 設(shè)置map端輸出壓縮方式
configuration.setClass("mapreduce.map.output.compress.codec", BZip2Codec.class, CompressionCodec.class);
依舊是在driver中設(shè)置以下
// 設(shè)置reduce端輸出壓縮開啟
FileOutputFormat.setCompressOutput(job, true);
// 設(shè)置壓縮的方式
FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class);
// FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class);
// FileOutputFormat.setOutputCompressorClass(job, DefaultCodec.class);
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。