Paimon
Apache Paimon (incubating) 是一项流式数据湖存储技术,可以为用户提供高吞吐、低延迟的数据摄入、流式订阅以及实时查询能力。Paimon 采用开放的数据格式和技术理念,可以与 Flink / Spark / Trino 等诸多业界主流计算引擎进行对接,共同推进 Streaming Lakehouse 架构的普及和发展。
Paimon x Spark
Apache Spark,作为大数据处理的统一计算分析引擎,不仅支持多种语言的高级API使用,也支持了丰富的大数据场景应用,包括结构化数据处理的Spark SQL、用于机器学习的MLlib,用于图形处理的GraphX,以及用于增量计算和流处理的Structured Streaming。Spark已经成为了大数据领域软件栈中必不可少的组成部分。对 Paimon 来说,为了在准实时和离线湖仓场景更加便利的落地,与 Spark 深度、全面的集成势在必行。
在之前的Paimon Release版本,我们着重丰富Paimon在功能上和Spark SQL生态的集成,包括Schema Evolution,Structured Streaming Read/Write,Dynamic Insert Overwrite Partition,Update/Merge Into等等。在最近发布的0.6和0.7版本,我们开始在Paimon基于Spark SQL查询性能上做一些工作。在初期我们会结合Spark SQL已有的优化规则和框架,让Paimon充分利用到这些。通过一系列优化,我们将 Paimon x Spark 在 TpcDS 上的性能提高了37+%,已基本和 Parquet x Spark 持平。下文将对其中的关键优化点进行详细介绍。
动态分区裁剪
动态分区裁剪(Dynamic Partition Prunning,DPP)在SQL优化中是常见的优化点,本质上是谓词下推(Predicate PushDown)的一种拓展,其目的是最小化从数据源中读取数据的IO成本,也进而减少了计算成本。
在数仓中,常常将较大的事实表和很小的维度表关联查询,且事实表需要根据维表中的字段信息来进行过滤,如下面TpcDS Q14中的SQL片段:
select ss_quantity quantity ,ss_list_price list_price
from store_sales, date_dim
where ss_sold_date_sk = d_date_sk and d_year between 1999 and 1999 + 2
order by quantity limit 10;
在不支持DPP的情况下的执行计划简化如下:
Paimon应用的是Spark DataSource V2的查询框架,该框架在Spark3.2后提供了 SupportsRuntimeFiltering
接口用于V2表实现运行时的动态过滤。理论上,任何字段(包括普通数据字段和分区字段)的过滤条件都能被应用,但一般而言仅分区字段的过滤条件能够被完全应用,即无需上层的Filter的节点再使用该过滤条件去选择数据。Paimon表通过该接口实现了动态分区裁剪的能力。在支持DPP后执行计划如下所示:
在1T的TpcDS数据集下,应用DPP后 store_sales
表参与join的数据量从27亿 减少到16亿。仅应用到该优化后,Q14运行时间减少到原来的~55%,1T TpcDS数据集的查询性能整体提升20+%;
相关代码:
https://github.com/apache/incubator-paimon/pull/2411
https://github.com/apache/incubator-paimon/pull/2421
Exchange复用
Exchange是Spark中物理计划中一个关键的操作,对应逻辑计划中的Shuffle。在执行阶段,Exchange可以代表某个SQL中部分Plan输出的数据。在复杂的SQL中,我们可以通过公共表表达式(Common Table Expr