Spark作业如何实现默认参数自动传递?
问题根因
调用dbutils.notebook.getContext.tags("jobId")、dbutils.notebook.getContext.tags("runId")失效,核心是这组API有严格的上下文限制:
- 仅在Notebook交互式运行、或作业类型为Notebook作业时能正常返回值
- 提交Jar包形式的Scala作业、或作业运行在非Notebook上下文时,tags集合中不存在这两个键,直接调用会抛出
NoSuchElementException - 部分旧版运行时中,runId对应的标签键名不是
runId,硬编码键名很容易取空值
实现方案
不需要作业创建者手动传参,无论用户配置作业时是否传入这两个参数,都能自动获取到对应值,两种实现路径均可以满足需求:
方案1:全局Spark配置注入(最稳定,全作业类型兼容)
在作业关联的集群配置中,提前配置全局默认Spark参数,直接映射平台自带的动态作业变量,作业启动时平台会自动替换为真实值,不受用户传参影响:
spark.custom.jobId {{job.id}} spark.custom.runId {{run.id}}
Scala代码中直接从Spark上下文读取即可,不需要依赖dbutils组件:
import org.apache.spark.sql.SparkSession val spark = SparkSession.builder().getOrCreate() val jobId = spark.conf.get("spark.custom.jobId") val runId = spark.conf.get("spark.custom.runId")
方案2:直接读取系统内置属性(零配置,兼容现有作业)
运行时启动作业进程时,默认会把作业ID、运行ID注入到JVM系统属性中,不需要提前做任何集群配置,直接在Scala代码中读取即可,Jar作业、Notebook作业都能生效:
// 读取系统内置属性,无额外依赖 val jobId = System.getProperty("spark.databricks.job.id") val runId = System.getProperty("spark.databricks.job.runId")
如果需要兼容本地调试场景,加个兜底值避免空指针即可:
val jobId = Option(System.getProperty("spark.databricks.job.id")).getOrElse("local_test") val runId = Option(System.getProperty("spark.databricks.job.runId")).getOrElse("local_test")
两种方案都不需要作业创建者手动传入JobId、RunId参数,平台层面自动完成值的注入,不会增加使用方的传参负担。
内容的提问来源于stack exchange,提问作者ConfusedDeveloper
相关产品推荐
相关产品推荐

