从 Azure 数据块读取 Amazon S3 特定文件夹,无需公开访问存储桶

Posted

技术标签:

【中文标题】从 Azure 数据块读取 Amazon S3 特定文件夹,无需公开访问存储桶【英文标题】:Read Amazon S3 specific folder from Azure databricks without public access to the bucket 【发布时间】:2021-09-02 18:47:52 【问题描述】:

问题:从 databricks(pyspark) 访问 Amazon S3 存储桶中存在的特定目录内容

存储桶策略设置

    S3 存储桶不可公开访问 S3 存储桶内的目录被授予公共访问权限并包含 parquet 文件。

Azure 上的 Databricks 设置

    Databricks 运行时版本 8.3 Spark 版本 3.1.1

代码 sn-p:

    设置访问密钥和密钥为
sc._jsc.hadoopConfiguration().set("fs.s3n.awsAccessKeyId", access_key)
sc._jsc.hadoopConfiguration().set("fs.s3n.awsSecretAccessKey", secret_key)
    从目录中读取数据框中的数据
AWS_S3_BUCKET_NAME = BUCKET_NAME
 
read_df = spark.read \
    .format("parquet") \
    .option("header", "true") \
    .load("s3n:///".format(AWS_S3_BUCKET_NAME, directory_name))

access_key、secret_key、BUCKET_NAME 和 directory_name 是正确的值。

错误消息:服务:Amazon S3;状态码:403;错误代码:403禁止;

当 S3 存储桶不可公开访问时,是否需要设置任何属性以便使用 Azure 数据块从 S3 存储桶中读取特定目录内容?

【问题讨论】:

【参考方案1】:

执行此操作的理想方法是使用 AWS IAM 角色授予对存储桶的只读访问权限。基本阶段如下:

    为自己创建一个 IAM 角色。

    指定允许哪些用户从事该工作。

    创建一个授予角色只读访问权限的存储桶策略。

    使用 dbutils.fs.mount 命令,将存储桶挂载到 Databricks 文件系统。

    在构建 Databricks 集群时,提供 IAM 角色

access_key = dbutils.secrets.get(scope = "aws", key = "aws-access-key")
secret_key = dbutils.secrets.get(scope = "aws", key = "aws-secret-key")
encoded_secret_key = secret_key.replace("/", "%2F")
aws_bucket_name = "<aws-bucket-name>"
mount_name = "<mount-name>"

dbutils.fs.mount("s3a://%s:%s@%s" % (access_key, encoded_secret_key, aws_bucket_name), "/mnt/%s" % mount_name)
display(dbutils.fs.ls("/mnt/%s" % mount_name))

您可以在哪里访问文件:

df = spark.read.text("/mnt/%s/...." % MOUNT_NAME)

注意:当您使用密钥挂载 S3 存储桶时,所有用户都拥有对 S3 存储桶所有对象的读写权限。

【讨论】:

以上是关于从 Azure 数据块读取 Amazon S3 特定文件夹,无需公开访问存储桶的主要内容,如果未能解决你的问题,请参考以下文章

将 Azure BLOB 存储同步到 Amazon S3

使用 PySpark 从 Amazon S3 读取文本文件

读取 Amazon Kinesis Firehose 流写入 s3 的数据

将 Amazon S3 文件导入数据库

如何从不同于网络的本地文件中读取 InputStream 对象(通过 Amazon S3)?

Azure 数据块。从sql数据库读取数据的java错误