Apache Gluten 常用 CLI 命令与工具详解

汇总 Apache Gluten 集成后 spark-submit、spark-shell、spark-sql 的常用命令与 --conf 用法,以及 EXPLAIN、计划变更日志、日志关键字等诊断命令与性能对比方法。

Apache GlutenApache Gluten2026/10/12

Apache Gluten 常用 CLI 命令与工具详解

Gluten 不提供独立命令行,它的“CLI”就是 Spark 自带的 spark-submit、spark-shell、spark-sql 等工具,再加上一组用于查看执行计划与原生执行情况的诊断手段。本文以 Apache Gluten 1.7.0 + Spark 3.5.5 + JDK 17 为基准,给出实用命令与真实回显。

一、通用约定

1.1 环境变量

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64   # CentOS 8 为 /usr/lib/jvm/java-17-openjdk
export PATH=$JAVA_HOME/bin:$PATH
export SPARK_HOME=/opt/spark
GLUTEN_JAR=/opt/gluten/gluten-velox-bundle-spark3.5_2.12-linux_amd64-1.7.0.jar
JVM_OPTS='--add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED -Dio.netty.tryReflectionSetAccessible=true'

JVM_OPTS 是 JDK 17 下的必需项,缺少会报 sun.misc.Unsafe or java.nio.DirectByteBuffer.<init>(long, int) not available。

1.2 最小 Gluten 配置组合

三个 --conf 加一个 --jars 即可启用:

--conf spark.plugins=org.apache.gluten.GlutenPlugin \
--conf spark.memory.offHeap.enabled=true \
--conf spark.memory.offHeap.size=1g \
--conf spark.shuffle.manager=org.apache.spark.shuffle.sort.ColumnarShuffleManager \
--jars $GLUTEN_JAR

二、spark-submit

2.1 提交 Scala/Java 作业

$SPARK_HOME/bin/spark-submit --master 'local[4]' --driver-memory 512m \
  --conf spark.plugins=org.apache.gluten.GlutenPlugin \
  --conf spark.memory.offHeap.enabled=true \
  --conf spark.memory.offHeap.size=1g \
  --conf spark.shuffle.manager=org.apache.spark.shuffle.sort.ColumnarShuffleManager \
  --conf "spark.driver.extraJavaOptions=$JVM_OPTS" \
  --conf "spark.executor.extraJavaOptions=$JVM_OPTS" \
  --jars $GLUTEN_JAR \
  --class com.example.GlutenAgg /opt/app/myapp.jar

2.2 提交 Python 作业

$SPARK_HOME/bin/spark-submit --master 'local[4]' --driver-memory 512m \
  --conf spark.plugins=org.apache.gluten.GlutenPlugin \
  --conf spark.memory.offHeap.enabled=true \
  --conf spark.memory.offHeap.size=2g \
  --conf spark.shuffle.manager=org.apache.spark.shuffle.sort.ColumnarShuffleManager \
  --jars $GLUTEN_JAR /opt/app/job.py

2.3 常用参数速查

参数说明
--master集群/本地模式,如 local[4]、yarn
--driver-memoryDriver 堆内存,示例用 512m
--executor-memoryExecutor 堆内存
--jars分发 Gluten bundle 到 Driver/Executor
--conf传入任意 Spark/Gluten 配置
--version查看 Spark 版本

三、spark-shell

3.1 启动并验证插件

# $SPARK_HOME/bin/spark-shell --master 'local[4]' --driver-memory 512m \
    --conf spark.plugins=org.apache.gluten.GlutenPlugin \
    --conf spark.memory.offHeap.enabled=true \
    --conf spark.memory.offHeap.size=1g \
    --conf spark.shuffle.manager=org.apache.spark.shuffle.sort.ColumnarShuffleManager \
    --jars $GLUTEN_JAR
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 3.5.5
      /_/
Using Scala version 2.12.18, OpenJDK 64-Bit Server VM, 17.0.20.1
scala>

在 REPL 中确认插件与内存配置:

scala> spark.conf.get("spark.plugins")
res0: String = org.apache.gluten.GlutenPlugin

scala> spark.conf.get("spark.memory.offHeap.size")
res1: String = 1g

3.2 脚本模式

把 Scala 语句写入文件后用 -i 执行(末尾 sys.exit(0) 退出):

$SPARK_HOME/bin/spark-shell --master 'local[4]' --driver-memory 512m \
  --conf spark.plugins=org.apache.gluten.GlutenPlugin \
  --conf spark.memory.offHeap.enabled=true --conf spark.memory.offHeap.size=2g \
  --jars $GLUTEN_JAR -i /root/perf.scala

四、spark-sql

4.1 执行 SQL 文件

echo "SELECT count(*) AS cnt, sum(id) AS s FROM range(1000000);" > /root/test.sql
$SPARK_HOME/bin/spark-sql --master 'local[4]' --driver-memory 512m \
  --conf spark.plugins=org.apache.gluten.GlutenPlugin \
  --conf spark.memory.offHeap.enabled=true --conf spark.memory.offHeap.size=1g \
  --conf spark.shuffle.manager=org.apache.spark.shuffle.sort.ColumnarShuffleManager \
  --jars $GLUTEN_JAR -f /root/test.sql

