这是 Spark SQL Metrics 深度解析的三部曲:

什么是 SQL Metrics?

Spark SQL 的每个物理算子都可以定义 metrics——在查询执行过程中跟踪各种计数的指标。当你在 SQL 标签页点击一个查询,看到 “number of output rows: 5,000” 或 “peak memory: 512.0 MiB”,那些就是 SQL Metrics。

它们基于 Spark 的 AccumulatorV2 框架:每个任务更新自己的本地副本,任务完成后 Driver 进行聚合。

五种指标类型

1. Sum(createMetric

最简单的类型。所有任务的值求和为单一总计。

显示格式: 1,234,567

典型用途: 行数、文件数、分区数。

2. Size(createSizeMetric

用于字节量度。显示总计加上每任务的分布。

显示格式: total (min, med, max): 512.0 MiB (128.0 MiB, 128.0 MiB, 128.0 MiB)

典型用途: 峰值内存、Spill 大小、数据大小、Shuffle 字节数。

(min, med, max) 分布对于检测数据倾斜至关重要——如果 maxmedian 的 10 倍,说明有掉队任务。

3. Timing(createTimingMetric

用于毫秒级耗时。显示总计加上每任务分布。

显示格式: total (min, med, max): 5.0 s (100 ms, 1.2 s, 2.0 s)

典型用途: 聚合时间、排序时间、广播时间。

4. NsTiming(createNanoTimingMetric

与 Timing 相同但接受纳秒值,显示时自动转换为毫秒。

典型用途: Shuffle 写入时间。

5. Average(createAverageMetric

用于每任务平均值,显示平均值在各任务间的分布。

显示格式: avg (min, med, max): (1.2, 2.5, 6.3)

典型用途: 哈希探测效率。

如何解读 “total (min, med, max)” 格式

peak memory
total (min, med, max)
512.0 MiB (128.0 MiB, 128.0 MiB, 128.0 MiB (stage 3.0: task 36))
字段含义
total所有任务的总和
min最小的任务值
med中位数(第 50 百分位)
max最大的任务值,标注 (stage X: task Y)

负载均衡时: min ≈ med ≈ max

数据倾斜时: max » med——检查标注的那个任务

完整 SQL Metrics 参考

Scan 算子

指标显示名称类型算子
numOutputRowsnumber of output rowssum所有 Scan 算子
numFilesnumber of files readsumDataSourceScanExec
filesSizesize of files readsizeDataSourceScanExec
scanTimescan timetimingDataSourceScanExec
metadataTimemetadata timetimingDataSourceScanExec
pruningTimedynamic partition pruning timetimingDataSourceScanExec

聚合算子

指标显示名称类型算子
numOutputRowsnumber of output rowssum所有聚合算子
aggTimetime in aggregation buildtimingHashAggregateExec, ObjectHashAggregateExec, SortAggregateExec
peakMemorypeak memorysizeHashAggregateExec
spillSizespill sizesizeHashAggregateExec, ObjectHashAggregateExec
avgHashProbeavg hash probes per keyaverageHashAggregateExec

Join 算子

指标显示名称类型算子
numOutputRowsnumber of output rowssum所有 Join 算子
buildDataSizedata size of build sidesizeShuffledHashJoinExec
buildTimetime to build hash maptimingShuffledHashJoinExec
spillSizespill sizesizeSortMergeJoinExec

Sort 算子

指标显示名称类型算子
sortTimesort timetimingSortExec
peakMemorypeak memorysizeSortExec
spillSizespill sizesizeSortExec

Shuffle 写入

指标显示名称类型
dataSizedata sizesize
shuffleBytesWrittenshuffle bytes writtensize
shuffleRecordsWrittenshuffle records writtensum
shuffleWriteTimeshuffle write timensTiming

Shuffle 读取(AQEShuffleReadExec

指标显示名称类型
partitionDataSizepartition data sizesize
numCoalescedPartitionsnumber of coalesced partitionssum
numSkewedPartitionsnumber of skewed partitionssum
numSkewedSplitsnumber of skewed partition splitssum
fetchWaitTimefetch wait timetiming
remoteBytesReadremote bytes readsize
localBytesReadlocal bytes readsize

Broadcast Exchange

指标显示名称类型
dataSizedata sizesize
collectTimetime to collecttiming
buildTimetime to buildtiming
broadcastTimetime to broadcasttiming

Python UDF 算子

指标显示名称类型
pythonDataSentdata sent to Python workerssize
pythonDataReceiveddata returned from Python workerssize
pythonBootTimetime to start Python workerstiming
pythonInitTimetime to initialize Python workerstiming
pythonTotalTimetime to run Python workerstiming
pythonProcessingTimetime to execute Python codetiming

写入算子

指标显示名称类型
numFilesnumber of written filessum
numOutputByteswritten outputsize
taskCommitTimetask commit timetiming
jobCommitTimejob commit timetiming

MERGE INTO 算子

指标显示名称类型
numTargetRowsInsertedtarget rows insertedsum
numTargetRowsUpdatedtarget rows updatedsum
numTargetRowsDeletedtarget rows deletedsum
numTargetRowsCopiedtarget rows copied unmodifiedsum

有状态流处理算子

指标显示名称类型
numTotalStateRowsnumber of total state rowssum
stateMemorymemory used by statesize
allUpdatesTimeMstime to updatetiming
allRemovalsTimeMstime to removetiming
commitTimeMstime to commit changestiming

WholeStageCodegen 与指标范围

大多数算子被 WholeStageCodegen 融合成单一 JVM 方法。它们的行数指标(numOutputRows)各自准确,但没有各自的计时——因为它们作为一个编译函数执行。

代码生成管道之外有独立执行阶段并具有独立计时的算子:

  • SortExec(排序时间)
  • 聚合算子(聚合构建时间)
  • ShuffledHashJoinExec(Hash Table 构建时间)
  • BroadcastExchangeExec(收集/构建/广播时间)
  • ShuffleExchangeExec(Shuffle 写入时间)
  • Python UDF 算子(Python 工作器时间)
  • 有状态流处理算子(更新/删除/提交时间)

第二部分将深入 SQL Metrics 的内部实现机制(AccumulatorV2 生命周期),以及 AQE 如何利用 Shuffle 统计信息在运行时重写查询计划。第三部分将介绍 DataSource V2 CustomMetric 扩展 API、UI 渲染和 REST API。