Spark Paimon 中为什么我指定的分区没有下推

spark-sql写数据到paimon并同步到hive元数据 INSERT INTO paimon.my_db.my_table VALUES (1, 'M', 173.5,'北京市朝阳区'), (2, 'G',185, '上海市'), (3, 'cherry', 168.0,'河北省秦皇岛市');备注需要将将paimon-hive-connector-3.1-0.9.0.jar上传到hive的lib目录下/cluster/hive/lib。-- 在已建立的paimon catalog中,建立数据库。-- 向Paimon中写入数据。-- 建立Paimon表。 阅读详情

背景

最近在使用 Paimon 的时候遇到了一件很有意思的事情,写的 SQL 居然读取的数据不下推,明明是分区表,但是却全量扫描了。
目前使用的版本信息如下:
Spark 3.5.0
Paimon 0.6.0
paimon的建表语句如下:

CREATE TABLE `table_demo`(
  `user_id` string COMMENT 'from deserializer' 
  )
PARTITIONED BY ( 
  `dt` string COMMENT '日期, yyyyMMdd', 
  `hour` string COMMENT '小时, HH')
ROW FORMAT SERDE 
  'org.apache.paimon.hive.PaimonSerDe' 
STORED BY 
  'org.apache.paimon.hive.PaimonStorageHandler' 
WITH SERDEPROPERTIES ( 
  'serialization.format'='1')
LOCATION
  'xxxx'
TBLPROPERTIES (
  'bucket'='50', 
  'bucketing_version'='2', 
  'bukect-key'='user_id', 
  'file.format'='parquet', 
  'merge-engine'='partial-update', 
  'partial-update.ignore-delete'='true', 
  'primary-key'='user_id', 
  'transient_lastDdlTime'='1701679855', 
  'write-only'='false')

查询的SQL如下:

select * from 
table_demo
where dt =20231212
and hour =10
limit 100;

注意我们这里写的dt是整数类型,而表中定义的是字符串类型

结论及解决方法

结论

具体的原因是Spark DSv2中的规则 V2ScanRelationPushDown.pushDownFilters 对于 Cast类型转换表达式不会传递到DataSource端,所以只会在读取完Source转换进行过滤,
这种情况下,对于文件的读取IO会增大,但是对于shuffle等操作是不会有性能的影响的。

解决方法

对于分区字段来说,我们在写SQL对分区字段进行过滤的时候,保持和分区字段类型一致

分析

错误写法分析

针对于错误的写法,也就是导致读取全量数据的写法,我们分析一下,首先是类型转换阶段,在Spark中,对于类型不匹配的问题,spark会用规则进行转换,具体的规则是
CombinedTypeCoercionRule,
在日志中可以看到:

=== Applying Rule org.apache.spark.sql.catalyst.analysis.TypeCoercionBase$CombinedTypeCoercionRule ===
 'GlobalLimit 100                                                                                   'GlobalLimit 100
 +- 'LocalLimit 100                                                                                     +- 'LocalLimit 100
    +- 'Project [*]                                                                                        +- 'Project [*]
