覆盖 AWS EMR 主节点上的默认 aws-sdk jar

Overriding default aws-sdk jar on AWS EMR master node

我 运行 遇到了 运行 我在 EMR 主节点上的应用程序的问题。需要访问一些1.11版本新增的AWS SDK方法。所有必需的依赖项都捆绑到一个 fat jar 中,应用程序在我的开发箱上按预期工作。

但是,如果应用程序在 EMR 主节点上执行,调用方法时会失败并出现 NoSuchMethodError 异常,在 AWS SDK ver 1.11+ 中添加,例如

java.lang.NoSuchMethodError:
 com.amazonaws.services.sqs.model.SendMessageRequest.withMessageDeduplicationId(Ljava/lang/String;)Lcom/amazonaws/services/sqs/model/SendMessageRequest;

我追踪到传递给 JVM 实例的类路径参数,由 spark-submit 启动:

-cp /usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf/:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/lib/spark/conf/:/usr/lib/spark/jars/*:/etc/hadoop/conf/

特别是,它会加载 /usr/share/aws/aws-java-sdk/aws-java-sdk-sqs-1.10.75.1.jar 而不是使用我的 fat jar 中的版本 1.11.77。

有没有办法强制 Spark 使用我需要的 AWS SDK 版本?

以下是我在尝试解决此问题时学到的知识。

默认 class 路径参数是使用 /etc/spark/conf/spark-defaults.conf 中的 spark.driver.extraClassPath 设置构造的。 spark.driver.extraClassPath 包含对旧版本 AWS SDK 的引用,它位于 /usr/share/aws/aws-java-sdk/*

为了使用较新版本的 AWS API,我将 jar 上传到我在主目录中创建的目录并在 --driver-class-path spark-submit 参数中指定它:

--driver-class-path '/home/hadoop/aws/*'