【Hadoop篇08】Hadoop数据压缩

简洁而不简单

Hadoop数据压缩

数据压缩优点和缺点

​ 压缩技术能够有效减少底层存储系统(HDFS)读写字节数。压缩提高了网络带宽和磁盘空间的效率。在 Hadoop下,尤其是数据规模很大和工作负载密集的情况下,使用数据压缩显得非常重要。在这种情况下,IO操作和网络数据传输要花大量的时间。还有, Shuffle与 Merge过程同样也面临着巨大的IO压力鳘于磁盘IO和网络带宽是 Hadoop的宝贵资源,数据压缩对于节省资源、最小化磁盘IO和网络传输非常有帮助

​ 不过,尽管压缩与解压操作的CPU开销不髙,其性能的提升和资源的节省并非没有代价。如果磁盘IO和网络带宽影响了 MapReduce作业性能,在任意 MapReduce阶段启用压缩都可以改善端到端处理时间并減少IO和网络流量。

压缩策略和原则

​ 压缩是提高 Hadoop运行效率的一种优化策略通过对 Mapper、 Reducer运行过程的数据进行压缩,以减少磁盘IO,提高MR程序运行速度。 ​ 注意:釆用压缩技术减少了磁盘IO,但同时增加了CPU运算负担。所以,压缩特性运用得当能提高性能,但运用不当也可能降低性能压缩基本原则:

(1)运算密集型的job,少用压缩 (2)IO密集型的job,多用压缩!!

MR支持的压缩编码

压缩格式 hadoop自带? 算法 文件扩展名 是否可切分 换成压缩格式后,原来的程序是否需要修改
DEFLATE 是,直接使用 DEFLATE .deflate 和文本处理一样,不需要修改
Gzip 是,直接使用 DEFLATE .gz 和文本处理一样,不需要修改
bzip2 是,直接使用 bzip2 .bz2 和文本处理一样,不需要修改
LZO 否,需要安装 LZO .lzo 需要建索引,还需要指定输入格式
Snappy 否,需要安装 Snappy .snappy 和文本处理一样,不需要修改

为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器,如下表所示。

压缩格式 对应的编码/解码器
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

压缩方式选择

Gzip压缩

image-20200619174950679

Bzip2压缩

image-20200619175002143

Lzo压缩

image-20200619175012846

Snappy压缩

image-20200619175204704

压缩位置选择

image-20200619175257463

压缩参数配置

参数 默认值 阶段 建议
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
mapreduce.output.fileoutputformat.compress.type(在mapred-site.xml中配置) RECORD reducer输出 SequenceFile输出使用的压缩类型:NONE和BLOCK

压缩案例

image-20200619175722079

public class TestCompress {

    public static void main(String[] args) throws Exception {
        compress("e:/hello.txt","org.apache.hadoop.io.compress.BZip2Codec");
//        decompress("e:/hello.txt.bz2");
    }

    // 1、压缩
    private static void compress(String filename, String method) throws Exception {

        // (1)获取输入流
        FileInputStream fis = new FileInputStream(new File(filename));

        Class codecClass = Class.forName(method);

        CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, new Configuration());

        // (2)获取输出流
        FileOutputStream fos = new FileOutputStream(new File(filename +codec.getDefaultExtension()));
        CompressionOutputStream cos = codec.createOutputStream(fos);

        // (3)流的对拷
        IOUtils.copyBytes(fis, cos, 1024*1024*5, false);

        // (4)关闭资源
        fis.close();
        cos.close();
        fos.close();
    }

    // 2、解压缩
    private static void decompress(String filename) throws FileNotFoundException, IOException {

        // (0)校验是否能解压缩
        CompressionCodecFactory factory = new CompressionCodecFactory(new Configuration());

        CompressionCodec codec = factory.getCodec(new Path(filename));

        if (codec == null) {
            System.out.println("cannot find codec for file " + filename);
            return;
        }

        // (1)获取输入流
        CompressionInputStream cis = codec.createInputStream(new FileInputStream(new File(filename)));

        // (2)获取输出流
        FileOutputStream fos = new FileOutputStream(new File(filename + ".decoded"));

        // (3)流的对拷
        IOUtils.copyBytes(cis, fos, 1024*1024*5, false);

        // (4)关闭资源
        cis.close();
        fos.close();
    }
}

Map输出端采用压缩

public class WordCountDriver {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {

        Configuration configuration = new Configuration();

