1.压缩概述
压缩优缺点:减少磁盘IO时间、节省磁盘空间;增加CPU开销
压缩原则:CPU密集型Job,少用压缩;IO密集型Job,多用压缩
2.压缩算法比较
压缩格式 | Hadoop自带 | 算法 | 扩展名 | 可切片 | 程序是否需修改 | 压缩速度MB/S | 解压速度MB/S |
---|---|---|---|---|---|---|---|
DEFLATE | 是 | DEFLATE | .deflate | 否 | 否 | ||
Gzip | 是 | DEFLATE | .gz | 否 | 否 | 17.5 | 58 |
Bzip2 | 是 | bzip2 | .bz2 | 是 | 否 | 2.4 | 9.5 |
LZO | 否,需安装 | LZO | .lzo | 是 | 需要建索引并指定输入格式 | 49.3 | 74.6 |
Snappy | 是 | Snappy | .snappy | 否 | 否 | 250 | 500 |
3.压缩算法选择
压缩方式选择时重点考虑:解压缩速度、压缩率、压缩后是否支持切片
Mapper输入端压缩:无需显示指定编解码方式。Hadoop自动检查文件扩展名,如果匹配,就会用恰当的方式对文件进行压缩和解压。数据量小于块大小,重点考虑压缩比较快的LZO与Snappy;如果数据量非常大,重点考虑支持切片的Bzip2和LZO
Mapper输出端压缩:为了减少MapTask和ReduceTask之间的网络IO,重点考虑解压缩比较快的LZO与Snappy
Reducer输出端压缩:如果数据永久保存,考虑压缩率比较高的Bzip2和Gzip
4.压缩算法实践
我们执行hadoop checknative
查看目前支持的算法
public class WordCountCompressDriver {
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
Configuration conf = new Configuration();
// 开启map端输出压缩
conf.setBoolean("mapreduce.map.output.compress", true);
// 设置map端输出压缩格式
conf.setClass("mapreduce.map.output.compress.codec", BZip2Codec.class, CompressionCodec.class);
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCountCompressDriver.class);
job.setMapperClass(WordCountMapper.class);
job.setCombinerClass(WordCountReduce.class);
job.setReducerClass(WordCountReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// 开始Reduce端输出压缩
FileOutputFormat.setCompressOutput(job, true);
//FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class);
// 设置压缩编码
FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
欢迎关注公众号算法小生与我沟通交流