Amazon AWS S3

Slack Docker Pulls

本指南描述了将 Amazon AWS S3 配置为 Alluxio 底层存储系统的说明。 Amazon AWS S3,即 Amazon Simple Storage Service,是一种对象存储服务,提供行业领先的可扩展性、数据可用性、安全性和性能。 有关 Amazon AWS S3 的更多信息,请阅读其文档

先决条件

如果你还没有满足先决条件,在开始前请阅读先决条件

准备将Amazon AWS S3与Alluxio一起使用时,请遵循以下步骤。

<S3_BUCKET> 创建一个新的S3 bucket或者使用一个现存的bucket
<S3_DIRECTORY> 你想在容器中使用的目录,创建一个新目录,或者使用一个现有的目录。
<S3_ACCESS_KEY_ID> 用于对 AWS 发出的请求进行签名计算。请参阅如何获取Access Key ID 和Secret Access Key
<S3_SECRET_KEY> 用于对 AWS 发出的请求进行签名计算。请参阅如何获取Access Key ID 和Secret Access Key

基础设置

使用 挂载表操作 来增加一个新的挂载点, 指定Alluxio路径在其上创建挂载,指定S#的路径作为UFS URI。 密钥和配置选项也可以通过指定 --option 标志作为挂载命令的一部分来指定,如配置挂载点所述。

一个将 s3://<S3_BUCKET>/<S3_DIRECTORY> 挂载到 /s3 的示例命令:

bin/alluxio mount add --path /s3/ --ufs-uri s3://<S3_BUCKET>/<S3_DIRECTORY> \
  --option s3.accessKeyId=<S3_ACCESS_KEY_ID> --option s3.secretKey=<S3_SECRET_KEY>

请注意,如果您想挂载S# bucket的根,请在bucket名称后面添加一个斜杠(例如s3://S3_BUCKET/).

对于其他设置AWS凭证的方法,请参阅高级设置中的凭证章节。

高级设置

配置AWS SDK v2

