【问题标题】:Hadoop Streaming jar not found when submitting Google Dataproc Hadoop Job?提交 Google Dataproc Hadoop 作业时找不到 Hadoop Streaming jar?
【发布时间】:2019-01-02 15:52:30
【问题描述】:

当尝试以编程方式(从使用 dataproc 库的 Java 应用程序)提交 Hadoop MapReduce 作业时,该作业会立即失败。通过 UI 提交完全相同的作业时,它工作正常。

我已尝试通过 SSH 连接到 Dataproc 集群以确认文件存在、检查权限并更改了 jar 引用。还没有任何效果。

我得到的错误:

Exception in thread "main" java.lang.ClassNotFoundException: file:///usr/lib/hadoop-mapreduce/hadoop-streaming-2.8.4.jar
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at com.google.cloud.hadoop.services.agent.job.shim.HadoopRunClassShim.main(HadoopRunClassShim.java:18)
Job output is complete

当我在控制台中克隆失败的作业并查看 REST 等效项时,我看到的是:

POST /v1/projects/project-id/regions/us-east1/jobs:submit/
{
  "projectId": "project-id",
  "job": {
    "reference": {
      "projectId": "project-id",
      "jobId": "jobDoesNotWork"
    },
    "placement": {
      "clusterName": "cluster-name",
      "clusterUuid": "uuid"
    },
    "submittedBy": "service-account@project.iam.gserviceaccount.com",
    "jobUuid": "uuid",
    "hadoopJob": {
      "args": [
        "-Dmapred.reduce.tasks=20",
        "-Dmapred.output.compress=true",
        "-Dmapred.compress.map.output=true",
        "-Dstream.map.output.field.separator=,",
        "-Dmapred.textoutputformat.separator=,",
        "-Dmapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec",
        "-Dmapreduce.input.fileinputformat.split.minsize=268435456",
        "-Dmapreduce.input.fileinputformat.split.maxsize=268435456",
        "-mapper",
        "/bin/cat",
        "-reducer",
        "/bin/cat",
        "-inputformat",
        "org.apache.hadoop.mapred.lib.CombineTextInputFormat",
        "-outputformat",
        "org.apache.hadoop.mapred.TextOutputFormat",
        "-input",
        "gs://input/path/",
        "-output",
        "gs://output/path/"
      ],
      "mainJarFileUri": "file:///usr/lib/hadoop-mapreduce/hadoop-streaming-2.8.4.jar"
    }
  }
}

当我通过控制台提交作业时,它可以工作。该作业的 REST 等效项:

POST /v1/projects/project-id/regions/us-east1/jobs:submit/
{
  "projectId": "project-id",
  "job": {
    "reference": {
      "projectId": "project-id,
      "jobId": "jobDoesWork"
    },
    "placement": {
      "clusterName": "cluster-name,
      "clusterUuid": ""
    },
    "submittedBy": "user_email_account@email.com",
    "jobUuid": "uuid",
    "hadoopJob": {
      "args": [
        "-Dmapred.reduce.tasks=20",
        "-Dmapred.output.compress=true",
        "-Dmapred.compress.map.output=true",
        "-Dstream.map.output.field.separator=,",
        "-Dmapred.textoutputformat.separator=,",
        "-Dmapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec",
        "-Dmapreduce.input.fileinputformat.split.minsize=268435456",
        "-Dmapreduce.input.fileinputformat.split.maxsize=268435456",
        "-mapper",
        "/bin/cat",
        "-reducer",
        "/bin/cat",
        "-inputformat",
        "org.apache.hadoop.mapred.lib.CombineTextInputFormat",
        "-outputformat",
        "org.apache.hadoop.mapred.TextOutputFormat",
        "-input",
        "gs://input/path/",
        "-output",
        "gs://output/path/"
      ],
      "mainJarFileUri": "file:///usr/lib/hadoop-mapreduce/hadoop-streaming-2.8.4.jar"
    }
  }
}

我 ssh'ed 进入盒子并确认该文件实际上是存在的。我真正能看到的唯一区别是“submittedBy”。一个有效,一个无效。我猜这是一个权限问题,但我似乎无法说出在每种情况下从哪里获取权限。在这两种情况下,Dataproc 集群都是使用相同的服务帐号创建的。

查看我看到的集群上那个 jar 的权限:

-rw-r--r-- 1 root root  133856 Nov 27 20:17 hadoop-streaming-2.8.4.jar
lrwxrwxrwx 1 root root      26 Nov 27 20:17 hadoop-streaming.jar -> hadoop-streaming-2.8.4.jar

我尝试将 mainJarFileUri 从显式指向版本控制的 jar 更改为链接(因为它具有打开权限),但并没有真正期望它能够工作。但事实并非如此。

有没有更多 Dataproc 经验的人知道这里发生了什么,以及我该如何解决?

【问题讨论】:

  • 您能否添加失败作业尝试的gcloud dataproc jobs describe <jobid> 的输出,如果可能,添加您用于以编程方式构建作业设置的代码的 sn-p?

标签: hadoop-streaming google-cloud-dataproc


【解决方案1】:

在代码中很容易犯的一个常见错误是在您打算调用 setMainJarFileUri 时调用 setMainClass,反之亦然。您收到的java.lang.ClassNotFoundException 表明Dataproc 试图将该jarfile 字符串作为类名而不是jarfile 提交,因此Dataproc 认为您设置了main_class。您可能需要仔细检查您的代码,看看这是否是您遇到的错误。

在 GUI 中使用“克隆作业”隐藏此问题的原因是 GUI 试图通过提供一个用于设置 main_classmain_jar_file_uri 的文本框来更加用户友好,并推断它是否是jarfile 通过查看文件扩展名。因此,如果您在 main_class 字段中提交带有 jarfile URI 的作业并且它失败,那么您单击 clone 并提交新作业,GUI 将尝试智能并识别新作业实际上指定了一个 jarfile名称,因此将正确设置 JSON 请求中的 main_jar_file_uri 字段而不是 main_class

【讨论】:

  • 不好意思承认我们发现这是问题所在。非常感谢您的帮助。
  • 感谢您的更新,很高兴听到您成功了!无论如何,这对后代都有好处,因为在克隆作业时 UI 会自动填充正确的字段,这对于遇到这种情况的其他人来说可能是一个自然的混乱来源
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多