Apache Auron 8.0.0-incubating 快速入门与集成示例

用 10 分钟把 Apache Auron 8.0.0-incubating 接入 Spark 3.5.8 并跑通第一个 200 万行聚合查询,覆盖最小配置五项、native 引擎日志级验证、enable 开关 A/B 对照与真实 fallback 实录,全部已在 Ubuntu 22.04 实测。

Apache AuronApache Auron2026/10/15

Apache Auron 8.0.0-incubating 快速入门与集成示例

目标:10 分钟内把 Apache Auron 8.0.0-incubating 接入 Spark 3.5.8,跑通第一个 200 万行 Parquet 聚合查询,并从日志层面确认 native 引擎真实参与执行;随后用开关对照、fallback 实录把「加速是否生效」变成可检查的事实。以下全部命令与回显均已在 Ubuntu 22.04(x86_64)、OpenJDK 17.0.20.1 实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • JDK:OpenJDK 17.0.20.1(java -version 实测)
  • 计算框架:Apache Spark 3.5.8(Scala 2.12.18,spark-submit --version 实测)
  • 加速组件:Apache Auron 8.0.0-incubating(fat JAR:auron-spark-3.5_2.12-release-linux-x86_64-8.0.0-incubating.jar,42,165,721 字节,内嵌 libauron.so 80,822,712 字节)
  • 版本事实:8.0.0-incubating 于 2026-07-18 发布(官方归档页标注 Jul 18 2026,源码包目录时间戳 2026-07-07),是 Apache Auron 进入 Apache 孵化器后的最新版本;此前 v6.0.0-incubating(2025-10-17)、v7.0.0-incubating(2026-03-04)均为孵化版本,v5.0.0(2025-04-28)及更早为进入 ASF 之前的版本
  • 组件状态:Apache Auron 处于 Apache 孵化器孵化阶段,官方只发布源码包 apache-auron-8.0.0-incubating-source.tgz,Maven 中央仓库尚无任何坐标(repo1.maven.org/maven2/org/apache/auron/ 实测 404),二进制 JAR 一律通过源码构建获得
  • Spark 安装目录:/opt/spark-3.5.8-bin-hadoop3(软链 /opt/spark)
  • JAR 部署位置:/opt/spark/jars/auron-spark-3.5_2.12-release-linux-x86_64-8.0.0-incubating.jar
  • 示例工程目录:/opt/auron-demo(SQL 与本地仓库目录)

确认 Spark 与 Auron 基线(实时回显):

/opt/spark/bin/spark-submit --version 2>&1 | head -6
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 3.5.8
      /_/
ls -l /opt/spark/jars/auron-spark-3.5_2.12-release-linux-x86_64-8.0.0-incubating.jar
-rw-r--r-- 1 root root 41963238 Oct 15 07:59 /opt/spark/jars/auron-spark-3.5_2.12-release-linux-x86_64-8.0.0-incubating.jar

⚠️ 注意:Auron 的 fat JAR 内嵌了用 Rust 编译的 native 动态库 libauron.so,它与构建机器的 glibc 版本绑定。本文 JAR 在 Ubuntu 22.04(glibc 2.35)上构建并在同系统验证;把更高 glibc 版本系统(如 Ubuntu 24.04)构建的 JAR 拿到 22.04 上运行会报 UnsatisfiedLinkError ... version 'GLIBC_2.38' not found(完整报错与解法见第六章 FAQ Q1)。JAR 获取与构建步骤见安装指南。

二、10 分钟最小可用

本节从配置到跑通第一个查询共 3 步,全程约 10 分钟:写最小配置(2 分钟)→ 写查询脚本(2 分钟)→ 执行并核对结果(6 分钟,含 Spark 启动)。

2.1 最小配置

Auron 以 Spark 客户端扩展的方式安装,无需改动 Spark 本体。两处配置:

第一处,把 fat JAR 放进 Spark 驱动端 classpath(最简单是 jars/ 目录):

cp auron-spark-3.5_2.12-release-linux-x86_64-8.0.0-incubating.jar /opt/spark/jars/

第二处,/opt/spark/conf/spark-defaults.conf 写入官方推荐的最小五项(完整内容):

spark.auron.enable true
spark.sql.extensions org.apache.spark.sql.auron.AuronSparkSessionExtension
spark.shuffle.manager org.apache.spark.sql.execution.auron.shuffle.AuronShuffleManager
spark.memory.offHeap.enabled false
spark.auron.ui.enabled true

