【问题标题】:Where should I put jars on a dataproc cluster so they can be used by gcloud dataproc jobs submit spark?我应该在哪里将 jar 放在 dataproc 集群上,以便 gcloud dataproc 作业提交 spark 使用它们?
【发布时间】:2026-01-08 19:25:03
【问题描述】:

我有一个初始化脚本,它从我们的本地人工制品存储库下载一个 .jar,并将其放入集群上每个节点上的 /usr/local/bin。我可以使用

运行它
gcloud dataproc jobs submit spark --cluster=my_cluster \
      --region=us-central1 --jar=file:///usr/local/bin/myjar.jar -- arg1 arg2

但是,如果我的最终用户不必知道 jar 的位置,我会更喜欢它。

我可以将 .jar 放在哪里,这样就不必指定它的位置?

【问题讨论】:

    标签: google-cloud-dataproc


    【解决方案1】:

    对于 spark 作业,您应该能够将 jarfile 放在所有节点上的 /usr/lib/spark/jars 中,以便在类路径中自动可用。

    要获得更广泛的报道,您可以将您的 jars 添加到 /usr/lib/hadoop/lib; hadoop lib 目录也自动包含在 Dataproc 上的 Spark 作业中,并且是 GCS 连接器 jarfile 等库所在的位置。您可以通过/etc/spark/conf/spark-env.sh 中配置的SPARK_DIST_CLASSPATH 环境变量看到hadoop lib 目录。

    如果所需的行为仍然是指定使用--jar 标志来指定“主jar”而不是--jars 来指定仅提供类的库jar,不幸的是目前没有“工作目录”的概念只允许指定“主 jar”的相对(而不是绝对)路径的集群。但是,有两种方法会产生类似的行为:

    1. 将 jarfile 设置为提交作业的用户工作区的本地文件 - gcloud 将在作业提交时将 jarfile 上传到 GCS,并在作业特定目录中运行时将作业指向 jarfile。请注意,这会导致每次作业运行时将 jarfile 重复上传到 GCS,因为它总是暂存到唯一的作业目录中;稍后您必须 gcloud dataproc jobs delete 清理这些 jarfile 使用的 GCS 空间
    2. (首选方法):使用--class 而不是--jar 参数来指定在执行上述步骤后要运行的作业以使jar 已经在Spark 类路径中可用。虽然类名的调用有点冗长,但它仍然实现了向用户隐藏 jarfile 位置的详细信息的目标。

    例如,用于“spark-shell”实现的类已经在类路径中,所以如果您想像通过spark-shell 运行它一样运行 scala 文件,您可以运行:

    gcloud dataproc jobs submit spark --cluster my-cluster \
        --class org.apache.spark.repl.Main \
        -- -i myjob.scala
    

    【讨论】:

    • 我假设 ${SPARK_HOME} 返回 /usr/lib/spark ?
    • 刚刚测试了这个假设,这是一个错误的假设。我猜我只是硬编码 /usr/lib/spark
    • 对不起@dennis-huo,我很难让这个工作。我将罐子放在/usr/lib/spark/jars 中,我知道 Spark 知道它们是因为我在提交工作时看到的日志消息,但是我仍然不得不使用gcloud dataproc jobs submit --cluster mycluster --jar file:///usr/lib/spark/jars/myjar.jar 中的整个路径我错过了什么?
    • 哦,我错过了您将它用作“主 jar”的事实,而不仅仅是一个库 jar。您是否希望用户仍然必须指定 jarfile 名称,而不是它所在的目录?或者提交作业而无需指定任何 jarfile?
    • 啊,我明白了。不幸的是,对于提交到集群的所有作业,没有单一“工作目录”的概念,您可以在其中为预先存在的 jar 指定相对路径。与您所描述的最接近的两种方法是: 1. Jarfiles 是用户工作区的本地文件 - 然后 gcloud 在作业提交时自动上传到 GCS 并将 jarfile 指向特定于作业的目录。 2. 使用--class 而不是--jar。我会将这些添加到答案中。
    最近更新 更多