ORC文件存储原理以及Spark读写ORC问题解决方法

1、    概述

  Spark作为一个常用的数据处理引擎,经常被用做对Hive中的离线数据进行处理并回写到Hive的场景。Hive表格数据存储类型有text,orc和parquet三种类型。其中orc类型以其压缩比例高,文件可切分以及列式存储等优点被广泛使用。但是如果Spark的中的orc写入版本与Hive中使用的版本不一致;会有Hive读取数据失败的问题。

2、Hive存储数据类型ORC介绍

2.1 ORC文件存储原理

图2-1 ORC的文件存储格式示意图

   Orc的存储文件方式如上图2-1所示,存储文件最初默认大小是256M,一个文件在逻辑结果上被多个Stripe,新版本的Orc写入数据时,默认每个Stripe数据大小为64M(Hive0.1版本默认值是256M),每一个stripe包含多条记录,这些记录按照列进行独立存储。每个Stripe又分为Index Data、Row Data和Stripe Footer三部分。其中:

l  Index Data这里面存储的是索引数据,即数据在group的位置信息。

l  Row Data里面存储的是具体的数据,包括metadata stream和data stream;metadata stream用于描述每个行组的元数据信息,为了进一步的避免读入不必要的数据,在逻辑上将一个column的index以一个给定的值(默认为10000,可由参数配置)分割为多个index组。以10000条记录为一个group,对数据进行统计。Hive查询引擎会将where条件中的约束传递给ORC reader,这些reader根据组级别的统计信息,过滤掉不必要的数据。如果该值设置的太小,就会保存更多的统计信息,用户需要根据自己数据的特点权衡一个合理的值。数据是以Stream的形式保存了数据的具体信息。

l  Stripe Footer里面存储的是数据所在的文件目录,包含了该Stripe的统计结果,包括Max、Min以及Count等信息。

l  文件的末尾File Footer里面包含了ORC文件中Stripe的列表、每个Stripe的行数,以及每个列的数据类型。它还包含了该表每个列的最小值、最大值等信息。因此,如果查询一个列的最大、最小值,可以从这里直接读取。FileFooter记录信息截图如下:

图2-1 ORC的Footer存储信息示意图

l  PostScript中保存着整个文件的元数据信息,它包括文件的压缩格式、文件内部每一个压缩块的最大长度(每次分配内存的大小)、Footer长度,以及一些版本信息。Postscript记录信息截图如下: 

图2-2 ORC的PostScript存储信息示意图

2.2 ORC格式优势

ORC(Optimied Row Columnar)在RCFile的基础上发展而来,并在RCFile的基础上进行了一定的改进,所以与RCFile相比,具有以下一些优势:

1、ORC中的特定的序列化与反序列化操作可以使ORC file writer根据数据类型进行写出。

2、提供了多种RCFile中没有的indexes,这些indexes可以使ORC的reader很快的读到需要的数据,并且跳过无用数据,这使得ORC文件中的数据可以很快的得到访问。

3、由于ORC file writer可以根据数据类型进行写出,所以ORC可以支持复杂的数据结构(比如Map等)。

4、除了上面三个理论上就具有的优势之外,ORC的具体实现上还有一些其他的优势,比如ORC的stripe默认大小更大,为ORC writer提供了一个memory manager来管理内存使用情况。

3、Spark读写ORC问题以及解决方法

3.1 问题描述

  Spark3.x版本中使用的ORC的版本是1.7.6,该版本中默认写入的版本类型是ORC_14,当Spark向CDH6.X写入数据时,默认使用该版本写入到文件的postscript信息中。

如下图所示:

图3-1 ORC1.7.6版本的默认写入版本示意图

  当hive读取ORC类型数据时,文件元数据类型不为空时,会读取写入文件的版本信息,相关代码如下:

图3-2 hive读取orc格式文件元数据信息示意图

   由于CDH6.X使用的hive为2.1版本,该版本中ORC的写入版本最大值为Hive_13083,当读取的ORC文件版本超过枚举值最大值时会导致报错数组越界。报错示意图如下:

图3-3 hive读取高版本orc格式文件报错示意图 

图3-4报错代码定位示意图

  Hive2.1支持的ORC文件格式写入版本源码截图如下:

 

图3-5 cdh6.x处理orc格式文件版本代码示意图

3.2、解决方法

  下载ORC1.7.6的源码,修改ORC的默认写入文件的版本号,改成CDH6.X版本最大可以识别的版本HIVE_13083(4),重新编译并替换掉Spark的ORC的jar包即可。

posted @ 2024-01-29 19:17  虎啸千峰  阅读(1176)  评论(0编辑  收藏  举报