打怪升级之小白的大数据之旅(五十七)<Hadoop压缩>
Posted GaryLea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打怪升级之小白的大数据之旅(五十七)<Hadoop压缩>相关的知识,希望对你有一定的参考价值。
打怪升级之小白的大数据之旅(五十七)
Hadoop压缩
上次回顾
介绍完zookeeper之后,接下来就是Hadoop的扩展知识点,压缩和HA了,因为HA是建立在zookeeper基础上的,所以我现在才带来这个知识点
Hadoop压缩
压缩概述
- 首先我们要知道,压缩是一种对数据的优化方法
- 使用压缩可以有效减少HDFS存储数据的读写字节数,提高网络带宽和磁盘空间的使用效率
- 因为运行MR操作时,Shuffle和Merge要花费大量的时间,所以使用压缩可以提高我们MR程序的工作效率
压缩的优缺点
- 虽然通过对MR过程中的数据进行压缩可以减少磁盘IO来提高MR程序运行速度,但压缩同时增加了CPU的运算负担
- 因为压缩后的数据需要解压缩才可以使用,所以压缩特效运用得当可以提高性能,运用不当也可能降低性能
使用压缩的场景
了解了压缩的优缺点,我们自然就可以猜到压缩的应用场景了吧?
- 运算密集型的任务(job),我们尽量少用压缩
- IO密集型的任务(job),我们要多用压缩
MR的压缩编码
- 压缩也分为很多种格式,因为它们的底层算法不同
- 通过不同的压缩技术,我们可以针对不同的场景来使用压缩
- 下面,让我们来了解一下MR支持的几种压缩技术
MR支持的压缩编码
压缩格式 | hadoop自带? | 算法 | 文件扩展名 | 是否可切分 | 换成压缩格式后,原来的程序是否需要修改 |
---|---|---|---|---|---|
DEFLATE | 是,直接使用 | DEFLATE | .deflate | 否 | 和文本处理一样,不需要修改 |
Gzip | 是,直接使用 | DEFLATE | .gz | 否 | 和文本处理一样,不需要修改 |
bzip2 | 是,直接使用 | bzip2 | .bz2 | 是 | 和文本处理一样,不需要修改 |
LZO | 否,需要安装 | LZO | .lzo | 是 | 需要建索引,还需要指定输入格式 |
Snappy | 否,需要安装 | Snappy | .snappy | 否 | 和文本处理一样,不需要修改 |
Hadoop的编码/解码API
压缩格式 | 对应的编码/解码器 |
---|---|
DEFLATE | 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 |
压缩性能比较
压缩算法 | 原始文件大小 | 压缩文件大小 | 压缩速度 | 解压速度 |
---|---|---|---|---|
gzip | 8.3GB | 1.8GB | 17.5MB/s | 58MB/s |
bzip2 | 8.3GB | 1.1GB | 2.4MB/s | 9.5MB/s |
LZO | 8.3GB | 2.9GB | 49.3MB/s | 74.6MB/s |
snappy | 8.3GB | 4GB | 250MB/s | 500MB/s |
snappy的压缩速度是最快的,但是它的压缩效果是最低的,基本上只能将文件压缩至源文件的一半大小左右,想要了解snappy的小伙伴可以参考github的说明:http://google.github.io/snappy
压缩参数配置
参数 | 默认值 | 阶段 | 建议 |
---|---|---|---|
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使用文件扩展名判断是否支持某种编解码器 |
mapreduce.map.output.compress(在mapred-site.xml中配置) | false | mapper输出 | 这个参数设为true启用压缩 |
mapreduce.map.output.compress.codec(在mapred-site.xml中配置) | org.apache.hadoop.io.compress.DefaultCodec | mapper输出 | 企业多使用LZO或Snappy编解码器在此阶段压缩数据 |
mapreduce.output.fileoutputformat.compress(在mapred-site.xml中配置) | false | reducer输出 | 这个参数设为true启用压缩 |
mapreduce.output.fileoutputformat.compress.codec(在mapred-site.xml中配置) | org.apache.hadoop.io.compress.DefaultCodec | reducer输出 | 使用标准工具或者编解码器,如gzip和bzip2 |
表格是为了让大家方便查看,下面来总结一下压缩应用场景
- Gzip
- Hadoop本身支持,使用方便,因为在程序中处理Gzip格式的文件就和直接处理文本一样,并且大部分的linux系统都有Gzip命令
- 因为Gzip不支持切片,所以当单个文件压缩的大小约等于一个块以内(130M左右),我们可以采用Gzip
- Bzip2
- Bzip2同样是Hadoop自带的一种压缩格式,它的特点是支持对单个很大的文本文件压缩时又想对其进行切片,此时我们就选择使用Bzip
- 但是Bzip2的压缩、解压缩的速度比较慢
- Lzo
- 压缩、解压缩速度块,支持切片,是我们最常使用的压缩格式之一,我们可以在Linux中安装lzop命令来使用它
- Lzo在使用的时候需要对Lzo格式文件做一些特殊处理,比如为了支持切片,我们需要建立索引,并且指定InputFormat为Lzo格式
- Lzo的特点是压缩后数据量大小还大于200M的时候使用
- Lzo最大的优势就是单个文件越大,它的压缩效率优势就越明显
- Snappy
- 它的特点就一个字,快,高速的压缩、解压缩效率,让其他压缩望尘莫及
- 但是它不支持切片并且压缩后的大小是源文件的一半
- 正因为它很快,所以我们通常在MR的Map阶段数据比较大的时候作为Map到Reduce的中间格式,或者作为一个MR作业输出到另一个MR作业输入的时候使用
数据流的压缩和解压缩
- 了解了压缩和解压缩以及MR支持的格式之后,下面我们通过代码来演示具体压缩是怎么创建使用的
- 在Hadoop中,我们可以使用内置的CompressionCodec对象来创建压缩流完成对文件的压缩、解压缩
package com.compress; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.io.compress.*; import org.apache.hadoop.util.ReflectionUtils; import org.junit.Test; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class CompressDemo { /** * 压缩 */ @Test public void test() throws Exception { //1.输入流--普通文件流 FileInputStream fis = new FileInputStream("D:\\\\io\\\\compress\\\\aaa.txt"); //2.输出流--压缩流 //2.1创建对应的编解码器的对象 CompressionCodec gzipCodec = ReflectionUtils.newInstance(GzipCodec.class, new Configuration()); //2.2创建流 //gzipCodec.getDefaultExtension() : 获取压缩类型的扩展名 CompressionOutputStream cos = gzipCodec.createOutputStream( new FileOutputStream("D:\\\\io\\\\decompress\\\\aaa.txt" + gzipCodec.getDefaultExtension())); //3.文件对拷 IOUtils.copyBytes(fis,cos,1024,true); } /** * 解压缩 */ @Test public void test2() throws Exception { //输入流---压缩流 CompressionCodec gzipCodec = ReflectionUtils.newInstance(GzipCodec.class, new Configuration()); CompressionInputStream cis = gzipCodec.createInputStream( new FileInputStream("D:\\\\io\\\\decompress\\\\aaa.txt.gz")); //输出流---普通的文件流 FileOutputStream fos = new FileOutputStream("D:\\\\io\\\\compress\\\\aaa.txt"); //3.文件对拷 IOUtils.copyBytes(cis,fos,1024,true); } /** * 解压缩 */ @Test public void test3() throws Exception { //创建压缩的工厂类 CompressionCodecFactory factory = new CompressionCodecFactory(new Configuration()); //输入流---压缩流 //根据文件的扩展名创建对应的编解码器类的对象(智能) CompressionCodec gzipCodec = factory.getCodec(new Path("D:\\\\io\\\\decompress\\\\aaa.txt.gz")); if (gzipCodec != null){//没有对应的编解码器的对象 CompressionInputStream cis = gzipCodec.createInputStream( new FileInputStream("D:\\\\io\\\\decompress\\\\aaa.txt.gz")); //输出流---普通的文件流 FileOutputStream fos = new FileOutputStream("D:\\\\io\\\\compress\\\\aaa.txt"); //3.文件对拷 IOUtils.copyBytes(cis,fos,1024,true); } } }
总结
本章对压缩的知识点进行分享,了解并使用压缩是在我们日常工作中必不可少的知识之一,合理的使用压缩可以大大提高我们程序的执行效率,好了,本章内容就是这些,下一章为大家带来Hadoop的HA
以上是关于打怪升级之小白的大数据之旅(五十七)<Hadoop压缩>的主要内容,如果未能解决你的问题,请参考以下文章
打怪升级之小白的大数据之旅(五十三)<Hadoop最后一个模块--Yarn>
打怪升级之小白的大数据之旅(五十四)<Zookeeper概述与部署>
打怪升级之小白的大数据之旅(五十)<MapReduce框架原理二:shuffle>