        // 开启map端输出压缩
    configuration.setBoolean("mapreduce.map.output.compress", true);
        // 设置map端输出压缩方式
    configuration.setClass("mapreduce.map.output.compress.codec", BZip2Codec.class, CompressionCodec.class);

        Job job = Job.getInstance(configuration);

        job.setJarByClass(WordCountDriver.class);

        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        boolean result = job.waitForCompletion(true);

        System.exit(result ? 1 : 0);
    }
}

Mapper和Reducer代码不变

Reduce输出端采用压缩

public class WordCountDriver {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {

        Configuration configuration = new Configuration();

        Job job = Job.getInstance(configuration);

        job.setJarByClass(WordCountDriver.class);

        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // 设置reduce端输出压缩开启
        FileOutputFormat.setCompressOutput(job, true);

        // 设置压缩的方式
        FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class); 
//        FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class); 
//        FileOutputFormat.setOutputCompressorClass(job, DefaultCodec.class); 

        boolean result = job.waitForCompletion(true);

        System.exit(result?1:0);
    }
}

相关资料

1

本文配套GitHub:https://github.com/zhutiansama/FocusBigData

热门文章

暂无图片
编程学习 ·

关于Error:java: Compilation failed: internal java compiler error的解决方案

文章目录事故现场分析解决方案最终结果 事故现场分析 使用Idea导入新项目或升级idea或新建项目时会出现以上异常信息,导致这个错误的原因主要是因为jdk版本问题,此处有两个原因,一个是编译版本不匹配,一个是当前项目jdk版本不支持 常规分析:看一下compile,原来真的是错在…
暂无图片
编程学习 ·

PCL点云焊点提取

滚回来更新一篇文章,和各位交流一下 待处理点云: 数量级:百万 类型:零部件 描述:弯曲表面上有一些凸起在上面,需要提取凸起和平面接触的一圈点云,作为焊接的加工点参考:https://zhuanlan.zhihu.com/p/32111069其实这篇文章也算是全面了,思路和他的差不多,只是算法不太一…
暂无图片
编程学习 ·

Docker 2375 端口入侵服务器,部分解决方案

docker remote API的同学对2375端口入侵服务器2375->上传镜像-》获取控制权-》ssh pub key 注入-》登入服务器核心总结:1.禁用2375 2.创建linux新用户 3.禁止root远程登录4.卸载重新安装docker,并删除之前的文件5.禁止外网一、创建新用户以及授权创建用户adduser limp用户…
暂无图片
编程学习 ·

jkd从1.8升级后报sun.misc相关错误

Idea解决找不到sun.misc.BASE64Encoder及sun.misc.BASE64Decoder找不到包 报错原因: JDK从1.8升级到9.0.1后sun.misc.BASE64Decoder和sun.misc.BASE64Encoder不可用 原因分析: ​ 参看官网,发现JDK中的lib\tools.jar和JRE中的lib\rt.jar已从Java SE 9中删除。这些JAR中可用的…
暂无图片
编程学习 ·

Android编程权威指南总结(六)

第十七章 双版面主从用户界面本章是为了适应平板设备。双版面主从用户界面,也就是平板上的列表和详情界面同时展示的情况。一、增加布局灵活性双版面布局里面,一个 Activity 托管两个 Fragment。1、方法上使用 @LayoutRes 注解,这告诉Android Studio,任何时候该注解的…
暂无图片
编程学习 ·

iOS开发之多线程(2)—— Thread

目录版本简介方法属性示例 版本 Xcode 11.5 Swift 5.2.2 简介 一个Thread即为一个线程. 方法属性 OC中的属性方法(Swift方法名类似): #pragma mark - 属性 // 可以使用返回的字典来保存线程的特定数据. (这只是一个普通的字典, 用来保存所有开发者感兴趣的数据.) @property (r…
暂无图片
编程学习 ·

网上书城项目分析及前端页面

网上书城项目分析及前端页面项目分析背景/价值需求/功能需求功能划分前端页面实现登录and注册效果代码主页面效果代码搜索页面效果代码购物车页面效果代码思维导图总结 项目分析 背景/价值 背景 个人书店的业务管理使用 价值 方便个人书店的推广 角色 老板 消费者 思维导图需求…
暂无图片
编程学习 ·

机器视觉打光技巧

光源专家的8个打光技巧 机器视觉系统中的照明系统是极其重要的一部分,它的好坏直接影响着后面的图像处理。在听了一位日本光源专家的讲座之前,我其实对照明并不太了解,不就是将图像照亮以至于相机能够拍到图像吗?但事实并非如此,照明远非增强图像亮度这样简单,好的照明系…
暂无图片
编程学习 ·