逐项说明:

  • spark.auron.enable true:总开关,允许物理算子转换为 native 执行(默认即 true,显式写出便于对照排查)。
  • spark.sql.extensions org.apache.spark.sql.auron.AuronSparkSessionExtension:向 Spark 会话注入 Auron 的物理计划改写规则,没有这一项任何算子都不会被转换。
  • spark.shuffle.manager org.apache.spark.sql.execution.auron.shuffle.AuronShuffleManager:把 Spark Shuffle 换成 Auron 的本地实现(配合 native 压缩与紧凑写入格式)。
  • spark.memory.offHeap.enabled false:官方推荐组合下关闭 Spark 自身的堆外内存开关,Auron native 侧内存由自己的内存管理器(auron_memmgr)管理,不走 Spark 的 spark.memory.offHeap.size。
  • spark.auron.ui.enabled true:在 Spark UI 的 SQL 页签里追加 Auron 专属指标。

单机本地模式再加一行 /opt/spark/conf/spark-env.sh,把监听地址固定在回环(实测在仅有一块网卡/多网卡机器上能避免启动期绑定报错):

printf "export SPARK_LOCAL_IP=127.0.0.1\n" >> /opt/spark/conf/spark-env.sh

2.2 编写第一个查询

/opt/auron-demo/smoke.sql 全文(建表 + 聚合,直接照抄):

DROP TABLE IF EXISTS demo_order;
CREATE TABLE demo_order USING parquet AS
SELECT id,
       id % 6 AS l_linenumber,
       CAST(id * 1.01 AS DECIMAL(12,2)) AS l_extendedprice,
       CASE WHEN id % 3 = 0 THEN "A" WHEN id % 3 = 1 THEN "B" ELSE "C" END AS l_returnflag
FROM (SELECT explode(sequence(1, 2000000)) AS id);
SELECT l_returnflag, count(*) AS cnt, sum(l_extendedprice) AS total
FROM demo_order GROUP BY l_returnflag ORDER BY l_returnflag;

语句覆盖三类算子:CTAS 写入 Parquet(NativeParquetInsert 范畴)、全表聚合(HashAggregate)、排序(Sort)。首行 DROP TABLE IF EXISTS 让脚本可重复执行——spark-sql -f 直接重跑时已有同名表会报 TABLE_OR_VIEW_ALREADY_EXISTS(实测复现,见 FAQ Q3)。

2.3 执行与结果

cd /opt/auron-demo && /opt/spark/bin/spark-sql --driver-memory 512m -f smoke.sql

stdout 结果(实测):

A       666666  673332996666.33
B       666667  673333670000.00
C       666667  673334343333.67

手算核对:2,000,000 个 id 按 id % 3 均分为三组,A 组为 id=3,6,9 即 666,666 个,B、C 各 666,667 个,与实测完全一致;total 为各组 id * 1.01 的十进制求和,量级 6.73 万亿亦与 66.6 万 × 均值 101 万相符。

2.4 验证点与预期结果

拿到下表结果即集成成功,任一不符按第三章核对日志、按第六章排查:

检查项预期(实测值)不符时排查
查询退出码0,输出三行分组结果报 UnsatisfiedLinkError → FAQ Q1
stderr 中 NativeHelpermemory total: 896.0 MiB, onheap: 512.0 MiB, offheap: 384.0 MiB无此行 → 检查 2.1 的 extensions 配置
stderr 中 native 执行条数Start executing native plan 共 8 次0 次 → 检查 spark.auron.enable 是否被覆盖为 false
结果计数666666 / 666667 / 666667数值不对 → 检查数据源 SQL

三、确认 native 引擎真的在工作

「查询跑对了」不代表「native 加速生效了」——Auron 转换失败会静默回退到 Spark JVM 执行。本节给出三个可直接复制的检查命令,全部来自上面那次实测运行。

3.1 日志证据

Auron 的 native 引擎由 Rust 实现,经 JNI 加载,执行期会向 stderr 输出带 [auron::rt]、[auron_memmgr] 标签的日志。用 grep 直接取证(smoke.err 为上节命令 2> 重定向的 stderr):

grep -cE "Start executing native plan" smoke.err
8

8 次对应 CTAS 与聚合查询在 local 模式下被转换的各执行阶段(含 partial/final 两级聚合与 shuffle 写读)。

grep -m1 "NativeHelper: memory" smoke.err
26/10/15 08:07:29 WARN NativeHelper: memory total: 896.0 MiB, onheap: 512.0 MiB, offheap: 384.0 MiB

这一行在 native 环境初始化时输出:onheap 即 --driver-memory 512m 的 JVM 堆,offheap 384.0 MiB 是 JVM 直接内存额度,native 侧内存管理器据此划定预算。

grep -m1 "start executing plan:" smoke.err | cut -c1-200
2026-10-15 08:07:38.644 (+0.027s) [INFO] [auron::rt:155] (stage: 1, partition: 2, tid: 3) - start executing plan:

