存储格式与压缩算法

文件存储格式

  从Hive官网得知,Apache Hive支持Apache Hadoop中使用的几种熟悉的文件格式,如 TextFile(文本格式),RCFile(行列式文件),SequenceFile(二进制序列化文件),AVRO,ORC(优化的行列式文件)和Parquet 格式,而这其中我们目前使用最多的是TextFile,SequenceFile,ORC和Parquet。

下面来详细了解下这2种行列式存储

1、ORC(HDP)

背景描述:

  传统的行式数据库存储方式,按行存储,如果没有存储索引的话,如果需要查询一个字段,就需要把整行的数据都查出来然后做筛选,这么做式比较消耗IO资源的,于是在Hive种最开始也是用了索引的方式来解决这个问题,但是由于索引的高成本,在目前的Hive3.X 中,已经废除了索引,当然也早就引入了列式存储

  列式存储的存储方式,其实和名字一样,它是按照一列一列存储的,这样的话如果查询一个字段的数据,就等于是索引查询,效率高。但是如果需要查全表,它因为需要分别取所有的列最后汇总,反而更占用资源。于是ORC行列式存储出现了。

原理:

  1. 在需要全表扫描时,可以按照行组读取
  2. 如果需要取列数据,在行组的基础上,读取指定的列,而不需要所有行组内所有行的数据和一行内所有字段的数据。

介绍:

  1. 特别注意:ORC格式的表还支持事务ACID,但是支持事务的表必须为分桶表,所以适用于更新大批量的数据,不建议用事务频繁的更新小批量的数据
  2. 压缩方式:可选的类型有NONE、ZLIB、和SNAPPY,默认值是ZLIB(Snappy不支持切片)

2、Parquet(CDH)

背景描述:

  Parquet是另一种高性能的行列式存储结构。既然ORC都那么高效了,那为什么还要再来一个Parquet,那是因为Parquet是为了使Hadoop生态系统中的任何项目都可以使用压缩的,高效的列式数据表示形式,它支持压缩格式:Snappy、GZIP、Lzo

  

Parquet 是语言无关的,而且不与任何一种数据处理框架绑定在一起,适配多种语言和组件,能够与 Parquet 配合的组件有:

查询引擎: Hive, Impala, Pig, Presto, Drill, Tajo, HAWQ, IBM Big SQL

计算框架: MapReduce, Spark, Cascading, Crunch, Scalding, Kite

数据模型: Avro, Thrift, Protocol Buffers, POJOs

 介绍:

  1、默认值为 UNCOMPRESSED,表示页的压缩方式。可以使用的压缩方式有 UNCOMPRESSED、 SNAPPY、GZP和LZO。 

总结

  1. Parquet文件是以二进制方式存储的,所以不可以直接读取,和ORC一样,文件的元数据和数据一起存储,所以Parquet格式文件是自解析的

压缩方式

存储和压缩结合该如何选择?

根据ORC和parquet的要求,一般就有了

1、ORC格式存储,Snappy压缩

2、Parquet格式存储,Lzo压缩

3、Parquet格式存储,Snappy压缩

因为Hive 的SQL会转化为MR任务,如果该文件是用ORC存储,Snappy压缩的,因为Snappy不支持文件分割操作,所以压缩文件只会被一个任务所读取,如果该压缩文件很大,那么处理该文件的Map需要花费的时间会远多于读取普通文件的Map时间,这就是常说的Map读取文件的数据倾斜。

那么为了避免这种情况的发生,就需要在数据压缩的时候采用bzip2和Zip等支持文件分割的压缩算法。但恰恰ORC不支持刚说到的这些压缩方式,所以这也就成为了大家在可能遇到大文件的情况下不选择ORC的原因,避免数据倾斜。

在Hve on Spark的方式中,也是一样的,Spark作为分布式架构,通常会尝试从多个不同机器上一起读入数据。要实现这种情况,每个工作节点都必须能够找到一条新记录的开端,也就需要该文件可以进行分割,但是有些不可以分割的压缩格式的文件,必须要单个节点来读入所有数据,这就很容易产生性能瓶颈。(下一篇文章详细写Spark读取文件的源码分析)

所以在实际生产中,使用Parquet存储,lzo压缩的方式更为常见,这种情况下可以避免由于读取不可分割大文件引发的数据倾斜。
但是,如果数据量并不大(预测不会有超大文件,若干G以上)的情况下,使用ORC存储,snappy压缩的效率还是非常高的。

  

原文地址:https://www.cnblogs.com/wang--lei/p/14803871.html