Snappy你拖了马甲我照样认识你 原创
春节不停更,此文正在参加「星光计划-春节更帖活动」
大家好,我是怀瑾握瑜,一只大数据萌新,家有两只吞金兽,嘉与嘉,上能code下能teach的全能奶爸
如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~
前言
Hive中对中间数据或最终数据都会做压缩处理,以提高吞吐量和性能。
通常压缩比高的占用空间小,但解压缩慢,反之亦然,常用的压缩格式有:GZIP、BZIP2、Snappy
压缩方式 | 压缩后大小 | 压缩速度 | 是否可分隔 |
---|---|---|---|
GZIP | 中 | 中 | 否 |
BZIP2 | 小 | 慢 | 是 |
Snappy | 大 | 快 | 是 |
Snappy因为解压缩速度很快,并且可以进行分隔,是大数据存储中最常用的压缩方式。
起因
今天跑批处理的时候,读取HDFS中的Snappy文件的时候报错了,这边使用的是org.apache.hadoop.hive.serde2.JsonSerDe的解析方式,解析TEXTFILE存储的JSON文件,压缩方式是Snappy,就想查看一下Snappy里面的具体文件内容。
解决问题
1.使用命令行查看
hadoop fs -text /XXX/XXX.snappy
使用-text命令可以直接查看文件,或直接使用命令输出到文件中进行查看。
缺点是不方便进行一些复杂的处理,或者输出统计结果。
2.使用代码解析
使用代码解析后,就可以进行读取并处理,也可以输出统计结果,或异常数据可以直接定位。
CompressionCodec有两个方法可以用于压缩或解压缩数据。要想对正在被写入一个输出流的数据进行压缩,我们可以使用createOutputStream(OutputStreamout)方法创建一个CompressionOutputStream,将其以压缩格式写入底层的流。相反,要想对从输入流读取而来的数据进行解压缩,则调用createInputStream(InputStreamin)函数,从而获得一个CompressionInputStream,从而从底层的流读取未压缩的数据。
压缩方式 | 压缩包 |
---|---|
GZIP | org.apache.hadoop.io.compress.GzipCodec |
BZIP2 | org.apache.hadoop.io.compress.BZip2Codec |
Snappy | org.apache.hadoop.io.compress.SnappyCodec |
DEFLATE | org.apache.hadoop.io.compress.DefaultCodec |
public static void main(String[] args) throws IOException {
decompres("d:\\a1-k01-1642561371606.snappy");
}
public static void compress(String filername, String method) throws ClassNotFoundException, IOException {
// 1 创建压缩文件路径的输入流
File fileIn = new File(filername);
InputStream in = new FileInputStream(fileIn);
// 2 获取压缩的方式的类
Class codecClass = Class.forName(method);
Configuration conf = new Configuration();
// 3 通过名称找到对应的编码/解码器
CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);
// 4 该压缩方法对应的文件扩展名
File fileOut = new File(filername + codec.getDefaultExtension());
OutputStream out = new FileOutputStream(fileOut);
CompressionOutputStream cout = codec.createOutputStream(out);
// 5 流对接
IOUtils.copyBytes(in, cout, 1024 * 1024 * 5, false); // 缓冲区设为5MB
// 6 关闭资源
in.close();
cout.close();
out.close();
}
public static void decompres(String filename) throws FileNotFoundException, IOException {
Configuration conf = new Configuration();
CompressionCodecFactory factory = new CompressionCodecFactory(conf);
// 1 获取文件的压缩方法
CompressionCodec codec = factory.getCodec(new Path(filename));
// 2 判断该压缩方法是否存在
if (null == codec) {
System.out.println("Cannot find codec for file " + filename);
return;
}
// 3 创建压缩文件的输入流
InputStream cin = codec.createInputStream(new FileInputStream(filename));
// 4 创建解压缩文件的输出流
File fout = new File(filename + ".decoded");
OutputStream out = new FileOutputStream(fout);
// 5 流对接
IOUtils.copyBytes(cin, out, 1024 * 1024 * 5, false);
// 6 关闭资源
cin.close();
out.close();
}
结束语
如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~
可关注公众号【怀瑾握瑜的嘉与嘉】,获取资源下载方式