Rust 侧执行器真实启动的证据,(stage, partition, tid) 三元组标明是哪个 Spark task 的 native 执行实例。

grep -m1 "mem manager status" smoke.err
2026-10-15 08:07:39.539 (+0.922s) [INFO] [auron_memmgr:145] (stage: 0, partition: 0, tid: 0) - mem manager status: total: 230.4 MiB, mem_used: 0 B, jvm_direct: 385.1 KiB, proc resident: 850.0 MiB

auron_memmgr 的状态行给出 native 侧内存账本:预算 230.4 MiB(总内存 896.0 MiB × 预留系数)、实际 native 堆用量 mem_used、经 JNI 的直接内存 jvm_direct、进程常驻内存 proc resident。

3.2 为什么 EXPLAIN 里看不到 Native 节点

对同一查询执行 EXPLAIN,物理计划里并没有出现 NativeParquetScan 之类的节点(实测输出):

== Physical Plan ==
AdaptiveSparkPlan isFinalPlan=false
+- Sort [l_returnflag#16 ASC NULLS FIRST], true, 0
   +- Exchange rangepartitioning(l_returnflag#16 ASC NULLS FIRST, 200), ENSURE_REQUIREMENTS, [plan_id=63]
      +- HashAggregate(keys=[l_returnflag#16], functions=[count(1), sum(l_extendedprice#15)])
         +- Exchange hashpartitioning(l_returnflag#16, 200), ENSURE_REQUIREMENTS, [plan_id=60]
            +- HashAggregate(keys=[l_returnflag#16], functions=[partial_count(1), partial_sum(l_extendedprice#15)])
               +- FileScan parquet spark_catalog.default.demo_order[l_extendedprice#15,l_returnflag#16] Batched: true, ...

这是正常现象而非配置失效:Auron 不在优化器产物上做文本级替换,而是在物理计划执行准备阶段通过 Spark 的 injectColumnar 扩展点把可转换算子包成带 Columnar 实现的执行节点,序列化成 protobuf 后经 JNI 交给 Rust 侧 DataFusion 执行。EXPLAIN 打印的是转换前的原始物理计划,native 参与与否以 3.1 节日志为准。

3.3 关闭开关的 A/B 对照

用 --conf 在命令行覆盖总开关,即可在同一份数据上对照「native 参与 / 不参与」(实测):

/opt/spark/bin/spark-sql --driver-memory 512m --conf spark.auron.enable=false -f q1.sql
B       666667
C       666667
A       666666
grep -cE "Start executing native plan" q1-off.err
0

结果与开启时一致(正确性不受影响),但 native 执行条数为 0,证明开关确实把整条链路切回了 Spark JVM 执行。这一对照也是排查「升级后疑似变慢」的第一手段:先确认 native 日志条数没有归零。

四、fallback:不支持的算子如何回退

Auron 支持算子级、表达式级的细粒度回退:遇到尚未 native 化的表达式时,该表达式留在 JVM 执行,其余部分照常下沉 native。上节 CTAS 里 id * 1.01(decimal 与字面量相乘)就触发了一次真实回退,stderr 完整原文:

26/10/15 08:07:31 WARN NativeConverters: Falling back expression: scala.NotImplementedError: unsupported expression: (class org.apache.spark.sql.catalyst.expressions.Multiply) (cast(id#4 as decimal(10,0)) * 1.01)

要点解读:

  • 回退以 WARN NativeConverters: Falling back expression 为标志,级别是 WARN 不是 ERROR,查询正常完成——本例最终三行结果与纯 Spark(3.3 节开关关闭)完全一致。
  • 一次回退的代价是 JVM 与 native 之间多一次数据边界转换,个别算子回退可接受;大面积回退会让加速收益归零。生产上应把 Falling back 出现频次纳入巡检,并用 spark.auron.enable.* 系列开关把高频回退算子固定切回 JVM(配置键全表见配置详解篇)。
  • 8.0.0-incubating 对这条路径的定位是「fine-grained failback」:官方介绍明确支持大部分 native 算子/表达式与细粒度回退,UDF/UDTF 等场景即依赖该机制保持可运行。

五、加速方案选型参考

💡 技术拓展:Spark 生态里做「native 向量化加速」的不止 Auron 一家,主流开源方案对比如下——

方案技术底座接入方式许可/状态适用场景
Apache Auron(孵化中)Rust + Apache Arrow-DataFusion客户端扩展:改 spark-defaults.conf 即可Apache-2.0,Apache 孵化器已在生产级环境验证过 EB 级数据,TPC-DS 全案例通过,官方口径较 Spark 3.5 提速约 2 倍
Apache Gluten(孵化中)C++/JVM 混合,可对接 Velox/ClickHouse 后端插件 JAR + 配置Apache-2.0,Apache 孵化器需要多后端选择、已有 Velox 运维经验的团队
原生 Spark 3.5JVM + Tungsten无需接入Apache-2.0不想引入新组件、查询以小表为主
商业发行版(如 Photon)厂商内置 native 引擎随平台提供商业许可使用对应云平台且预算允许

本文采用 Apache Auron,理由:安装面小(一个 fat JAR + 五行配置,SQL 无需改写);回退机制细(表达式级 failback 保证兼容性);孵化状态虽新,但上游按 Apache 流程对 8.0.0-incubating 完成了源码签名发布(sha512 与 gpg 验证均实测通过)。

六、常见问题(FAQ)

Q1:查询报 UnsatisfiedLinkError ... GLIBC 怎么办? 完整实测报错(在 Ubuntu 22.04 上运行了更高 glibc 系统构建的 JAR):

java.lang.UnsatisfiedLinkError: /tmp/libauron-2949776914807434968.tmp: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by /tmp/libauron-2949776914807434968.tmp)

原因:JAR 内嵌的 libauron.so 在加载时由 JVM 解压到 /tmp/libauron-*.tmp 再 dlopen,它链接的 glibc 符号版本不能高于运行机。解法:在与运行环境一致(或 glibc 更低)的系统上执行源码构建,产出本机可用的 JAR 后替换 jars/ 里的旧包;构建步骤见安装指南。验证方法:grep -cE "UnsatisfiedLinkError" <stderr日志> 归零,且 Start executing native plan 条数恢复。

Q2:NativeHelper: memory 这行日志没出现,查询结果却是对的? 说明 Auron 扩展没有注入成功,查询全程跑在 JVM 上。按序检查:spark-defaults.conf 是否写入 spark.sql.extensions=org.apache.spark.sql.auron.AuronSparkSessionExtension;jars/ 里的 JAR 是否为构建机同 glibc 版本产物;命令行有没有 --conf spark.auron.enable=false 覆盖。三条都正常仍无效时,用 spark-submit --version 确认实际使用的 Spark 与 Scala 版本(3.5.x + 2.12)与 JAR 的 shim 匹配。

Q3:重跑脚本报 TABLE_OR_VIEW_ALREADY_EXISTS? spark-sql -f 的多条语句里 CREATE TABLE 不是幂等的,本地 derby 元数据(metastore_db)会把表持久化。把 DROP TABLE IF EXISTS demo_order; 放在脚本首行(本文 2.2 节写法),或临时换表名。实测报错原文:

[TABLE_OR_VIEW_ALREADY_EXISTS] Cannot create table or view `spark_catalog`.`default`.`demo_order` because it already exists.

Q4:本地单机模式跑,spark.executor.memory 调大没效果? local 模式下 Driver 即 Executor,生效的是 --driver-memory(本文实测 512m,native 日志行 onheap: 512.0 MiB 与之对应);JVM 等价写法是给 Driver 进程加 -Xms256m -Xmx256m 一类的堆参数,位置在 spark-env.sh 的 SPARK_DRIVER_MEMORY 或提交命令 --driver-memory,修改后以 NativeHelper: memory 日志行为准复核。集群模式才使用 spark.executor.memory 与 spark.executor.memoryOverhead(native 内存走 overhead,建议值见调优篇)。

Q5:8.0.0-incubating 名字里的 incubating 是什么意思,能用吗? 表示项目仍在 Apache 孵化器孵化期,尚未成为 ASF 顶级项目,版本号以 -incubating 后缀披露孵化状态。这影响的是 ASF 毕业评估而非代码可用性:8.0.0-incubating 按 Apache 发布流程完成了签名源码包与校验文件,本文从安装到查询的完整链路均在实测中通过。选型时需要知悉的风险是孵化期项目 API 与配套(如 Spark 支持范围)仍在快速演进。

七、参考链接

  1. Apache Auron 官方主页:https://auron.apache.org/
  2. 官方 Getting Started(Spark 集成配置出处):https://auron.apache.org/documents/getting-started.html
  3. 8.0.0-incubating 发行说明:https://auron.apache.org/archives/v8.0.0-incubating.html
  4. ASF 源码下载目录(含 KEYS 与 sha512):https://downloads.apache.org/incubator/auron/
  5. 官方配置项文档:https://auron.apache.org/documents/configuration.html
  6. Apache Spark 3.5.8 下载(含 sha512):https://downloads.apache.org/spark/spark-3.5.8/