【Spark 核心内参】2025.10:从 Parquet 谓词下推的“度”到语义建模的“野心”

航向追踪

Apache Spark 4.1.0-preview3 发布

来源: https://lists.apache.org/thread/9y3t9j6ntg30os6os1c30dy5b2prqt8y

Spark 4.1.0-preview3相比Spark 4.1.0-preview2的核心变化:

  • 环境升级:新增对 Kubernetes v1.34 和 Swift 6.2 的支持,深度适配 Java 21。
  • 生态增强:优化 Spark Connect 远程 API,对齐 DataFrame 行为。
  • 架构稳固:彻底完成 Log4j 2 迁移,清理传递依赖冲突。
  • 分析能力:增强 SQL 结构化日志分析功能。
    该版本侧重于兼容性扩展与依赖清理,是向正式版过渡的关键迭代。

前线研讨

关于 Parquet 谓词下推中 IN 转 OR 阈值优化的技术权衡

来源:https://lists.apache.org/thread/o3r1o3mybqt3d102m6nqoyhzo4gdywt2

现象与痛点

  • 现象: 当用户在 Spark SQL 中使用 IN 子句(如 id IN (1, 2, 3...))查询 Parquet 文件时,Spark 会根据配置 spark.sql.parquet.pushdown.inFilterThreshold(默认值为 10)决定其去向。
  • 痛点: 如果 IN 列表中的值超过 10 个,Spark 就不再将该过滤条件下推给 Parquet。

预期与目标

  • 目标: 希望通过增加该配置的阈值(允许更多的值进行下推),让更多复杂的 IN 过滤能够在存储层(Parquet)直接完成。
  • 预期收益: 减少磁盘 I/O,利用存储层的跳块(Skipping)能力,提升整体查询响应速度。

各方见解

  • Asif Shahid 的技术见解:
    1. 他支持更宽泛的将 IN 转换为 OR 链条下推。
    2. 内存优化论: 他认为转换成 OR 链后,执行时变成了简单的线性判断,避免了在每个 Partition 上创建 HashSet(Map lookup)的开销,从而节省内存分配和查找成本。
  • Yuming Wang 的警示(通过引用 PR):
    1. 结构性限制: 提醒大家注意 Parquet Filter2 API 的局限。Parquet 处理 OR 是基于递归二叉树的。
    2. 性能瓶颈: 当 OR 条件过多(阈值设得太大),会导致生成的谓词树极其深,这不仅会增加 Driver 端生成计划的负担,还可能在 Executor 解析该树时导致 StackOverflowError(栈溢出) 或 CPU 瓶颈。

总结复盘

  • 核心权衡(Trade-off): 这是一个 "I/O 节省" vs "CPU/内存稳定性" 的博弈。
    1. 调大阈值: 适合 IN 列表在几十个到上百个,且数据分布稀疏的场景(此时 I/O 节省远大于 CPU 解析开销)。
    2. 保持低阈值: 是一种安全策略,防止不可控的超长 IN 列表(如几千个值)拖垮 Driver 或让读取逻辑崩溃。
  • 结论
    1. 默认值 10 是一个极其保守的"安全线"。在实际生产中,如果确定 IN 列表不会达到几千个,通常可以根据机器性能手动调优至 50-100。
    2. 通过这个问题我们可以思考一下sparksql在执行时,是怎么解析执行的?哪部分代码是在driver执行的,哪部分代码是在executor执行的。

Spark 多阶段聚合重写引发的性能疑问

来源:https://lists.apache.org/thread/jmblqxq4mf67o9p1y2k97h097pw6djxl

现象与痛点

  • 现象: 开发者在执行 groupBy("date") 聚合时,发现物理执行计划(Physical Plan)中莫名多出了一个按 (date, user_id) 进行的分组阶段。
  • 痛点:
    1. 资源浪费: 逻辑上只需要按日期汇总,底层却执行了更细粒度的 Shuffle 和聚合。
    2. 正确性疑虑: 担心 count_distinct 触发的执行计划重写,会导致非累加性函数 percentile(百分位数)计算结果出错。
    3. 性能损耗: 这种多级的 ObjectHashAggregate 在海量数据下会显著拖慢任务进度。

预期与目标

  • 合规性确认: 确认这种"多级聚合"是 Spark 的预期行为还是潜在的 Bug。
  • 原理溯源: 弄清楚为什么 count_distinct 会干预 percentile 的物理执行路径。
  • 方案优化: 在结果正确的前提下,如何消除冗余计算,提升执行效率。

