Pyspark 不使用 TemporaryAWSCredentialsProvider

Posted

技术标签:

【中文标题】Pyspark 不使用 TemporaryAWSCredentialsProvider【英文标题】:Pyspark not using TemporaryAWSCredentialsProvider 【发布时间】:2018-08-09 19:05:30 【问题描述】:

我正在尝试使用 Pyspark 使用临时会话凭据从 S3 读取文件,但不断收到错误消息:

Received error response: com.amazonaws.services.s3.model.AmazonS3Exception: Status Code: 403, AWS Service: null, AWS Request ID: XXXXXXXX, AWS Error Code: null, AWS Error Message: Forbidden, S3 Extended Request ID: XXXXXXX

我认为问题可能是 S3A 连接需要使用org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider 才能在标准访问密钥和密钥之外提取会话令牌,但即使设置了fs.s3a.aws.credentials.provider 配置变量,它仍在尝试使用BasicAWSCredentialsProvider 进行身份验证。查看我看到的日志:

DEBUG AWSCredentialsProviderChain:105 - Loading credentials from BasicAWSCredentialsProvider

我已经按照here 的指示添加了必要的配置值,但它们似乎没有任何区别。这是我用来设置它的代码:

import os
import sys
import pyspark
from pyspark.sql import SQLContext
from pyspark.context import SparkContext

os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages com.amazonaws:aws-java-sdk-pom:1.11.83,org.apache.hadoop:hadoop-aws:2.7.3 pyspark-shell'

sc = SparkContext()
sc.setLogLevel("DEBUG")
sc._jsc.hadoopConfiguration().set("fs.s3a.aws.credentials.provider", "org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider")
sc._jsc.hadoopConfiguration().set("fs.s3a.access.key", os.environ.get("AWS_ACCESS_KEY_ID"))
sc._jsc.hadoopConfiguration().set("fs.s3a.secret.key", os.environ.get("AWS_SECRET_ACCESS_KEY"))
sc._jsc.hadoopConfiguration().set("fs.s3a.session.token", os.environ.get("AWS_SESSION_TOKEN"))
sql_context = SQLContext(sc)

为什么TemporaryAWSCredentialsProvider 没有被使用?

【问题讨论】:

这个问题是怎么解决的? 我还不能让它工作。我认为 wafle 的响应方向是正确的,但它仍然不适用于我的配置。如果我能解决它,我会多尝试一下并在此处发布。 在 core-site.xml 中设置变量并将文件复制到 spark conf 文件夹。使用上述设置对我有用 hadoop.apache.org/docs/current/hadoop-aws/tools/hadoop-aws/… 2.8 似乎可以解决问题。我使用没有 Hadoop 的 Spark 安装让它工作,然后将 SPARK_DIST_CLASSPATH 指向 Hadoop 类路径并在 PYSPARK_SUBMIT_ARGS 中使用 org.apache.hadoop:hadoop-aws:2.8.4。 【参考方案1】:

您使用的是哪个 Hadoop 版本?

S3A STS 支持在 Hadoop 2.8.0 中为 added,这是我在 Hadoop 2.7 上得到的确切错误消息。

【讨论】:

我只是在没有 Hadoop 的情况下运行 Spark,并且只是引入 Hadoop 依赖项以与 S3 交互,这可能是问题的一部分。我更新了我的包以使用 hadoop-aws:2.8.0,但收到错误 java.lang.IllegalAccessError: tried to access method org.apache.hadoop.metrics2.lib.MutableCounterLong.<init>(Lorg/apache/hadoop/metrics2/MetricsInfo;J)V from class org.apache.hadoop.fs.s3a.S3AInstrumentation。阅读arnon.me/2015/08/spark-parquet-s3 让我觉得我需要设置extraClassPath 值,但我不确定如何正确设置。 您还需要使用匹配的 hadoop-common 版本。 hadoop-aws jar 正在尝试访问旧版本中不存在的方法。【参考方案2】:

华夫饼是对的,它只有 2.8+。

但是您可能能够摆脱设置 AWS_ 环境变量并以这种方式获取会话机密,因为 AWS 环境变量支持早已存在,我认为会接AWS_SESSION_TOKEN

见AWS docs

【讨论】:

以上是关于Pyspark 不使用 TemporaryAWSCredentialsProvider的主要内容,如果未能解决你的问题,请参考以下文章

如何在 pyspark 中使用“不存在”的 SQL 条件?

在不使用 Dataproc 的情况下将 GCP 与 PySpark 连接

Pandas UDF (PySpark) - 不正确的类型错误

如何在 PySpark 中提取对长度敏感的特征而不使用 .toPandas() hack?

使用 pyspark 解析 JSON 时嵌套动态模式不起作用

使用 pyspark 将结构数组旋转到列中 - 不爆炸数组