打怪升级之小白的大数据之旅(五十七)<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

压缩格式对应的编码/解码器
DEFLATEorg.apache.hadoop.io.compress.DefaultCodec
gziporg.apache.hadoop.io.compress.GzipCodec
bzip2org.apache.hadoop.io.compress.BZip2Codec
LZOcom.hadoop.compression.lzo.LzopCodec
Snappyorg.apache.hadoop.io.compress.SnappyCodec

压缩性能比较

压缩算法原始文件大小压缩文件大小压缩速度解压速度
gzip8.3GB1.8GB17.5MB/s58MB/s
bzip28.3GB1.1GB2.4MB/s9.5MB/s
LZO8.3GB2.9GB49.3MB/s74.6MB/s
snappy8.3GB4GB250MB/s500MB/s

snappy的压缩速度是最快的,但是它的压缩效果是最低的,基本上只能将文件压缩至源文件的一半大小左右,想要了解snappy的小伙伴可以参考github的说明:http://google.github.io/snappy

压缩参数配置

参数默认值阶段建议
io.compression.codecs (在core-site.xml中配置org.apache.hadoop.io.compress.DefaultCodecorg.apache.hadoop.io.compress.GzipCodecorg.apache.hadoop.io.compress.BZip2Codec输入压缩Hadoop使用文件扩展名判断是否支持某种编解码器
mapreduce.map.output.compress(在mapred-site.xml中配置)falsemapper输出这个参数设为true启用压缩
mapreduce.map.output.compress.codec(在mapred-site.xml中配置)org.apache.hadoop.io.compress.DefaultCodecmapper输出企业多使用LZO或Snappy编解码器在此阶段压缩数据
mapreduce.output.fileoutputformat.compress(在mapred-site.xml中配置)falsereducer输出这个参数设为true启用压缩
mapreduce.output.fileoutputformat.compress.codec(在mapred-site.xml中配置)org.apache.hadoop.io.compress.DefaultCodecreducer输出使用标准工具或者编解码器,如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>

打怪升级之小白的大数据之旅(五十八)<HadoopHA>

打怪升级之小白的大数据之旅(五十四)<Zookeeper概述与部署>

打怪升级之小白的大数据之旅(五十)<MapReduce框架原理二:shuffle>

打怪升级之小白的大数据之旅(五十六)<Zookeeper内部原理>

打怪升级之小白的大数据之旅(五十二)<MapReduce框架总结与扩展知识点>