欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

0496-使用Parquet矢量化为Hive加速

程序员文章站 2022-07-14 19:43:06
...

1 背景

Apache Hive是Hadoop之上最流行的数据仓库引擎。提升Hive性能的功能可以显著提高集群资源的整体利用率。Hive使用一连串的运算符来执行查询。这些运算符包括MapTask,ReduceTask或SparkTask,它们在查询执行计划中进行调度。以前这些运算符被设计为每次处理一行数据。一次处理一行导致运算符效率不高,因为需要许多虚函数调用来处理扫描的每一行。另外,如果运算符一次只处理一行,不能利用CPU的SIMD指令集(例如SSE或AVX)进行加速。本文主要介绍如何在Hive中利用基于SIMD的优化,使Apache Parquet表的查询运行效率提升26%以上。

2 CPU矢量化

矢量化是将算法从一次操作一个值转换为一次操作一组值的过程。现在的CPU一般都直接支持矢量操作,即使用单个指令处理多个数据点(SIMD)。

0496-使用Parquet矢量化为Hive加速

上图显示了使用scalar和vector指令添加两组值的简单示例

例如,支持AVX-512指令集的CPU提供512位寄存器,与16个标量指令中的相同计算相比,它可以保存多达16个32位的值并执行简单操作如在一条指令中执行加法运算。在此示例中,矢量化(vectorized)执行将比标量(scalar )执行快16倍。

3 Hive中的矢量化

为了利用这些优化,Hive在HIVE-4160中引入了矢量化查询执行,参考:

https://issues.apache.org/jira/browse/HIVE-4160

矢量化查询执行引入了新的运算符和表达式,即每次处理一批行,而不是每次只处理一行数据。与基于行的执行相比,矢量化执行避免了大量的虚函数调用,从而提高了指令和数据缓存命中率。它更好地利用了现在的CPU(如 Intel Xeon Scalable processors)的指令流水线(instruction pipeline),还可以利用Intel SSE/AVX指令集在CPU级别并行化数据处理。这可以显著提高查询性能。关于Hive中矢量化的更多设计细节可以参考:

https://issues.apache.org/jira/secure/attachment/12603710/Hive-Vectorized-Query-Execution-Design-rev11.pdf

4 Parquet Vectorized Reader

Apache Parquet是大数据生态系统中广泛使用的列式文件格式。但是Hive却不能矢量化读取Parquet文件,意味着即使你的集群中启用了矢量化,map任务在读取Parquet文件时依旧会一次只处理一行。所以如果你的表使用的是Parquet文件格式,查询这些表的时候将不能利用矢量化查询执行来提升性能。为了改善这一点,Cloudera和英特尔密切合作,在HIVE-14826中引入了Hive Parquet Vectorization,参考:

https://issues.apache.org/jira/browse/HIVE-14826

Parquet vectorized reader一次返回一批行的列而不是只有一行,这一批列可以直接被传递给运算符树(operator tree),而不用做任何中间转换。在Hive中而不是Parquet库中实现vectorized parquet reader可以避免额外的内存复制操作来创建批次,从而进一步提高了性能。从CDH6.0开始,CDH中的Hive可以使用此功能。

0496-使用Parquet矢量化为Hive加速

5 已知的限制

除了像string,integer或double这样的基本数据类型之外,Parquet还支持struct,list或map等复杂类型。目前vectorized reader只能处理基本数据类型和不带嵌套的复杂类型。支持嵌套复杂类型处理的工作尚在进行中。当查询的数据是嵌套复杂类型时(如list,map或struct),查询引擎会降回使用非矢量化执行。矢量化执行所有支持的数据类型参考:

http://www.cloudera.com/documentation/enterprise/latest/topics/hive_query_vectorization.html

6 使用Parquet矢量化

CDH6.0默认开启了Hive矢量化,你也可以在连接会话中使用set将

hive.vectorized.execution.enabled

配置为true,该参数默认值也为true从CDH6.0开始。

set hive.vectorized.execution.enabled=true;

你可以通过配置

hive.vectorized.input.format.excludes

来控制是否对某些文件格式不启用矢量化,配置该参数的值需要使用文件格式的类名的全名,采用逗号分隔,然后被配置的文件格式将都不会进行矢量化计算。例如,要为Parquet表禁用矢量化,可以将

hive.vectorized.input.format.excludes

设置为

org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat。

通过Cloudera Manager可以为Hive服务配置这些。更多与矢量化相关的配置具体参考:

http://www.cloudera.com/documentation/enterprise/latest/topics/hive_query_vectorization.html

7 性能结果

我们使用Hive on Spark在4个节点的Skylake集群(Xeon Gold 6140)上测试了Parquet矢量化的性能,测试场景是使用TPC-DS,数据集为3TB。同时使用CDH5.15.1和CDH6.0来比较不同版本的CDH的性能差异。以下是具体的硬件和软件配置:

0496-使用Parquet矢量化为Hive加速

Configuration A是使用CDH5.15.1运行基线的集群,不包括Parquet矢量化功能。 Configuration B使用CDH6.0,配置中禁用Parquet矢量化。Configuration C也使用CDH6.0,但启用了Parquet矢量化。共运行了TPC-DS的55个查询。

结果显示通过此功能可以带来显著的性能提升。使用CDH6.0中的Parquet矢量化功能,所有查询时间的几何平均(geomean )从CDH5.15.1的243.82秒提高到176.70秒,比CDH5.15.1提高了1.36倍。

0496-使用Parquet矢量化为Hive加速

下图显示同样在CDH6.0中,与禁用Parquet矢量化相比,开启矢量化后对于TPC-DS各个查询的性能提升百分比。5个查询(q21,q39,q58,q66,q88)性能提升超过50%,其余大部分提升在20%-40%之间。

0496-使用Parquet矢量化为Hive加速

8 总结

CDH6.0中的性能基准测试表明启用Parquet矢量化后可以显著提升典型的ETL工作负载的性能。使用TPC-DS,启用Parquet矢量化可以使平均性能提升26.5%(所有查询运行时间的几何平均值)。Vectorization通过减少虚函数调用的数量,并利用CPU的SIMD指令来获得这些性能提升。当满足某些条件(如受支持的字段类型或表达式),使用Hive查询就会使用矢量化执行。如果查询不能使用矢量化,则会回退到非矢量化执行。总的来说,从CDH6.0开始,在如今主流的处理器上,启用Parquet矢量化对于你查询Parquet表时都可以实现比以前更好的查询性能。

原文参考:

https://blog.cloudera.com/blog/2018/12/faster-swarms-of-data-accelerating-hive-queries-with-parquet-vectorization/

作者列表:

VihangKarajgaonkar is a Software engineer at Cloudera

SantoshKumar is a Senior Product Manager at Cloudera

HaifengChen is a Senior Engineering Manager at Intel

Cheng Xuis an Engineering Manager at Intel

WangLifeng is a Software Engineer at Intel

相关标签: Hadoop实操