windows10系统-2-安装Nodejs及SocketIO

(1)双击node-v12.14.1-x64.msi CMD>npm --version查看npm的版本 CMD>npm -v (2)使用淘宝镜像的命令 CMD>npm install -g cnpm --registry=https://registry.npm.taobao.org CMD>npm list -g查看所有全局安装的模块 【全局安装所在路径C:\Users\user\AppData\Roamin…
暂无图片
编程学习 ·

SpringBoot+Mybatis实现简单的增删改查

SpringBoot+Mybatis实现简单的增删改查 首先是在Springboot项目中整合Mybatis 先导入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.2</version></dependen…
暂无图片
编程学习 ·

微服务的全局异常处理器

如果是dubbo服务 直接在对外暴露服务的哪个模块添加该类即可 如果是springboot微服务 我们可以把他配置到网关里 并且在启动类配置如下目的是为了让服务知道该配置 否则不生效 ApiReturnObject是一个统一返回值类型 可以根据自己喜好进行定义 这里就不贴代码了package com.s…
暂无图片
编程学习 ·

vue.js 介绍 (一)

Vue.js 是一个 JavaScript 的渐进式框架(可以由浅入深,由简单到复杂的使用。 Vue.js优点:体积小 33K 更高的运行效率 基于虚拟dom, 基于 js进行各种计算,把最终dom计算出来 双向数据绑定 生态丰富,学习成本低 大量基于 vue.js 的 ui框架,常用组件。如Element, IView。Vu…
暂无图片
编程学习 ·

WWDC20 苹果发布会

iphone上的ios14亮点不多 主要是桌面小组件 分类app显示 画中画 还有小程序 来电小窗提示和siri ui更新与更加智能 还有汽车智能钥匙 不用带钥匙只需要nfc就可以打开车门与开车 首款支持的汽车是 宝马5系ipad上的ipadOS14 拥有ios14的的全部更新 更加方便的ui以及全局搜索 也…
暂无图片
编程学习 ·

登录小Demo(错题记录)

Demo描述:实现C3P0数据库池连接数据库。部署Tomcat服务器,使用servlet完成简单登录测试。错误描述:测试时,登录账号名和密码与数据库表中信息一致。但是提示登录失败,控制台无错误提示。产生原因:细节问题。忽略了setCharacterEncoding设置字符的编码方式.注意点:1.setC…
暂无图片
编程学习 ·

疫情期间,注重鼻腔呼吸道清洁卫生,很重要

疫情期间清洁鼻腔很重要鼻子是人类呼吸道的门户,作为一个与外界直接相通的腔道,很像家里空调的风口,容易存留脏物。从生理结构上来看,鼻腔里有鼻毛和大量的黏膜褶皱,灰尘、微生物、病毒都可能积攒其中。所以,在“勤洗手、戴口罩”的非常时期,别忘了鼻腔的清洁工作。另据…
暂无图片
编程学习 ·

setuptools Command Reference

https://setuptools.readthedocs.io/en/latest/setuptools.html#command-reference alias - Define shortcuts for commonly used commands bdist_egg - Create a Python Egg for the project develop - Deploy the project source in “Development Mode” egg_info - Create …
暂无图片
编程学习 ·

JavaScript从入门到精通复习资料大全(基础知识篇)

JavaScript从入门到精通复习一、JavaScript中的常量和变量1、常量:就是程序运行过程中,保持不变的数据。2、变量:是程序中一个已经命名的存储单元。3、 变量的赋值二:JavaScript中的运算符1、算术运算符2、比较运算符3、赋值运算符4、字符串运算符5、 逻辑运算符6、条件运…
暂无图片
编程学习 ·

C语言指针笔记

C语言指针 一.地址与指针变量 程序在执行过程中需要有内存来存储需要用到的数据和程序代码,它们都占据一些内存单元,地址是这些内存单元的编号,同时包括它所指向的数据的类型信息。因此,可以把地址形象化地称为"指针"。 但不要把地址和指针混为一个概念,地址是数…
暂无图片
编程学习 ·

mxnet安装环境配置

一、安装Miniconda 官方网址:https://conda.io/en/latest/miniconda.html 本人选择python3.7版本Windows64位 安装完成后打开Anaconda Prompt创建虚拟环境conda create –n env python=3.7 这里的env为自定义环境名激活环境 conda activate env 退出环境: conda deactivate查…