Hadoop基础-SequenceFile的压缩编解码器

                                            作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.Hadoop压缩简介

1>.文件压缩的好处

  第一:较少存储文件占用的磁盘空间,这样就加速数据在磁盘中的传输(比如源文件1G,经过压缩后只有10M,那么文件传输起来就相当的快啦!)

  第二:节省网络带宽,很多时候将数据压缩不仅仅是为了存储,还是为了节省网络带块,在传输数据的时候,先将数据进行压缩处理再发送给接收端,接收端接到数据后会进解压操作,从而拿到真正的数据。

2>.Hadoop压缩算法

  包括Deflate,Gzip,Bzip2,Lz4,Snappy等算法,其中Bzip2是极致压缩比例,而Lz4,Lzo和Snappy则是优化压缩速度,在生产环境下根据算法相关特性进行技术选型。

  注意:Lzo(with index)和Bzip2是可切割的算法,适合在MR中使用。

3>.Hadoop压缩算法的对比

二.Gzip压缩与解压缩案例展示

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.compress; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CompressionInputStream;
import org.apache.hadoop.io.compress.CompressionOutputStream;
import org.apache.hadoop.io.compress.GzipCodec;
import org.apache.hadoop.util.ReflectionUtils; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; public class TestCompressCodec {
private static final File srcFile = new File("D:\\10.Java\\IDE\\yhinzhengjieData\\CompressCodec\\jdk-9.CHM");
private static final File gzipFilePath = new File("D:\\10.Java\\IDE\\yhinzhengjieData\\CompressCodec\\yinzhengjie.gz");
private static final File gunzipFilePath = new File("D:\\10.Java\\IDE\\yhinzhengjieData\\CompressCodec\\yinzhengjie.CHM");
public static void main(String[] args) throws Exception {
GizpCompress();
GunizpCompress();
} //Gzip进行压缩的方法
public static void GizpCompress() throws Exception {
//获取程序开始执行的时间戳
long start = System.currentTimeMillis();
//实例化一个Configuration,它会自动去加载本地的core-site.xml配置文件的fs.defaultFS属性。(该文件放在项目的resources目录即可。)
Configuration conf = new Configuration();
//将hdfs写入的路径定义在本地,需要修改默认我文件系统,这样就可以覆盖到之前在core-site.xml配置文件读取到的数据。
conf.set("fs.defaultFS","file:///");
//通过hadoop提供的反射工具类ReflectionUtils的newInstance方法生成一个GzipCodec方法,第一个参数需要传入一个编解码器类,第二个参数需要传入一个Configuration对象。
GzipCodec gzipCodec = ReflectionUtils.newInstance(GzipCodec.class, conf);
//通过gzipCodec的createOutputStream方法创建出压缩输出流
CompressionOutputStream cos = gzipCodec.createOutputStream(new FileOutputStream(gzipFilePath));
//创建出需要压缩的文件
FileInputStream fis = new FileInputStream(srcFile);
//通过hadoop提供的拷贝类工具进行拷贝数据,第一个参数需要传入一个输入流,第二个参数需要传入一个输出流,第三个参数指定传输的缓冲区大小。
IOUtils.copyBytes(fis,cos,1024);
//释放资源
fis.close();
cos.close();
//获取程序结束执行的时间戳
long end = System.currentTimeMillis();
//输出时间压缩的时间
System.out.printf("源文件大小是:[%d]字节,压缩时间:[%d],压缩后的文件大小是:[%d]字节.\n",srcFile.length(),(end - start),gzipFilePath.length());
} //Gzip进行解压的方法
public static void GunizpCompress() throws Exception {
//获取程序开始执行的时间戳
long start = System.currentTimeMillis();
//实例化一个Configuration,它会自动去加载本地的core-site.xml配置文件的fs.defaultFS属性。(该文件放在项目的resources目录即可。)
Configuration conf = new Configuration();
//将hdfs写入的路径定义在本地,需要修改默认我文件系统,这样就可以覆盖到之前在core-site.xml配置文件读取到的数据。
conf.set("fs.defaultFS", "file:///");
//通过hadoop提供的反射工具类ReflectionUtils的newInstance方法生成一个GzipCodec方法,第一个参数需要传入一个编解码器类,第二个参数需要传入一个Configuration对象。
GzipCodec gzipCodec = ReflectionUtils.newInstance(GzipCodec.class, conf);
//通过gzipCodec的createOutputStream方法创建出解压输入流
CompressionInputStream cis = gzipCodec.createInputStream(new FileInputStream(gzipFilePath));
//创建解压后生成的文件
FileOutputStream fos = new FileOutputStream(gunzipFilePath);
//通过hadoop提供的工具类拷贝数据
IOUtils.copyBytes(cis,fos,1024);
//释放资源
fos.close();
cis.close();
//获取程序结束执行的时间戳
long end = System.currentTimeMillis();
//输出时间压缩的时间
System.out.printf("源文件大小是:[%d]字节,压缩时间:[%d],解压后的文件大小是:[%d]字节.\n",gzipFilePath.length(),(end - start),gunzipFilePath.length());
}
} /*
以上代码输出结果如下:
源文件大小是:[53712527]字节,压缩时间:[2360],压缩后的文件大小是:[53030595]字节.
源文件大小是:[53030595]字节,压缩时间:[336],解压后的文件大小是:[53712527]字节.
*/

  代码执行之前目录文件如下:

  代码执行之后目录文件如下:

三.综合测试Hadoop压缩编解码器(windows环境测试,不包含Snappy压缩

1>.测试代码如下:

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.compress; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.*;
import org.apache.hadoop.util.ReflectionUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; public class TestCompressCodec {
/**
* 设置路径动态传参
* @param args
*/
public static void main(String[] args) {
if(args == null || args.length == 0){
System.out.println("需要输入路径");
System.exit(-1);
}
Class[] classes = {
DefaultCodec.class,
GzipCodec.class,
BZip2Codec.class,
Lz4Codec.class,
LzopCodec.class,
// SnappyCodec.class
};
for(Class clazz : classes){
testCompress(clazz, args[0]);
testDecompress(clazz,args[0]);
}
}
/**
* Gzip压缩
* @throws Exception
*/
public static void testCompress(Class clazz, String path) {
try {
long start = System.currentTimeMillis();
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "file:///");
CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(clazz, conf);
FileInputStream fis = new FileInputStream(path);
//获取扩展名
String ext = codec.getDefaultExtension();
//创建压缩输出流
CompressionOutputStream cos = codec.createOutputStream(new FileOutputStream(path+ext));
IOUtils.copyBytes(fis,cos,1024);
fis.close();
cos.close();
System.out.print("压缩类型:"+ ext+"\t"+ "压缩时间:" + (System.currentTimeMillis() - start)+ "\t");
File f = new File(path+ext);
System.out.print("文件大小:"+ f.length() + "\t");
} catch (Exception e) {
e.printStackTrace();
}
} /**
* Gzip解压
* @throws Exception
*/
public static void testDecompress(Class clazz,String path) {
try {
long start = System.currentTimeMillis();
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "file:///");
CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(clazz, conf);
//扩展名
String ext = codec.getDefaultExtension();
//压缩输入流
CompressionInputStream cis = codec.createInputStream(new FileInputStream(path+ext));
FileOutputStream fos = new FileOutputStream(path+ext+".txt");
IOUtils.copyBytes(cis,fos,1024);
cis.close();
fos.close();
System.out.println("解压时间:" + (System.currentTimeMillis() - start));
} catch (Exception e) {
e.printStackTrace();
}
}
}

2>.Idea进行模拟命令行传参

  点击编辑配置(Edit Configurations)

  输入需要压缩的文件路径

3>.执行代码产物

  执行代码之前目录文件如下:

  执行代码之后目录文件如下:

4>.比较压缩结果

  执行上述代码结果如下:

  根据结果反推理论:(以上实验是我取了一次结果为准,生成环境最好以实际生成环境为准,这个数据仅供参考!)

       压缩时间从小到大:lz4 < lzo < gz < deflate < bz2;

       压缩大小从小到大:defalte < gz < lzo < bz2 < lz4;

       解压时间从小到大:lzo <  lz4 < deflate < gz < bz2; 

  注意,由于我此次测试环境是在windows,上述测试不包含Snappy压缩类型,想要查看Snappy压缩,请参考:https://www.cnblogs.com/yinzhengjie/p/9124038.html

四.压缩格式选型

1>.应该使用哪种压缩格式?(文笔摘自<<Hadoop权威指南第四册>>)

  Hadoop 应用处理的数据集非常大,因此需要借助于压缩。使用哪种压缩格式与待处理的文件的大小,格式和所使用的工具相关。下面有一些建议,大致是按照效率从高到低排列的。

      建议一:使用容器格文件格式,例如顺序文件,Avro数据文件,ORCFiles或者Parquet文件,所有含有这些文件格式同时支持压缩和切分。通常最好与一个快速压缩工具联合使用,例如:LZO,LZ4,或者Snappy。(推荐使用)

    建议二:使用支持切分的压缩格式,例如 bzip2(尽管 bzip2非常慢),或者使用通过索引实现切分的压缩格式,例如:LZO。(推荐使用)

    建议三:在应用中将文件切分成块,并使用任意一种压缩格式为每个数据块建立压缩文件(不论它是否支持切分)。在这种情况下,需要合理选择数据块的大小,以确保压缩后数据块的大小近似于HDFS块的大小。(不推荐)

    建议四:存储未经过压缩的文件。(不推荐)

  对大文件来说,不要使用不支持切分整个文件的压缩格式,因为会失去数据的本地特性,进而造成MapReduce应用效率底下。

2>.LZO通过索引实现切分的压缩格式案例展示

