hive文件的存储格式

列式存储和行式存储

hive文件的存储格式

上图左边为逻辑表,右边第一个为行式存储,第二个为列式存储。

行存储的特点: 查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。行存适用于对几行或者多行的操作(查询或者更新)。
列存储的特点:因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。列存适用于对列或者多列的操作(分析计算 sum count等)。

压缩

压缩这种优化的方法对于Column-Store比对Row-Store更有效,原因很简单,我个人对压缩的理解是:

对数据进行更高效的编码, 使得我们可以以更少的空间表达相同的意思。
而能够进行更高效编码的前提是这个数据肯定要有某种规律,比如有很多数据一样,或者数据的类型一样。而Column-Store正好符合这个特点,因为Column-Store是把同一个Column – 也就是相同类型的数据保存在一起,当然比Row-Store把一条记录里面不同类型的字段值保存在一起更有规律,更有规律意味着可以有更高的压缩比。

但是为什么压缩就能带来查询的高效呢?压缩首先带来的硬盘上存储空间的降低,但是硬盘又不值钱。它的真正意义在于:数据占用的硬盘空间越小,查询引擎花在IO上的时间就越少(不管是从硬盘里面把数据读入内存,还是从内存里面把数据读入CPU)。同时要记住的是数据压缩之后,要进行处理很多时候要需要解压缩(不管是Column-Store还是Row-Store), 因此压缩比不是我们追求的唯一,因为后面解压也需要花时间,因此一般会在压缩比和解压速度之间做一个权衡。

高压缩比的典型如Lempel-Ziv, Huffman, 解压快的典型如: Snappy(现在我们用的正是orc压缩的 Snappy), Lz2 。前面提到解压缩,有的场景下解压缩这个步骤可以彻底避免掉,比如对于采用Run-Length编码方式进行压缩的数据,我们可以直接在数据压缩的格式上进行一些计算:

Run-Length的大概意思是这样的, 对于一个数字序列: 1 1 1 1 2 2 2, 它可以表达成 1x4, 2x3
这样不管进行 count (4 + 3), sum (1 x 4 + 2 x 3) 等等都可以不对数据进行解压直接计算,而且因为扫描的数据比未压缩的要少,从而可以进一步的提升性能。文中还提到对于Column-Store应用压缩这种优化最好的场景是当数据是经过排序的,道理很简单,因为如果没有经过排序,那么数据就没那么“有规律”,也就达不到最好的压缩比。

Hive中常用的存储格式

存储格式 描述
STORED AS RCFILE 现在水平上划分为很多个Row Group,每个Row Group默认大小4MB,Row Group内部再按列存储信息。由facebook开源,比标准行式存储节约10%的空间。
STORED AS TEXTFILE 所有类型的数据都存储为String类型,不便于数据的解析,但它却比较通用。手动往hive load数据时,数据文件可以用textfile
STORED AS SEQUENCEFILE 储存格式比TEXTFILE格式多了头部、标识、信息长度等信息,这些信息使得其具备随机读写的能力。支持压缩,但压缩的是value
STORED AS ORC orc 列式存储,支持ACID 事务,支持Cost-based Optimizer (CBO)。优化过后的RCFile,现在水平上划分为多个Stripes,再在Stripe中按列存储。每个Stripe由一个Index Data、一个Row Data、一个Stripe Footer组成。每个Stripes的大小为250MB,每个Index Data记录的是整型数据最大值最小值、字符串数据前后缀信息,每个列的位置等等诸如此类的信息。这就使得查询十分得高效,默认每一万行数据建立一个Index Data。ORC存储大小为TEXTFILE的40%左右,使用压缩则可以进一步将这个数字降到10%~20%。
STORED AS JSONFILE 在Hive 4.0.0及更高版本中以Json文件格式存储。
STORED AS AVRO 在Hive 0.14.0和更高版本中以Avro格式存储
STORED AS PARQUET 在Hive 0.13.0及更高版本中以Parquet 列存储格式存储为Parquet格式;
STORED BY 以非本地表格式存储。创建或链接到非本地表,例如由HBase或Druid或Accumulo 支持的表

上表来自hive官网https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-StorageFormats

注:Hive 自0.14.0开始,加入了一项”Cost based Optimizer”来对HQL执行计划进行优化,这个功能通过”hive.cbo.enable”来开启。在Hive 1.1.0之后,这个feature是默认开启的,它可以自动优化HQL中多个JOIN的顺序,并选择合适的JOIN算法。(慎用 参考:https://blog.****.net/strangerzz/article/details/78992482)

小记:hive不同的存储方式区别很大。生产环境采用的是textfile(无压缩,行存) 和orc存储(snappy的压缩,列存)