各方见解

  • Herman van Hovell的见解:
    1. 这是 Spark 处理 count_distinct 的标准逻辑。为了确保去重准确,Spark 会将任务拆分为: 局部聚合,按 (分组键 + 去重键) 物理重组数据;全局聚合,在去重后的基础上计算最终结果。
    2. 这不是资源浪费,正确性保障: 虽然物理计划发生了重写,但 Spark 的优化器(Catalyst)能够确保 percentile 在多级聚合下的逻辑一致性。
  • FengYu Cao的见解:
    1. 确认了在他们的案例中(user id, date)预去重的情况下,count_distinct执行与否结果没有差异,但是会有额外的性能损耗(产生额外的ObjectHashAggregate)

总结复盘

  • 最佳实践优化:
    1. 如果你在生产环境中有类似的"去重+百分位"需求,建议先检查上游数据的唯一性。如果是为了计算活跃用户数,考虑使用 approx_count_distinct 来进一步释放计算资源。
  • 日常开发注意:
    1. 性能优化时需要多观察物理计划,警惕物理计划中涉及shuffle的操作,不必要的shuffle对性能会产生很大影响。

Spark的JSON解析行为不符合JSON标准(RFC 8259)

来源:https://lists.apache.org/thread/83ywfzb37lpktljz3rzlhgdrqwfkhyzr

现象与痛点

  • 跨系统兼容风险: 这种"宽松"的解析机制导致 Spark 能够读取被其他标准工具视为"损坏"的 JSON 数据,造成跨系统兼容性隐患。
    1. 单引号问题: Spark 默认允许使用单引号定义字符串(allowSingleQuotes=true),但标准 JSON 仅允许双引号,单引号应被视为畸形数据。
    2. 非转义字符问题: Spark 允许在字符串中直接出现未转义的控制字符(如 \n),而标准要求 U+0000 至 U+001F 的字符必须经过转义。

预期与目标

  • 核心诉求:推动 Spark 向 JSON 行业标准靠拢。
    1. 引入新的配置项来约束解析行为,使其与标准对齐。
    2. 提升数据的健壮性,对于不符合 RFC 8259 的数据应明确识别为"损坏"或"非法"。

各方见解

  • Philo的见解:
    1. 希望Spark和JSON标准接轨。将单引号视为非法。

总结复盘

  1. spark社区对此目前没有回应。也就是说近期不会对此进行改进。
  2. 问题背景在于与Hive的深度绑定: Spark 在发展初期为了快速获取 Hive 用户,其JSON处理逻辑大量参考了Hive的JsonSerDe。Hive作为一个面向 SQL 的工具,在处理字符串时对引号并不敏感,许多旧系统导出的数据本身就充斥着单引号或未转义的换行符。 另外"容错"即美德,在分布式计算中,如果因为千万分之中的一条数据"不合规"(比如多了一个控制字符)就导致整个计算任务(Job)失败,对用户来说是不可接受的。因此,Spark默认选择了Jackson解析器最宽松的PERMISSIVE模式。

方案思辨

指标与语义建模(The metrics & semantic modeling in Spark)

核心动机

目前在 Spark 中定义和使用业务指标存在以下问题:

  • 逻辑重复与维护困难:用户通常需要为不同的维度组合(如"按月活跃用户"和"按地区活跃用户")创建多个 SQL 视图,导致逻辑重复和复制粘贴错误 。
  • 计算结果不一致:复杂的指标(如比例或去重计数 COUNT DISTINCT)在被重新聚合时,往往会得到错误的结果 。
  • 治理混乱:难以确定哪个视图是指标的"官方"版本,且由于语义层往往存在于引擎之外,优化器和权限控制无法有效介入 。
  • LLM 集成困难:缺乏统一、确定的资产,使得 AI 代理或大模型难以在不同用例中获取一致且准确的数据 。

关键设计

该提案建议在 Spark 中引入一种名为 "指标视图 (Metric View)" 的一级对象 :

  • 核心理念:将指标定义(Measures)与维度划分(Dimensions)解耦。用户只需定义一次业务逻辑,即可按任意维度组合进行查询 。

  • 主要组成部分:

    1. Measures(指标):一种新型列类型,支持在没有预定义 GROUP BY 的情况下进行聚合(如 SUM(revenue)) 。
    2. Dimensions(维度):作为常规字段,用于对数据进行过滤和切分(如 Country, Date) 。
    • 使用方式:用户可以使用熟悉的 SQL 语法进行查询,系统会在查询时动态扩展为正确的聚合表达式并进行查询规划 。
    • 示例查询:SELECT MEASURE(revenue), country FROM metric_view GROUP BY ALL 。

影响价值

  • 对数据工程师:只需维护单一的指标定义,无需维护大量近似重复的视图,大大降低了维护成本和错误率 。
  • 对分析师/科学家:可以灵活地按不同维度拆解数据,且始终能得到一致、正确的答案,消除了"为什么数据对不上"的困扰 。
  • 对平台管理:实现了在引擎层面统一的治理、权限控制和"单一事实来源(Single Source of Truth)" 。
  • 对下游应用:为 AI 代理、BI 工具和 LLM 提供了可靠、确定性的数据基础,使自动生成的分析报告更加可信 。