/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.compress; import com.hadoop.compression.lzo.LzoIndexer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path; import java.io.IOException; public class LzoIndex {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
//设置编解码器
conf.set("io.compression.codecs","org.apache.hadoop.io.compress.LzopCodec");
//创建一个LzoIndexer对象,需要传入conf对象
LzoIndexer indexer = new LzoIndexer(conf);
//需要指定协议为本地“file:///”
indexer.index(new Path("file:///D:\\10.Java\\IDE\\yhinzhengjieData\\CompressCodec\\jdk-9.CHM.lzo"));
}
} /*
以上代码执行成功后,会在D:\10.Java\IDE\yhinzhengjieData\CompressCodec\jdk-9.CHM.lzo同级目录下生成文件:D:\10.Java\IDE\yhinzhengjieData\CompressCodec\jdk-9.CHM.lzo.index文件。
*/

Hadoop基础-SequenceFile的压缩编解码器的更多相关文章

  1. Hadoop基础-Idea打包详解之手动添加依赖(SequenceFile的压缩编解码器案例)

    Hadoop基础-Idea打包详解之手动添加依赖(SequenceFile的压缩编解码器案例) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编辑配置文件(pml.xml)(我 ...

  2. hadoop基础-SequenceFile详解

    hadoop基础-SequenceFile详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.SequenceFile简介 1>.什么是SequenceFile 序列文件 ...

  3. [SequenceFile_4] SequenceFile 配置压缩

    0. 说明 SequenceFile 配置压缩编解码器 && 压缩类型的选型 1. SequenceFile 配置压缩编解码器 package hadoop.compression; ...

  4. Hadoop基础-MapReduce的常用文件格式介绍

    Hadoop基础-MapReduce的常用文件格式介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MR文件格式-SequenceFile 1>.生成SequenceF ...

  5. Hadoop基础-MapReduce的工作原理第二弹

    Hadoop基础-MapReduce的工作原理第二弹 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Split(切片)  1>.MapReduce处理的单位(切片) 想必 ...

  6. Hadoop中SequenceFile的使用

    1.对于某些应用而言,须要特殊的数据结构来存储自己的数据. 对于基于MapReduce的数据处理.将每一个二进制数据的大对象融入自己的文件里并不能实现非常高的可扩展性,针对上述情况,Hadoop开发了 ...

  7. hadoop深入研究:(七)——压缩

    转载请标明出处:hadoop深入研究:(七)——压缩 文件压缩主要有两个好处,一是减少了存储文件所占空间,另一个就是为数据传输提速.在hadoop大数据的背景下,这两点尤为重要,那么我现在就先来了解下 ...

  8. Hadoop之SequenceFile

    Hadoop序列化文件SequenceFile能够用于解决大量小文件(所谓小文件:泛指小于black大小的文件)问题,SequenceFile是Hadoop API提供的一种二进制文件支持.这样的二进 ...

  9. Hadoop基础-MapReduce的排序

    Hadoop基础-MapReduce的排序 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MapReduce的排序分类 1>.部分排序 部分排序是对单个分区进行排序,举个 ...

随机推荐

  1. Daily Scrum8 11.12

    昨天的任务已完成. 今日任务: 徐钧鸿:个人作业 张艺:构建带有用户管理的框架,并将后端移植好的代码连结. 黄可嵩:完成搜索移植 徐方宇:研究httpclient如何运作,如何利用它实现服务器和客户端 ...

  2. 20162314 《Program Design & Data Structures》Learning Summary Of The Ninth Week

    20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Ninth Week ...

  3. jsp九大内置对象之session和application

    session和application 用的都是特别多尤其是application,但是想全面学习一下内置对象所以都了解一下. session又被称为是会话生存期是用户进入浏览器到关闭浏览器的期间.s ...

  4. bata6

    目录 组员情况 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:恺琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内最新成果 团队签入记 ...

  5. WebGL学习笔记(二)

    目录 绘制多个顶点 使用缓冲区对象 类型化数组 使用drawArrays()函数绘制图形 图形的移动 图形的旋转 图形的缩放 绘制多个顶点 使用缓冲区对象 创建缓冲区对象 var vertexBuff ...

  6. C#编程之神奇程序找数

    C#编程之神奇程序找数 问题1:这个程序要找的是符合什么条件的数? 问题2:这样的数存在么?符合这一条件的最小的数是什么? 问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间精确到分 ...

  7. 2013长沙网赛E题Travel by Bike

    题目链接:http://acm.zju.edu.cn/changsha/showProblem.do?problemId=26 题意:一个人从一个地方到另一个地方,长度为L,每小时速度为speed,周 ...

  8. 对synchronized的一点理解

    一.synchronized的使用(一).synchronized同步方法1. “非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程安全”问题.2. 如果多个线程共同访问 ...

  9. 前端基础:HTTP 状态码详解

    HTTP 状态码详解 1xx(信息类):表示接收到请求并继续处理 100 客户端应当继续发送请求.这个临时响应是用来通知客户端他的部分请求已经被服务器接收,且仍未被拒绝.客户端应当继续发送请求的剩余部 ...

  10. easyui布局隐藏伸缩按钮

    1. 在html中加入 <script> /** * layout方法扩展 * @param {Object} jq * @param {Object} region */ $.exten ...