从 Google 的 dataproc 中读取 S3 数据

Posted

技术标签:

【中文标题】从 Google 的 dataproc 中读取 S3 数据【英文标题】:Reading S3 data from Google's dataproc 【发布时间】:2016-09-07 19:24:10 【问题描述】:

我正在通过 Google 的 dataproc 在我创建的集群上运行 pyspark 应用程序。在一个阶段,应用程序需要访问 Amazon S3 目录中的目录。在那个阶段,我得到了错误:

AWS 访问密钥 ID 和秘密访问密钥必须分别指定为 s3 URL 的用户名或密码,或者通过设置 fs.s3.awsAccessKeyId 或 fs.s3.awsSecretAccessKey 属性(分别)。

我登录到集群的头节点并使用我的 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 信息设置 /etc/boto.cfg,但这并没有解决访问问题。

(1) 有关如何从 dataproc 集群访问 AWS S3 的任何其他建议?

(2) 另外,dataproc 用来访问集群的用户名是什么?如果我知道这一点,我可以在集群上为该用户设置 ~/.aws 目录。

谢谢。

【问题讨论】:

您是为了使用awscli 之类的东西而放弃工作,还是通过普通的 Spark/Hadoop 文件系统接口访问 S3? 通过普通 spark 接口访问 s3。我基本上想设置 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 然后执行 sc.textFile(s3_path) 并获取计数 【参考方案1】:

由于您使用的是 Hadoop/Spark 接口(例如 sc.textFile),因此确实应该通过 fs.s3.*fs.s3n.*fs.s3a.* 键完成所有操作,而不是尝试通过任何 ~/.aws/etc/boto.cfg 设置。您可以通过以下几种方式将这些设置应用于您的 Dataproc 集群:

在集群创建时:

gcloud dataproc clusters create --properties \
    core:fs.s3.awsAccessKeyId=<s3AccessKey>,core:fs.s3.awsSecretAccessKey=<s3SecretKey> \
    --num-workers ...

此处的core 前缀表示您希望将设置放在core-site.xml 文件中,如Cluster Properties documentation 中所述。

或者,在提交作业时,如果您使用 Dataproc 的 API:

gcloud dataproc jobs submit pyspark --cluster <your-cluster> \
    --properties spark.hadoop.fs.s3.awsAccessKeyId=<s3AccessKey>,spark.hadoop.fs.s3.awsSecretAccessKey=<s3SecretKey> \
    ...

在这种情况下,我们将属性作为 Spark 属性传递,Spark 提供了一种方便的机制来将“hadoop”conf 属性定义为 Spark conf 的子集,只需使用 spark.hadoop.* 前缀即可。如果您通过 SSH 在命令行提交,则相当于:

spark-submit --conf spark.hadoop.fs.s3.awsAccessKeyId=<s3AccessKey> \
    --conf spark.hadoop.fs.s3.awsSecretAccessKey=<s3SecretKey>

最后,如果您想在创建集群时进行设置,但不想在 Dataproc 元数据中明确设置访问密钥,您可以选择改用 initialization action。有一个名为 bdconfig 的便捷工具应该出现在您可以轻松修改 XML 设置的路径上:

#!/bin/bash
# Create this shell script, name it something like init-aws.sh
bdconfig set_property \
    --configuration_file /etc/hadoop/conf/core-site.xml \
    --name 'fs.s3.awsAccessKeyId' \
    --value '<s3AccessKey>' \
    --clobber
bdconfig set_property \
    --configuration_file /etc/hadoop/conf/core-site.xml \
    --name 'fs.s3.awsSecretAccessKey' \
    --value '<s3SecretKey>' \
    --clobber

将它上传到某个地方的 GCS 存储桶,并在集群创建时使用它:

gsutil cp init-aws.sh gs://<your-bucket>/init-aws.sh
gcloud dataproc clustres create --initialization-actions \
    gs://<your-bucket>/init-aws.sh

虽然 Dataproc 元数据确实像任何其他用户数据一样在静态时经过加密并且受到高度保护,但使用 init 操作有助于防止在查看您的 Dataproc 集群属性时不小心将您的访问密钥/秘密显示给站在您屏幕后面的人。

【讨论】:

【参考方案2】:

您可以尝试设置 AWS 配置,同时初始化 sparkContext。

conf = < your SparkConf()>
sc = SparkContext(conf=conf)
sc.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", <s3AccessKey>)
sc.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", <s3SecretKey>)

【讨论】:

我得到错误:AttributeError:'SparkContext'对象没有属性'hadoopConfiguration'。这项工作是没有 hadoop 的 spark 工作。有没有办法在没有 hadoop 的情况下设置这个配置?

以上是关于从 Google 的 dataproc 中读取 S3 数据的主要内容,如果未能解决你的问题,请参考以下文章

来自 DataProc 集群的 Google Cloud Sdk

Google Cloud Dataproc 上的 Pyspark 作业失败

在 google-dataproc 的 Spark 集群中的 pyspark 作业中使用外部库

如何在 Google Cloud Platform 上查看 Dataproc 作业的输出文件

暂停 Dataproc 集群 - Google 计算引擎

如何将 Spark-BigQuery_connector 用于现有的 spark 环境(不使用 google dataproc)