1:压缩的好处和坏处
压缩的优点:减少磁盘IO、减少磁盘存储空间
2:压缩原则
1:运算密集型的Job,少用压缩
2:IO密集型的Job,多用压缩
3:压缩算法对比
压缩格式 | Hadoop自带? | 算法 | 文件扩展名 | 是否可切片 | 换成压缩格式后,原来的程序是否需要修改 |
DEFLATE | 是 | DEFLATE | .deflate | 否 | 和文件处理一样,不需要修改 |
GZIP | 是 | DEFLATE | .gz | 否 | 和文件处理一样,不需要修改 |
BZIP2 | 是 | bzip2 | .bz2 | 是 | 和文件处理一样,不需要修改 |
LZ0 | 否,需安装 | LZ0 | .lz0 | 是 | 需要建索引,还需要指定输入格式 |
SNAPPY | 是 | snappy | .snappy | 否 | 和文件处理一样,不需要修改 |
4:压缩方式的选择
压缩方式的选择时重点考虑:压缩/解压缩速度,压缩率(压缩后存储大小),压缩后是否可以支持切片。
4.1:Gzip压缩
优点:压缩率比较高
缺点:不支持切片,压缩/解压缩速度一般
4.2:Bzip2压缩
优点:压缩率高,支持切片
缺点:压缩/解压缩速度慢
4.3:Lzo压缩
优点:压缩/解压缩速度比较快,支持切片
缺点:压缩率一般,想支持切片需要额外创建索引
4.4:snappy压缩
优点:压缩和解压缩速度快
缺点:不支持切片,压缩率一般
4.5:压缩位置选择
压缩可以在MapReduce作用的任意阶段启用。下图是三种阶段选择要求。
5:三个阶段的参数配置
6:案例:Mapper输出端以及Reduce的输出端设置
public class WordCountDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
// 1 获取配置信息以及获取 job 对象
Configuration conf = new Configuration();
// 这两个是Mapper输出端进行的设置,如果仅仅设置了这里,最后结果是没有压缩的
//因为仅仅是Map到Reduce压缩了,但是Reduce输出并没有设置,而且最后的结果是根据reduce设置得出的
conf.setBoolean("mapreduce.map.output.compress", true);
conf.setClass(" mapreduce.map.output.compress.codec", BZip2Codec.class , CompressionCodec.class);
Job job = Job.getInstance(conf);
// 2 关联本 Driver 程序的 jar
job.setJarByClass(WordCountDriver.class);
// 3 关联 Mapper 和 Reducer 的 jar
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
// 4 设置 Mapper 输出的 kv 类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
// 5 设置最终输出 kv 类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// 6 设置输入和输出路径,输出路径不能存在,不然会执行出错
FileInputFormat.setInputPaths(job, new Path("F:\\input\\inputword"));
FileOutputFormat.setOutputPath(job, new Path("F:\\output19"));
/*FileInputFormat.setInputPaths(job, new Path("F:\\input"));
FileOutputFormat.setOutputPath(job,new Path("F:\\output2"));*/
/*// 这里是设置 reduce 端输出压缩开启
FileOutputFormat.setCompressOutput(job, true);
// 设置压缩的方式
FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class);
*/
// 7 提交 job
boolean result = job.waitForCompletion(true);
System.exit(result ? 0 : 1);
}
}