在访问 S3 bucket时, 配置 AWS SDK v2。默认使用的版本是 v1。 如果您想将版本设置为 v2(该版本具有更好的内存管理和更高的吞吐性能, 请在 conf/alluxio-site.properties 文件中添加以下配置。

alluxio.underfs.s3.sdk.version=2

配置S3 Region

配置访问 S3 bucket时的 S3 Region,以提高性能。 否则,将启用全局 S3 bucket访问,这会引入额外的请求。 可以在 conf/alluxio-site.properties 中设置 S3 Region。

alluxio.underfs.s3.region=us-west-1

高级凭证设置

你可以用不同的方式指定凭证(credentials),优先级由高到低排列:

你可以使用多种不同的方式指定凭证,从高优先级到低优先级分别是:

  1. 作为挂载选项指定 s3a.accessKeyIds3a.secretKey
  2. 作为 Java 系统属性指定 s3a.accessKeyIds3a.secretKey
  3. alluxio-site.properties 中指定 s3a.accessKeyIds3a.secretKey
  4. 在 Alluxio 服务器上使用环境变量 AWS_ACCESS_KEY_ID 或者 AWS_ACCESS_KEY(两者之一即可)以及 AWS_SECRET_ACCESS_KEY 或者 AWS_SECRET_KEY(两者之一即可)
  5. 包含凭证的配置文件位于 ~/.aws/credentials
  6. 如果您使用的是 EC2 实例,则使用 AWS 实例配置凭证

当使用 AWS 实例配置文件提供凭证时:

  • 创建一个具有访问挂载存储桶权限的 IAM Role
  • 创建一个实例配置文件作为已定义 IAM role的容器
  • 使用创建的配置文件启动一个 EC2 实例

请注意,IAM role需要访问存储桶中的文件以及存储桶本身,以确定存储桶的所有者。 通过设置属性 alluxio.underfs.s3.inherit.acl=false 可以避免自动分配存储桶所有者。

有关更多详细信息,请参阅 Amazon 的文档

开启服务端加密

您可以对存储在 S3 中的数据进行加密。 加密仅对 S3 中静态数据有效,当客户端读取数据时将以解密形式传输。 请注意,启用此功能还会启用 HTTPS 以符合读取/写入对象的要求。

通过配置 conf/alluxio-site.properties 文件启用此功能:

alluxio.underfs.s3.server.side.encryption.enabled=true

DNS-Buckets

默认情况下,指向名为”mybucket”的bucket的请求将发送到名为”mybucket.s3.amazonaws.com”的主机。 您可以启用 DNS-Buckets 以使用路径风格的数据访问,例如:”http://s3.amazonaws.com/mybucket”,通过设置以下配置:

alluxio.underfs.s3.disable.dns.buckets=true

通过proxy访问S3

conf/alluxio-site.properties 中加入以下选项,用以支持使用proxy与S3交互:

alluxio.underfs.s3.proxy.host=<PROXY_HOST>
alluxio.underfs.s3.proxy.port=<PROXY_PORT>

<PROXY_HOST><PROXY_PORT> 需要用你的proxy的主机名和端口代替。

访问特定region的S3服务

如果你想访问一个特定region的AWS服务,而不是默认的us-east-1,在 conf/alluxio-site.properties 中修改下面的选项:

alluxio.underfs.s3.region=<S3_REGION>

如果你想访问AWS服务中特定region的一个特定的endpoint(类似于AWS VPC endpoint),在 conf/alluxio-site.properties 中修改下面的选项:

alluxio.underfs.s3.endpoint=<S3_ENDPOINT>
alluxio.underfs.s3.endpoint.region=<S3_ENDPOINT_REGION>

需要将上面的endpoint和region值更新为对应的特定region,而非全局默认region。 在设置后,alluxio.underfs.s3.region=<S3_REGION> 将不再生效。

使用一个非Amazon服务提供商

如果想使用一个非”s3.amazonaws.com”的S3服务提供商,修改 conf/alluxio-site.properties 中下面的选项:

alluxio.underfs.s3.endpoint=<S3_ENDPOINT>
alluxio.underfs.s3.endpoint.region=<S3_ENDPOINT_REGION>

<S3_ENDPOINT> 替换为您的 S3 服务的主机名和端口,例如:http://localhost:9000。 仅在使用非 s3.amazonaws.com 的提供者时使用此参数。

连接到 Oracle Cloud Infrastructure (OCI) 对象存储

endpoint和region值都需要被更新为使用non-home region。

alluxio.underfs.s3.endpoint=<S3_ENDPOINT>
alluxio.underfs.s3.endpoint.region=<S3_ENDPOINT_REGION>

所有的OCI对象存储region都需要使用 PathStyleAccess

alluxio.underfs.s3.disable.dns.buckets=true
alluxio.underfs.s3.inherit.acl=false

使用v2 S3签名

一些 S3 服务提供商仅支持 v2 签名。 对于这些 S3 提供商,您可以通过设置 alluxio.underfs.s3.signer.algorithmS3SignerType 来强制使用 v2 签名。

[实验性] S3 流式上传功能

由于 S3 作为对象存储的特性,文件上传时会被从客户端发送到Worker节点,并被存储在本地磁盘的临时目录中,默认在 close() 方法中被上传到S3。

要启用 S3 流式上传,您需要修改 conf/alluxio-site.properties 文件,添加以下内容:

alluxio.underfs.s3.streaming.upload.enabled=true

默认的上传过程更安全,但存在以下问题:

  • 上传时间慢。文件必须先发送到 Alluxio worker,然后由 Alluxio worker负责将文件上传到 S3。这两个过程是顺序执行的。
  • 临时目录必须有足够的容量来存储整个文件。
  • close() 方法执行缓慢。close() 方法的执行时间与文件大小成正比,与带宽成反比,即 O(FILE_SIZE/BANDWIDTH)。 close() 方法执行缓慢是预期之外的,并且已经成为 Alluxio FUSE 中的一个瓶颈。 Alluxio FUSE 方法调用 close() 是异步的,因此如果通过 Alluxio FUSE 将大文件写入 S3,FUSE 写操作会在文件实际写入 S3 之前很久就返回。

S3 流式上传功能解决了上述问题,并且基于 S3 低级别的分段上传

S3 流式上传具有以下优点:

  • 更快的上传时间:文件可以直接从客户端流式上传到 S3,而无需先发送到 Alluxio 工作节点。
  • 减少本地存储需求:无需在临时目录中存储整个文件,减少了对本地磁盘空间的需求。
  • 更快的 close() 方法:close() 方法执行时间大大缩短,因为文件的上传在写入过程中已经完成。

如果 S3 流式上传被中断,可能会有中间分段上传到 S3,并且 S3 将为这些数据收费。 为了减少费用,用户可以修改 conf/alluxio-site.properties 文件,添加以下内容:

alluxio.underfs.cleanup.enabled=true

所有非只读 S3 挂载点中超过clean age(由 alluxio.underfs.s3.intermediate.upload.clean.age 配置) 的中间分段上传文件将在达到清理时间间隔(由 alluxio.underfs.cleanup.interval 配置)时被清理。

[实验性] S3 多部分上传

默认的上传方法一次性从头到尾上传一个完整的文件。 我们使用分段上传方法将一个文件分成多个部分进行上传,每个部分将通过一个线程上传。上传过程中不会生成任何临时文件。 它会消耗更多内存,但比流式上传模式更快。

要启用 S3 分段上传,您需要修改 conf/alluxio-site.properties 文件,添加以下内容:

alluxio.underfs.s3.multipart.upload.enabled=true

可以在 conf/alluxio-site.properties 文件中指定其他参数,让上传过程更快更好。

# Timeout for uploading part when using multipart upload.
alluxio.underfs.object.store.multipart.upload.timeout
# Multipart upload partition size for S3. The default partition size is `64MB`
alluxio.underfs.s3.multipart.upload.partition.size

高并发调优

如果在每个 Alluxio server上使用大量client访问 S3,则可以下面调整这些参数,以开启Alluxio 使用针对 S3 的特定后端优化。

如果 S3 连接较慢,则可以尝试设置较大的超时时间:

alluxio.underfs.s3.socket.timeout=500sec
alluxio.underfs.s3.request.timeout=5min

如果需要大量并发元数据操作:

alluxio.underfs.s3.admin.threads.max=80

如果元数据+数据操作的总数很大:

alluxio.underfs.s3.threads.max=160

在worker端,这个参数的含义是worker到S3并发写的最大数量;在coordinator端,这个参数的含义是在一个文件夹中并发rename 文件的最大线程数。

alluxio.underfs.s3.upload.threads.max=80

这个参数的含义是在coordinator端提交delete和rename操作的线程池的大小。

alluxio.underfs.object.store.service.threads=80

S3 Objects的身份验证和访问控制

S3 的身份验证和访问管理 与传统的 POSIX 权限模型非常不同。 例如,S3 ACL 不支持组或目录级别的设置。 Alluxio 尽最大努力从 S3 ACL 信息中继承权限信息,包括文件所有者、组和权限模式(permission mode)。

为什么返回403 Access Denied Error

在 Alluxio 配置中设置的 S3 credentials 对应于一个 AWS 用户。 如果此用户没有访问 S3 bucket或object所需的权限,则将返回 403 permission denied错误。

如果在访问 S3 服务时在 Alluxio 服务器日志中看到 403 错误,请务必检查:

  1. 您是否使用了正确的 AWS credentials。请参阅 凭证设置.
  2. 您的 AWS 用户是否具有访问挂载到 Alluxio 的存储桶和对象的权限。

阅读更多关于 AWS 403 错误的故障排除指南

文件所有者和组

Alluxio 文件系统根据在 Alluxio 中配置的用于连接到 S3 的 AWS 账户设置文件所有者。 由于 S3 ACL 中没有组,因此所有者被设为文件的group。

默认情况下,Alluxio 提取此 AWS 账户的显示名称作为文件所有者。 如果此显示名称不可用,则将使用此 AWS 用户的规范用户 ID。 此规范用户 ID 通常是一个长字符串(例如 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be), 因此在实践中往往不方便阅读和使用。 可选地,属性 alluxio.underfs.s3.owner.id.to.username.mapping 可用于指定从规范用户 ID 到 Alluxio 用户名的预设映射,格式为 “id1=user1;id2=user2”。 例如,编辑 alluxio-site.properties 使之包含如下内容:

alluxio.underfs.s3.owner.id.to.username.mapping=\
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be=john

这个配置帮助 Alluxio 将所有由此 AWS 账户拥有的对象识别为 Alluxio 命名空间中的用户 john 拥有。 要找出您账户的 AWS S3 规范用户 ID,可以查看控制台 https://console.aws.amazon.com/iam/home?#/security_credentials, 展开 “Account Identifiers” 选项卡,然后参考 “规范用户 ID”。

修改权限

Alluxio目录和文件的 chown, chgrp, 和 chmod 不会被传递到底层的S3 buckets或者objects。

问题排查

启用 AWS-SDK 调试级别

如果在使用 S3 后端时遇到问题,可以启用额外的日志记录来跟踪 HTTP 流量。 修改 conf/log4j.properties 文件,添加以下属性:

log4j.logger.com.amazonaws=WARN
log4j.logger.com.amazonaws.request=DEBUG
log4j.logger.org.apache.http.wire=DEBUG

查阅Amazon文档查看详细情况。