Hive中对中间数据或最终数据都会做压缩处理,以提高吞吐量和性能。
通常压缩比高的占用空间小,但解压缩慢,反之亦然,常用的压缩格式有:GZIP、BZIP2、Snappy
压缩方式 | 压缩后大小 | 压缩速度 | 是否可分隔 |
---|---|---|---|
GZIP | 中 | 中 | 否 |
BZIP2 | 小 | 慢 | 是 |
Snappy | 大 | 快 | 是 |
Snappy因为解压缩速度很快,并且可以进行分隔,是大数据存储中最常用的压缩方式。
今天跑批处理的时候,读取HDFS中的Snappy文件的时候报错了,这边使用的是org.apache.hadoop.hive.serde2.JsonSerDe的解析方式,解析TEXTFILE存储的JSON文件,压缩方式是Snappy,就想查看一下Snappy里面的具体文件内容。
hadoop fs -text /XXX/XXX.snappy
复制代码
使用-text命令可以直接查看文件,或直接使用命令输出到文件中进行查看。
缺点是不方便进行一些复杂的处理,或者输出统计结果。
使用代码解析后,就可以进行读取并处理,也可以输出统计结果,或异常数据可以直接定位。
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();
}