社区探讨

  • 赞成观点
    1. 随着目前AI的兴起,Text2SQL存在准确性的问题,AI很难写出复杂聚合逻辑,尤其是非加性指标。如果Spark内部有了明确的MEASURE,AI就不用重头生成复杂聚合SQL,能够降低AI理解数据的难度。
    2. 如果指标定义在Spark内部,Spark的Catalyst可以更好的预聚合,提高查询性能。
  • 反对观点
    1. MEASURE这一新概念破坏了标准SQL的直观性,现在可以在没有group by时也能聚合,让SQL开发者违背直觉,会让不熟悉该特性的开发者感到困惑。
    2. MEASURE这一概念应当提到更高级的组件中入hive或其他第三方组件,不应由Spark承担"语义层"的职责。因为如果指标的概念存在第三方元数据管理平台,flink或其他引擎可以复用这一能力。
    3. 这会使得Catalyst变得过于臃肿,难以维护。
    4. 针对提案中提到的"多表关联自动去重(Symmetric Aggregation)",自动处理 Join 导致的重复计算(Fan-out)在技术上非常复杂。如果 Spark 自动帮用户做了"去重"或"聚合重写",当结果不符合预期时,用户将极其难以调试。与其在引擎内部通过黑盒逻辑处理,不如让用户显式地通过 SQL 写清楚,或者在数据预处理阶段(ETL)解决掉。

观察随笔

  • 笔者持保留意见,如果能被LLM利用,那当然很好。但是就目前来看还比较遥远,而且LLM发展的力度很可能很快就可以写出复杂SQL。另外指标这种业务概念,随着大数据目前湖仓一体的架构背景下,指标应该复用给其他引擎,不应当只限于Spark。

生态拓扑

Apache Spark Connect Swift Client 0.4.0 发布

https://github.com/apache/spark-connect-swift/releases/tag/0.4.0

Spark connect是spark社区在3.4版本开始大力推广的一项能力。Spark Connect 是一种基于 gRPC 的解耦架构,它允许开发者通过轻量级 API 远程连接 Spark 集群,实现"像访问数据库一样"跨语言、低开销地操作大数据。

  • 协议升级:全面升级至 gRPC Swift 2,并重新生成了相关代码。
  • 功能扩展:新增对 Timestamp 类型的支持,支持 createDataflowGraph、startRun 等算子。
  • 环境适配:兼容 Swift 6.2 及 Spark 4.1.0-preview,优化了 macOS 和 Ubuntu 上的集成测试。

Apache Spark Kubernetes Operator 0.5.0 发布

https://github.com/apache/spark-kubernetes-operator/releases/tag/0.5.0

Apache Spark Kubernetes Operator 是一种云原生控制平面,它将 Spark 作业和集群抽象为 Kubernetes 的自定义资源(CRD),从而实现通过标准 K8s 工具链自动化部署、管理及扩展 Spark 应用。

  • 环境适配:新增对 Kubernetes v1.31 至 v1.33 的支持。
  • Spark版本:支持 Apache Spark 3.5 和 4.0。
  • CRD升级:将 SparkApp 和 SparkCluster 的自定义资源定义(CRD)推进至 v1beta1 版本。
  • 功能增强:支持为 SparkCluster 配置水平自动伸缩(HPA),并丰富了使用示例。
相关推荐
康王有点困2 小时前
Flink简单使用
大数据·flink
TDengine (老段)2 小时前
TDengine ODBC 连接器进阶指南
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
2501_941982052 小时前
企微API自动化:动态权重分配新策略
大数据
ViiTor_AI2 小时前
Instagram 视频如何转文字并翻译成多语言?AI 字幕与本地化实战指南
大数据·人工智能
物联网软硬件开发-轨物科技3 小时前
【轨物方案】新能源的下半场:构筑光伏场站全生命周期智慧运维新范式
大数据·人工智能·物联网
汇智信科11 小时前
智慧矿山和工业大数据解决方案“智能设备管理系统”
大数据·人工智能·工业大数据·智能矿山·汇智信科·智能设备管理系统
阿里云大数据AI技术12 小时前
Hologres Dynamic Table 在淘天价格力的业务实践
大数据·人工智能·阿里云·hologres·增量刷新
查士丁尼·绵12 小时前
hadoop集群存算分离
hive·hdfs·zookeeper·spark·hbase·yarn·galera
OpenCSG15 小时前
新能源汽车行业经典案例 — 某新能源汽车 × OpenCSG
大数据·人工智能·汽车·客户案例·opencsg