真实回显:

1000000 499999500000

4.2 执行单条语句

$SPARK_HOME/bin/spark-sql ... -e "SELECT count(*) FROM range(100)"

五、执行计划与诊断

5.1 EXPLAIN 系列

spark-sql> EXPLAIN EXTENDED SELECT count(*) AS cnt, sum(id) AS s FROM range(1000000);
spark-sql> EXPLAIN COST SELECT count(*) FROM range(1000000);
spark-sql> EXPLAIN FORMATTED SELECT count(*) FROM range(1000000);

关键点:AQE 开启时初始物理计划仍显示朴素 Spark 算子(AdaptiveSparkPlan isFinalPlan=false 下的 HashAggregate、Exchange、Range)。要直观看到原生算子,需临时关闭 AQE:

--conf spark.sql.adaptive.enabled=false

关闭后可见:

== Physical Plan ==
VeloxColumnarToRow
+- ^(2) HashAggregateTransformer(keys=[], functions=[count(1), sum(id#7L)], isStreamingAgg=false, ...)
   +- ColumnarExchange SinglePartition, ENSURE_REQUIREMENTS, ... , [shuffle_writer_type=hash], ...
      +- VeloxResizeBatches 1024, 2147483647, 10485760
         +- ColumnarRange 0, 1000000, 1, 4, 1000000, [id#7L]

只要出现 VeloxColumnarToRow、HashAggregateTransformer、ColumnarExchange、ColumnarRange 等节点,即说明算子已被原生引擎接管。

5.2 计划变更日志

打开 Spark 的计划变更日志,观察 Gluten 的列式转换是否发生:

--conf spark.sql.planChangeLog.level=WARN \
--conf spark.sql.planChangeLog.rules=org.apache.spark.sql.execution.columnar.*

5.3 日志关键字排查

把 org.apache.gluten 日志级别设为 INFO(在 $SPARK_HOME/conf/log4j2.properties 中追加):

logger.gluten.name = org.apache.gluten
logger.gluten.level = info

启动后检索以下关键字:

关键字含义
GlutenDriverPlugin: Gluten components插件已加载,列出各组件
SubstraitBackend: Gluten build info打印 Gluten/Java/Scala/Spark 版本
Successfully loaded library linux/amd64/libgluten.so原生主库加载成功
Successfully loaded library linux/amd64/libvelox.soVelox 库加载成功
Gluten is running with Spark local mode本地模式下的提示
Gluten SQL Tab has been attachedSpark UI 已挂载 Gluten 页签
Excluding runtime-incompatible component: velox-iceberg相关依赖缺失的正常告警
# 在作业日志中过滤
grep -iE 'gluten|velox' /tmp/gluten_run.log

5.4 Spark UI

启用 Gluten 后,Web UI 会额外出现 “Gluten SQL” 页签,可查看原生执行相关的统计与算子树。

六、性能对比命令

6.1 计时脚本

用 spark-shell -i 跑同一查询多轮,取稳定值(去掉冷启动轮次):

spark.sparkContext.setLogLevel("ERROR")
val q2 = "SELECT count(*) AS c FROM range(8000000) a JOIN range(8000000) b ON a.id = b.id"
for (i <- 1 to 3) {
  val t0 = System.nanoTime()
  val r  = spark.sql(q2).collect()
  val t1 = System.nanoTime()
  println("ITER=" + i + " ELAPSED_MS=" + ((t1 - t0) / 1000000) + " RESULT=" + r(0))
}
sys.exit(0)

分别以“带 Gluten 参数”和“不带 Gluten 参数”各跑一次,即可对比。

6.2 实测对照

环境:Spark 3.5.5 / JDK 17 / local[4] / driver 512m / offHeap 2g。

查询Gluten 开启Gluten 关闭
Q1 字符串聚合(2000 万行)2105 ms793 ms
Q2 自连接聚合(800 万 × 800 万)1479 ms4348 ms

结论:Q2 这类连接/Shuffle 密集型负载,Gluten 约快 2.9×;Q1 这类轻量字符串聚合,原生 Spark codegen 反而更快。Gluten 的收益强依赖工作负载形态,简单查询会因 JNI 与列式搬运产生额外开销。

七、命令速查表

目的命令要点
查看 Spark 版本spark-submit --version
启用 Gluten--conf spark.plugins=org.apache.gluten.GlutenPlugin --jars $GLUTEN_JAR
预留原生内存--conf spark.memory.offHeap.enabled=true --conf spark.memory.offHeap.size=1g
列式 Shuffle--conf spark.shuffle.manager=org.apache.spark.shuffle.sort.ColumnarShuffleManager
查看原生计划EXPLAIN EXTENDED ... + --conf spark.sql.adaptive.enabled=false
计划变更日志--conf spark.sql.planChangeLog.level=WARN
查看 Gluten 日志`grep -iE 'gluten
性能对比spark-shell -i + System.nanoTime() 多轮计时