如何在Spark作业内部获取Dataproc提交作业的jobId
Dataproc作业内部获取平台Job ID的实现方式
Dataproc不会将平台层面生成的作业ID默认写入Spark Context的内置配置项,无法直接通过Spark Context原生属性读取该值,但可以通过以下两种稳定方案在作业运行时拿到对应ID:
方案1:读取节点内置元数据服务(通用无侵入方案)
Dataproc会在作业调度时,自动将当前作业的ID注入到作业运行节点(含Driver、Executor节点)的本地元数据服务中,作业代码不需要额外配置、也不需要外网访问权限,直接请求本地元数据接口即可获取,是最推荐的实现方式。
以Scala语言的Spark作业为例,读取代码如下:import scala.io.Source import java.net.URL import java.net.HttpURLConnection // 访问集群本地元数据服务,无外网开销 val metaUrl = new URL("http://metadata.google.internal/computeMetadata/v1/instance/attributes/dataproc_job_id") val conn = metaUrl.openConnection().asInstanceOf[HttpURLConnection] // 元数据服务要求携带固定标识头,否则会被拒绝访问 conn.setRequestProperty("Metadata-Flavor", "Google") val dataprocJobId = Source.fromInputStream(conn.getInputStream).mkString.trim方案2:提交作业时主动传入Job ID(适配自定义场景)
如果不想在代码里请求元数据接口,可以在调用gcloud、Dataproc API提交Spark作业时,提前拿到生成的Job ID,将其作为自定义Spark配置参数传入作业,作业运行时直接从SparkConf中读取即可。
提交作业时添加配置参数示例:gcloud dataproc jobs submit spark \ --cluster=<你的集群名> \ --region=<集群所在区域> \ --properties=spark.custom.dataproc.job.id=<当前提交的作业ID> \ --class=<你的作业主类> \ --jars=<你的作业jar包路径>作业内部读取配置的代码示例:
val spark = SparkSession.builder().getOrCreate() val dataprocJobId = spark.conf.get("spark.custom.dataproc.job.id")
注意:不要混淆Spark自身的
spark.app.id和Dataproc平台的Job ID,前者是Spark引擎为运行中的应用生成的内部标识,和Dataproc平台层面的作业ID不属于同一套命名体系,二者不能互相替代。
内容的提问来源于stack exchange,提问作者Shreya Singhal
相关产品推荐
相关产品推荐

