Apache Impala 4.1概览
自从Impala 4.0发布后,历时近11个月,Impala 4.1终于发布了!新版本在Iceberg集成、Catalog优化、Parquet/ORC读取性能、嵌套类型等方面都有较大进展。限于个人认知和篇幅有限,本文只能挑些重要功能进行介绍,详细更新列表可见 Change Log-4.1.
1. Iceberg集成
Impala-4.1开始正式支持Apache Iceberg。Iceberg是开源的table format,具有以下几个特性:
- ACID保证:DML都是原子操作,查询都访问一致的snapshot
- 隐藏分区:不像传统的Hive表用文件目录来表示分区值,Iceberg表的分区值由列值转换而来,分区信息保存在metadata文件中。reader不需要知晓分区的定义,Iceberg会推断出查询所需的文件。
- 分区演化:分区的定义可以灵活更改,得益于隐藏分区,这种更新不需要重写数据文件,只需要生成新的metadata文件
- 表格式演化:新增、删除、更新列的定义都没有副作用,如不需要重写数据文件
- 版本回溯(Time travel):查询可以访问特定的一个数据版本
下面的例子演示了如何在Impala中使用Iceberg表:
目前Impala只支持Iceebrg V1类型的DML操作,即insert into/insert overwrite。Iceberg V2类型的操作如行级别的修改(update, delete)仍未支持。更多细节可查看文档:Using Impala with Iceberg Tables
2. Parquet优化
Impala支持多种文件格式,如Parquet、ORC、Avro、Text等,其中Parquet格式的支持是性能最好的,做了比较多的优化,Impala-4.1在这方面又有不少改进。
2.1 延迟物化(Late Materialization)
Parquet Scanner的工作主要包含数据读取、解压、解码和执行下推的谓词等。当有谓词下推时,可以先读取相关列的数据,过滤得到所需要的行号后,再去相应地读取其它列。在谓词选择性高的场景下,可以有数倍的性能提升,具体可查看 IMPALA-9873。
2.2 文件Bloom Filter
Parquet文件是自解释的文件,包含了schema和索引信息(如各列min-max值),其中的索引就包含可选的Bloom Filter。Impala-4.1开始支持读写Parquet文件中的Bloom Filter,下推的等值谓词能作用在文件的Bloom Filter上。(IMPALA-10640, IMPALA-10642)
2.3 文件字典(Dictionary)
Parquet文件的列可以使用字典编码,下推的谓词(Predicate/Filter)会先作用在字典上,以过滤无用的RowGroup,从而减少读取的数据量。Runtime Filter是在运行时生成的谓词,由hash join的hash表生成而来,下推到scanner提前过滤数据。
从Impala-4.1开始,Runtime Filter也会作用在字典上,前提是字典不能太大,超过一定大小将不启用此优化。这个阈值由查询选项PARQUET_DICTIONARY_RUNTIME_FILTER_ENTRY_LIMIT 控制,默认为1024。
2.4 Decimal兼容性
支持高精度类型Decimal读取的schema兼容性,即当Parquet文件的Decimal列与表字段定义的precision或scale不一致时,可兼容性地读取。(IMPALA-7087, IMPALA-8131)
3. ORC优化
Impala在ORC文件的读取方面(即ORC Scanner)集成的是第三方的ORC C++ Reader,虽然易于维护,但不像内建的Parquet Scanner那样更方便做性能优化。Impala-4.1在ORC读取方面做了不少优化,旨在缩小Parquet Scanner和ORC Scanner间的性能差距。比如下推谓词和Runtime IN-list Filter到ORC Reader,ORC Reader的异步数据读取,ORC Scanner和ORC Reader的代码优化等。许多场景下已经能做到接近读Parquet的性能。
下面列出部分JIRA:
IMPALA-6505: Min-Max predicate push down in ORC scanner
IMPALA-10894: Pushing down predicates in reading "original files" of ACID tables
IMPALA-10873: Push down EQUALS, IS NULL and IN-list predicate to ORC reader
IMPALA-6636: Use async IO in ORC scanner
IMPALA-10898: Add runtime IN-list filters for ORC tables
IMPALA-11204: Template implementation for OrcStringColumnReader::ReadValue
IMPALA-11123: Optimize count(star) for ORC scans
更多细节详见Epic: https://issues.apache.org/jira/browse/IMPALA-9040 (登陆JIRA以查看所有item)
4. Catalog优化
4.1 event-processor的改进
Event processor是catalogd中的组件,用来自动同步Hive MetaStore中的元数据更新,让用户不必使用Refresh或Invalidate Metadata <table>语句来手动同步。Impala-4.1中有以下改进
- 优化了对create/drop类型事件的处理逻辑,当对同一对象(db/table/partition)反复Create/Drop时,Impala元数据不会出现短暂不一致的现象。(IMPALA-10468、IMPALA-10502)
- 优化了对同一个表的连续多个partition事件(ALTER_PARTITION、INSERT partition)的处理,它们会被当成一批统一处理(之前是逐一处理)。Event processor只需要获取一次表锁,并且可以并行refresh变动的partition。(IMPALA-9857)
- 这极大优化了大表变动时的同步性能,我们实验了在Hive中对一个大表的Insert操作,总共产生了1824个ALTER_PARTITION和1824个INSERT event,同步到Impala中的时长如下
外表(External Table):优化前75秒,优化后25秒
内表(ACID Table):优化前313秒,优化后47秒
- 这极大优化了大表变动时的同步性能,我们实验了在Hive中对一个大表的Insert操作,总共产生了1824个ALTER_PARTITION和1824个INSERT event,同步到Impala中的时长如下
- 优化了事务表的partition事件处理,可以增量更新有变动的分区,在大表上的同步时间可以降低几个数量级(IMPALA-10923)
- 优化了对ALTER_PARTITION事件的处理,只按需刷新文件元信息(IMPALA-11050)
4.3 其它Catalog改进
- 支持在单文件上建只读表(见6.2)。
- Catalogd的慢请求和大请求会打出warning日志,有利于排查异常请求。(IMPALA-10702)
5. 嵌套类型
5.1 直接在SelectList使用Struct或Array类型
从Impala-4.1开始,SelectList里可以直接使用Struct或Array类型的列,结果将以JSON的形式转换成字符串,表现与Hive兼容。具体可见 IMPALA-9495、IMPALA-9498.
5.2 使用UNNEST()进行Array类型的行转列
Impala语法不支持Hive中的Lateral View,需要用join来展开array和map。Impala-4.1引入了和Postgresql兼容的UNNEST()函数,以方便进行array的展开(暂未支持map)。具体可见 IMPALA-10920、IMPALA-11038.
6. 其它进展
6.1 新增函数
- 所有字符串函数支持UTF-8编码,即在长度统计、大小写转换等函数里不再以字节为单位进行处理,而是以字符为单位。由于该功能与老版本不兼容,因此是默认关闭的,需要使用查询选项 set UTF8_MODE=true打开该功能。(IMPALA-2019)
- 新增 sha1、sha2、md5等内建哈希函数(IMPALA-10679、IMPALA-10730)
- 新增DataSketches函数ds_cpc_sketch, ds_cpc_estimate, ds_cpc_union, ds_cpc_stringify, ds_cpc_union_f 等(IMPALA-10282、IMPALA-10687、IMPALA-10688、IMPALA-10689)
- 新增BYTES函数统计字符串字节占用(IMPALA-955)
6.2 新增语句
- 支持Alter table unset tblproperties/serdeproperties 语句(IMPALA-5569)
- 支持用单个文件建表(只读),方便用Impala/Hive对单个文件进行分析(IMPALA-10934),需要Hive版本包含HIVE-25569(如Hive 4.0.0, 4.0.0-alpha-1)。建表语句里只需要在location前加 “sfs+”,如
CREATE EXTERNAL TABLE test_file (s STRING, i INT)
STORED AS PARQUET
LOCATION 'sfs+hdfs:///tmp/data.paq';
6.3 impala-shell连接HiveServer2
Impala-4.1中的impala-shell支持使用hs2 protocol连接HiveServer2,直接提交Hive查询。命令行参数使用--strict_hs2_protocol
,如
impala-shell.sh --strict_hs2_protocol -i hs2-host:10000
详见 IMPALA-10778: Allow impala-shell to connect directly to HS2
6.4 Spill to HDFS
Impala在计算内存不足时,会溢写中间数据到本地磁盘中。Impala-4.0开始支持溢写到S3,在云上部署时不需要配置大存储的节点。从Impala-4.1开始,溢写目录可以配置到HDFS上,溢写空间不再受限于本地磁盘容量,更有利于存储计算分离。(IMPALA-10429)
6.5 Planner改进
在基数(cardinality)估计方面有不少改进,如
IMPALA-10681: Improve inner join cardinality estimates
IMPALA-7560: Set selectivity of Not-equal
IMPALA-10766: Better selectivity for =,not distinct
也优化了inline view相关的查询计划生成性能
IMPALA-10799: Analysis slowdown with inline views and thousands of column
IMPALA-10806: Create single node plan slowdown when hundreds of inline views are joined
6.6 自适应的三路快排
Impala使用快速排序算法对内存里的数据进行排序,当数据重复度较高时,三路快排会更优于传统的两路快排。Impala-4.1开始,排序算子会根据处理的数据自适应地调整排序算法。(IMPALA-10961)
6.7 优化了Timestamp类型到String类型的转换性能
在使用cast(… as string)或 from_unixtime() 将Timestamp类型转换为String类型时,性能有近十倍的提升。(IMPALA-10984)
7. 致谢
欢迎加微信号China_Impala进入Impala社区微信群,有任何Impala相关的问题都可以在群里讨论。
最后感谢所有为Impala-4.1贡献过代码的社区开发者!他们是
Abhishek Rawat
Alexander Saydakov
Alexey Serbin
Aman Sinha
Amogh Margoor
Andrew Sherman
Attila Jeges
Bikramjeet Vig
Carolin Chen
Csaba Ringhofer
Daniel Becker
Deepti Sehrawat
Fang-Yu Rao
Fucun Chu
Gabor Kaszab
Gergely Fürnstáhl
Guojing Feng
Joe McDonnell
Kishen Das
Lipeng Lin (LPL)
Liu Yao
Michael Smith
Noemi Pap-Takacs
Norbert Luksa
Pranav Lodha
Qifan Chen
Quanlong Huang (stiga-huang)
Riza Suminto
Shajini Thayasingh
Sheng Wang (skyyws)
Shikha Asrani
Sourabh Goyal
Steve Carlin
Tamas Mate
Vihang Karajgaonkar
Wei-Chiu Chuang
Wenzhe Zhou (wzhou-code)
Xiang Yang (yx91490)
Xianqing He (xqhe)
Yida Wu
Yong Yang
Yu-Wen Lai
Zoltan Borok-Nagy
Zoltan Garaguly
Zoltan Haindrich