!      +- 'Filter ((dt#520 = 20231212) AND (hour#521 = 10))                                                   +- Filter ((cast(dt#520 as int) = 20231212) AND (cast(hour#521 as int) = 10))
          +- SubqueryAlias spark_catalog.default.table_demo                                                      +- SubqueryAlias spark_catalog.default.table_demo
             +- RelationV2[user_id#497, dt#520, hour#521] spark_catalog.default.table_demo                          +- RelationV2[user_id#497,dt#520, hour#521] spark_catalog.default.table_demo
           

通过以上规则我们可以看到 过滤条件(dt#520 = 20231212) AND (hour#521 = 10) 转换为了 (cast(dt#520 as int) = 20231212) AND (cast(hour#521 as int) = 10)

接着再经过以下规则:V2ScanRelationPushDown的洗礼,我们可以看到如下日志:

12-13 13:52:58 763  INFO (org.apache.spark.sql.execution.datasources.v2.V2ScanRelationPushDown:60) - 
Pushing operators to table_demo
Pushed Filters: IsNotNull(dt), IsNotNull(hour)
Post-Scan Filters: (cast(dt#520 as int) = 20231212),(cast(hour#521 as int) = 10)
12-13 13:52:58 723  INFO (org.apache.paimon.spark.PaimonScanBuilder:62) - pushFilter log: IsNotNull(dt),IsNotNull(hour)
12-13 13:52:58 823  INFO (org.apache.spark.sql.execution.datasources.v2.V2ScanRelationPushDown:60) - 
Output: user_id#497, dt#520, hour#521
         
12-13 13:52:58 837  INFO (org.apache.spark.sql.catalyst.rules.PlanChangeLogger:60) - 
=== Applying Rule org.apache.spark.sql.execution.datasources.v2.V2ScanRelationPushDown ===
 InsertIntoHadoopFsRelationCommand ], Overwrite, [user_id,  dt, hour]                                                                        InsertIntoHadoopFsRelationCommand xxx, false, Parquet, [path=xxx], Overwrite, [user_id, dt, hour] 
 +- WriteFiles                                                                                                                                    +- WriteFiles
    +- Repartition 1, true                                                                                                                           +- Repartition 1, true
       +- GlobalLimit 100                                                                                                                               +- GlobalLimit 100
          +- LocalLimit 100                                                                                                                                +- LocalLimit 100
!            +- Filter ((isnotnull(dt#520) AND isnotnull(hour#521)) AND ((cast(dt#520 as int) = 20231212) AND (cast(hour#521 as int) = 10)))                   +- Filter ((cast(dt#520 as int) = 20231212) AND (cast(hour#521 as int) = 10))
!               +- RelationV2[user_id#497, dt#520, hour#521] spark_catalog.default.table_demo table_demo                                                                     +- RelationV2[user_id#497, dt#520, hour#521] spark_catalog.default.table_demo   table_demo
   

这里只有过滤条件 isnotnull(dt#520) AND isnotnull(hour#521) 被下推到了 DataSource。
从现象来看,确实分区的过滤条件没有推到DataSource端, 我们来分析一下该规则的数据流:

V2ScanRelationPushDown.pushDownFilters
       ||
       \/
PushDownUtils.pushFilters
       ||
       \/
DataSourceStrategy.translateFilterWithMappin
       ||
       \/
translateLeafNodeFilter

具体到translateLeafNodeFilter 方法:

  private def translateLeafNodeFilter(
      predicate: Expression,
      pushableColumn: PushableColumnBase): Option[Filter] = predicate match {
    case expressions.EqualTo(pushableColumn(name), Literal(v, t)) =>
      Some(sources.EqualTo(name, convertToScala(v, t)))
    case expressions.EqualTo(Literal(v, t), pushableColumn(name)) =>
      Some(sources.EqualTo(name, convertToScala(v, t)))
    ...
    case _ => None

这里没有对Cast表达式进行处理,所以说最后返回的就是不能下推的处理,而 Paimon datasouce那边,具体的类为PaimonBaseScanBuilder:

  override def pushFilters(filters: Array[Filter]): Array[Filter] = {

这里传进来的filters实参 就不存在 (cast(dt#520 as int) = 20231212) AND (cast(hour#521 as int) = 10) 这个过滤条件,所以就不会下推到Paimon中去

其实不仅仅是对于Paimon Source, 其他的source也会有这个问题。

正确学法分析

正确的SQL如下:

select * from 
table_demo
where dt ='20231212'
and hour ='10'
limit 100;

运行如上SQL,我们可以看到如下日志:

12-14 14:22:42 328  INFO (org.apache.paimon.spark.PaimonScanBuilder:62) - pushFilter log: IsNotNull(dt),IsNotNull(hour),EqualTo(dt,20231212),EqualTo(hour,10)
12-14 14:22:42 405  INFO (org.apache.spark.sql.execution.datasources.v2.V2ScanRelationPushDown:60) - 
Pushing operators to table_demo
Pushed Filters: IsNotNull(dt), IsNotNull(hour), EqualTo(dt,20231212), EqualTo(hour,10)
Post-Scan Filters: 

=== Applying Rule org.apache.spark.sql.execution.datasources.v2.V2ScanRelationPushDown ===
 InsertIntoHadoopFsRelationCommand xxx, false, Parquet, [path=xxx], Overwrite, [user_id, dt, hour]                       InsertIntoHadoopFsRelationCommand xxx, false, Parquet, [path=xxx], Overwrite, [user_id, dt, hour]
 +- WriteFiles                                                                                                            +- WriteFiles
    +- Repartition 1, true                                                                                                   +- Repartition 1, true
       +- GlobalLimit 100                                                                                                       +- GlobalLimit 100
          +- LocalLimit 100                                                                                                        +- LocalLimit 100
!            +- Filter ((isnotnull(dt#1330) AND isnotnull(hour#1331)) AND ((dt#1330 = 20231212) AND (hour#1331 = 10)))               +- RelationV2[user_id#1307,  dt#1330, hour#1331] table_demo
!               +- RelationV2[user_id#1307,  dt#1330, hour#1331] spark_catalog.ad_dwd.table_demo table_demo                           
   

可以看到经过了规则转换 所有的过滤条件都下推到了DataSource了,但是具体的下推还得在DataSource进一步处理才能保证真正的下推

Paimon——官网阅读:Spark 引擎 阅读详情

相关推荐

别再被SpringerLink虐了!手把手教你搞定LaTeX源文件提交(附正确文件顺序和类型选择)

本文详细解析了SpringerLink投稿系统中LaTeX源文件提交的常见问题与解决方案,包括文件打包、类型选择和顺序排列等关键步骤。通过实战经验,帮助科研人员避开隐形陷阱,一次性完成LaTeX提交,提升投稿效率。特别针对`.bst`和`.cls`文件的正确处理提供了专业指导。

weixin_42522964的博客 442

Paimon 与 Spark 的集成(一)

PaimonApache Paimon (incubating) 是一项流式数据湖存储技术,可以为用户提供高吞吐、低延迟的数据摄入、流式订阅以及实时查询能力。Paimon 采用开放的数据格式和技术理念,可以与 ApacheFlink / Spark / Trino 等诸多业界主流计算引擎进行对接,共同推进 Streaming Lakehouse 架构的普及和发展。Paimon x SparkApa...

weixin_45906054的博客 1836

运算放大器 VS 仪表放大器

运算放大器(Operational Amplifier, 简称 Op Amp)和仪表放大器(Instrumentation Amplifier, 简称INA)在电子电路设计中都有非常广泛的应用,但两者在结构、特性以及应用场景上都有明显的区别。以下是它们之间主要的差异:运算放大器(Op Amp)仪表放大器(INA)运算放大器仪表放大器运算放大器仪表放大器运算放大器仪表放大器运算放大器仪表放大器总之,运算放大器是通用型放大元件,需要设计者自己做额外的电路配置;而仪表放大器则是针对高精度测量差分信号而生,内部匹配

chinahongjiang的博客 1346

流数据湖平台Apache Paimon(六)集成Spark之DML插入数据

不能将另一个表的可为空列插入到一个表的非空列中。通过tags表可以查询表的标签历史信息,包括基于哪些快照进行标签以及快照的一些历史信息。通过snapshots表可以查询表的快照历史信息,包括快照中发生的记录数。插入的行可以由值表达式或查询结果指定,跟标准的sql语法一致。系统表包含有关每个表的元数据和信息,例如创建的快照和使用的选项。Paimon的批量读取返回表快照中的所有数据。可以通过选项表查询DDL中指定的表的选项信息。通过查询快照表,可以了解该表的提交和过期信息以及数据的时间旅行。

Maynor的博客 1075

波分复用技术原理

波分复用原理 把不同波长的光信号复用到同一根光纤中进行传送,这种方式我们把它叫做波分复用( Wavelength Division Multiplexing ) 一根光纤被划分为多个波道,多个波长以一定的间隔隔开,在光纤中独立传输。 波分复用应用演示 如果将WDM系统看作交通系统,光纤可以看作是多个车道的公用道路。 各种类型的业务就像货物一样,被打包装载到车辆中。 车辆按照分配的车道行驶至目的地,完成货物的运输。 想要提高波分复用系统的传输容量,就要增加波道数量或是提升单波传...

m0_63251770的博客 9997

高分7(GF7)卫星数据制作平原地区DSM/DEM(三)——可信度分割

李国春(接上)

副组长的博客 1714

spark-sql读取映射hbase数据的hive外部表

之前在业务处理中建立的一个hive映射hbase数据的外部表,通过hive查询成功,但是通过spark-sql去查询报了如下错误:Error: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Error in loading storage handler.org.apache.hadoop.

Sir_yuan的博客 5700

从厘米级到公里级:北斗网格10级精度在ArcPro中的完整应用指南

本文提供了北斗网格十级精度体系在ArcGIS Pro中的完整应用指南。详细解析了从660公里到1.5厘米的十级网格尺度及其编码逻辑,并重点演示了如何在ArcPro中生成网格、计算编码,以及根据项目需求(如滑坡监测)选择合适精度层级的实战策略。指南旨在帮助GIS专业人士利用这套统一的网格框架,高效管理多尺度空间数据并优化分析工作流。

Black的专栏 471

Paimon 与 Spark 的集成(二):查询优化

PaimonApache Paimon (incubating) 是一项流式数据湖存储技术,可以为用户提供高吞吐、低延迟的数据摄入、流式订阅以及实时查询能力。Paimon 采用开放的数据格式和技术理念,可以与 Flink / Spark / Trino 等诸多业界主流计算引擎进行对接,共同推进 Streaming Lakehouse 架构的普及和发展。Paimon x Spark‍‍Apache ...

weixin_45906054的博客 1930

基于 YOLOv26 的金属表面缺陷检测系统:智能视觉质检方案

摘要: 基于YOLOv26的金属表面缺陷检测系统采用深度学习技术,实现对划痕、裂纹、腐蚀等8类常见缺陷的自动化检测。系统通过数据增强预处理和YOLOv26模型的高精度识别能力,具备多类别分类、实时推理和强鲁棒性特点,适用于不同金属材质与光照条件。架构包含数据采集、预处理、YOLOv26检测和后处理模块,代码实现采用PyTorch框架,支持训练数据增强与标准化处理,为工业质检提供高效智能解决方案。

一键难忘的博客 588

EtherCAT从站EEPROM组成信息详解(2):字8-15产品标识区

以实际的从站EEPROM数据为例,参照EtherCAT的SII规范,详细分析了从站EEPROM字8-字15的产品标识区内容组成。

kevin1499的博客 718

【PySpark 学习笔记 三】数据清洗:DataFrame API基础操作

本文介绍了使用PySpark DataFrame API完成从数据读取到写出的完整流程。通过电商平台用户消费分析案例,演示了以下关键步骤: 创建SparkSession并配置Paimon Catalog 从Paimon表读取用户和订单数据 数据清洗(过滤活跃用户、有效订单) 聚合计算(用户级和城市级聚合) 多表关联(inner/left join选择) 空值处理与去重 结果写出到Paimon表和Parquet文件 流程重点包括Schema裁剪优化、聚合组合操作、join类型选择等核心技巧,适用于大规模数据处

MaoLin Tian's Blog 526

【DexGraspNet与多指手抓取算法详解】第四章 抓取检测网络架构设计

图 $G=(V, E)$ 包含两类节点:指尖节点 $V_{tip} = \{v_{tip}^i\}_{i=1}^{N_{finger}}$ 与物体表面节点 $V_{obj} = \{v_{obj}^j\}_{j=1}^{N_{surf}}$。节点特征包含位置 $x \in \mathbb{R}^3$ 、法向 $n \in \mathbb{R}^3$ 及视觉特征 $f \in \mathbb{R}^d$。

VectorShift的博客 440

EMR Serverless Spark 推出 Spark 4.0,加速湖仓架构下的数据处理升级

这是 Spark 项目自诞生以来变化最大的一次版本升级——全新的 VARIANT 数据类型、原生 SQL UDF、重新设计的基础设施架构、以及对 Python 生态的全面增强。阿里云 EMR Serverless Spark 当前已适配 Spark 4.0 ,企业用户可直接在生产环境使用这些能力,无需自建集群、无需手动升级、无需担心兼容性。对于数据湖上的 JSON 密集型工作负载,Paimon Variant 配合 Spark 4.0 的 VARIANT 类型,提供了业界领先的存储 + 计算方案。

weixin_45906054的博客 81

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【sql篇】大数据SQL五层优化(万字详解)

《大数据SQL性能优化五层体系》摘要:本文系统性地提出大数据SQL优化的五层体系:1.字段级优化(选择最小化数据类型,避免隐式转换)2.算子级优化(重写SQL逻辑,减少计算量)3.表级优化(合理分区分桶,优化存储格式)4.引擎级优化(调整执行参数,处理数据倾斜)5.架构级优化(数据分层治理)。核心原则是自底向上逐层检查,通过减少数据移动和计算量提升性能。文章包含数值/时间类型选择、Join策略、分区设计等实战技巧,并给出检查清单和优化案例,帮助开发者系统解决SQL性能问题。

zy123456nn的博客 510

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【PySpark 学习笔记 五】SQL 协作:Spark SQL、临时视图、UDF

摘要 本文介绍了Spark SQL的核心功能与应用场景,通过城市销售日报案例对比DataFrame API与SQL的差异。主要内容包括: 双接口设计:Spark提供DataFrame API和SQL两种操作方式,底层共享Catalyst优化器,性能一致但适用场景不同。DataFrame适合复杂ETL,SQL便于临时查询。 技术实现:详细讲解临时视图、内置函数分类(字符串/日期/数学/聚合/窗口)和UDF性能优化(Pandas UDF比Python UDF更快)。 实践案例:从纯DataFrame实现逐步演变

MaoLin Tian's Blog 666

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

EMR Serverless Spark 数据湖上新能力:一条 SQL 实现标量向量混合检索

阿里云 EMR Serverless Spark 现已支持 标量向量混合检索——基于 DLF Global Index 提供的向量索引能力,Spark SQL 原生支持标量过滤 + 向量近邻检索的混合查询,一条 SQL 即可完成"语义相似 + 条件约束"的双重检索。

科技很有意思 538

如何在3步内搭建企业级元数据湖?Apache Gravitino完整安装与使用指南

在数据爆炸式增长的时代,企业面临的最大挑战之一就是元数据碎片化问题。不同数据源、不同计算引擎、不同存储系统之间形成了数据孤岛,导致数据发现困难、治理成本高昂。Apache Gravitino作为新一代高性能、地理分布式和联邦化的元数据湖解决方案,正是为了解决这一痛点而生,为企业提供统一的元数据访问,实现跨云数据发现、AI资产管理和多引擎兼容的一站式数据治理平台。 ## 为什么需要统一元数据管理?

gitblog_00783的博客 452

重磅!flink-table-store将作为独立数据湖项目重入apache

重磅!flink-table-store将作为独立数据湖项目重入apache,项目名 Paimon

qq_39712666的博客 1561

淘宝闪购基于阿里云 EMR Serverless Spark&Paimon 的湖仓实践:超大规模下的特征生产&多维分析双提效

本文介绍阿里云 Serverless Spark + Paimon在淘宝闪购大数据湖仓场景的应用。

科技很有意思 1175

官宣|Apache Fluss 毕业成为顶级项目,湖流一体开启 Agentic Lake 全面实时化时代

今年 7 月,Apache Fluss 的毕业提案在 Apache 孵化器项目管理委员会(IPMC)投票中获得全票通过,随后获 Apache 软件基金会董事会批准。今天,Apache 软件基金会正式宣布 Apache Fluss 孵化毕业,成为 Apache 顶级项目(TLP)!这一里程碑不仅标志着 Fluss 迈入新的发展阶段,也将进一步推动流式存储、实时湖仓与 AI 数据基础加速融合,为实时数据基础设施的发展开启新的篇章。图 1|Apache 软件基金会发布 Apache Fluss 成为顶级项目公告。

Ververica的博客 1278

001:一个快速、可嵌入、模块化的分析查询引擎

通过插件开发,我们能够极大地释放Typora的潜力,使其从一个优秀的Markdown编辑器进化为一个高度定制化的“写作操作系统”。回顾核心要点:从环境搭建、API学习到实战开发与性能优化。未来可能性:AI辅助写作集成、云同步插件、多人在线协作编辑等。行动号召:鼓励读者从一个小需求开始,动手开发自己的第一个Typora插件,共同丰富Markdown写作的工具生态。

336

<span class=“js_title_inner“>云栖2025|阿里云开源大数据发布新一代“湖流一体”数智平台及全栈技术升级</span>

在AI融合领域,阿里云通过 Spark + DLF 全模态湖仓实现文本、音频、视频等多模态数据的统一治理与AI模型训练,而 Flink + Milvus + LLM 构建的实时智能分析决策系统,则支持舆情分析、直播监控等场景的毫秒级AI决策。在企业级治理能力方面,覆盖存储、计算、开发、安全多维度,事前、事中、事后等全方位治理能力;,在支持 Paimon、Iceberg 等主流湖表格式的基础上,将存储格式从传统结构化数据,拓展至全模态数据场景,支持面向 AI 场景的 Lance 文件数据、表格数据等全类型。

weixin_45906054的博客 99

网易数帆EasyData使用Cloudera CDP、CMP(华为鲲鹏版)作为底座的AI功能操作步骤

网易数帆EasyData支持以Cloudera CDP或华为CMP(鲲鹏ARM版)为数据底座的AI增强分析方案。该方案通过JDBC/ODBC接入CDP/CMP数据源,利用EasyData内置AI引擎实现自然语言查询(ChatBI)、时序预测和异常检测等功能。实施步骤包括:1)配置数据源连接(支持Kerberos认证);2)同步元数据并创建逻辑表;3)启用AI功能模块。特别针对华为CMP需注意ARM64架构适配和性能优化。该方案适用于已部署CDP/CMP且需保留原数据存储的企业,实现数据与AI能力的解耦部署。

yumgpkpm的专栏 1186
上一篇: Spark升级中对log4j的一些思考
下一篇: Spark 中 BroadCast 导致的内存溢出(SparkFatalException)
鸿乃江边鸟
博客等级 码龄6年 3746粉丝 235原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值