Amazon AWS S3

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

还支持与 S3 兼容的存储。有关具体示例,请参阅与 S3 兼容的存储

先决条件

在开始之前,请确保您已具备下列所需信息:

在使用 Amazon AWS S3 和 Alluxio 之前:

<S3_BUCKET>

创建一个新的 S3 存储桶 或使用现有的存储桶

<S3_DIRECTORY>

您希望在该容器中使用的目录,可以通过创建新目录或使用现有目录来实现。

<S3_ACCESS_KEY_ID>

用于对向 AWS 发出的编程请求进行签名。请参阅如何获取访问密钥 ID 和秘密访问密钥

<S3_SECRET_KEY>

用于对向 AWS 发出的编程请求进行签名。请参阅如何获取访问密钥 ID 和秘密访问密钥

基本设置

使用挂载表示例添加新的挂载点,指定创建挂载的 Alluxio 路径和作为 UFS URI 的 S3 路径。凭据和配置选项也可以作为挂载操作的一部分指定,如配置挂载点中所述。

使用 operator 创建挂载点的 ufs.yaml 示例:

apiVersion: k8s-operator.alluxio.com/v1
kind: UnderFileSystem
metadata:
  name: alluxio-s3
  namespace: alx-ns
spec:
  alluxioCluster: alluxio-cluster
  path: s3://<S3_BUCKET>/<S3_DIRECTORY>
  mountPath: /s3
  mountOptions:
    s3a.accessKeyId: <S3_ACCESS_KEY_ID>
    s3a.secretKey: <S3_SECRET_KEY>
    alluxio.underfs.s3.region: <S3_REGION>

如果不使用 operator,将 s3://<S3_BUCKET>/<S3_DIRECTORY> 挂载到 /s3 的示例命令:

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

请注意,如果要挂载 S3 存储桶的根目录,请在存储桶名称后添加一个尾随斜杠(例如 s3://S3_BUCKET/)。

有关设置 AWS 凭据的其他方法,请参阅高级设置中的凭据部分。

高级设置

请注意,配置选项可以指定为挂载选项或 conf/alluxio-site.properties 中的配置属性。以下部分将介绍如何将配置设置为属性,但它们也可以通过 --option <key>=<value> 设置为挂载选项。

配置 AWS SDK v1

配置访问 S3 存储桶时使用的 AWS SDK 版本。默认使用的版本是 v2。如果要将版本设置为 v1,请在 conf/alluxio-site.properties 中添加以下配置

alluxio.underfs.s3.sdk.version=1

请注意,AWS SDK v2 具有更好的内存管理和更高的吞吐量性能。

配置 S3 区域

配置访问 S3 存储桶时的 S3 区域将提高性能。否则,将启用全局 S3 存储桶访问,这会引入额外的请求。S3 区域可以通过属性 alluxio.underfs.s3.region 进行设置。

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

请注意,如果设置了 S3 端点,则此属性将被忽略,而使用特定于端点的区域属性。

高级凭据设置

您可以按从高到低的优先级以不同方式指定凭据:

  1. 作为挂载选项指定的 s3a.accessKeyIds3a.secretKey

  2. 作为 Java 系统属性指定的 s3a.accessKeyIds3a.secretKey

  3. alluxio-site.properties 中的 s3a.accessKeyIds3a.secretKey

  4. Alluxio 服务器上的环境变量 AWS_ACCESS_KEY_IDAWS_ACCESS_KEY(两者均可接受)和 AWS_SECRET_ACCESS_KEYAWS_SECRET_KEY(两者均可接受)

  5. ~/.aws/credentials 中包含凭据的配置文件

  6. 如果您使用的是 EC2 实例,则为 AWS 实例配置文件凭据

当使用 AWS 实例配置文件作为凭据提供程序时:

  • 创建一个具有访问已挂载存储桶权限的 IAM 角色

  • 创建一个实例配置文件作为已定义 IAM 角色的容器

  • 使用创建的配置文件启动 EC2 实例

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

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

HTTPS/HTTP 访问

默认情况下,Alluxio 使用 HTTPS 协议与 S3 进行安全通信。如果需要禁用 SSL 证书验证和 SSL 主机名验证,请配置以下属性:

alluxio.underfs.s3.secure.http.trust.all.certs=true

如果要使用 HTTP 协议与 S3 通信,请配置以下属性:

alluxio.underfs.s3.secure.http.enabled=false

启用服务器端加密

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

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

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

DNS-Buckets

默认情况下,针对名为“mybucket”的存储桶的请求将发送到主机名“mybucket.s3.amazonaws.com”。您可以通过设置以下配置来启用 DNS-Buckets 以使用路径样式数据访问,例如:“http://s3.amazonaws.com/mybucket”:

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

通过代理访问 S3

要通过代理与 S3 通信,请修改 conf/alluxio-site.properties 以包含:

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

<PROXY_HOST><PROXY_PORT> 应替换为代理的主机和端口。默认情况下,使用 HTTPS 协议访问代理;如果代理仅支持 HTTP,请确保设置 alluxio.underfs.s3.secure.http.enabled=false

指定端点

如果要访问特定端点(例如 AWS VPC 端点),请修改 conf/alluxio-site.properties 以包含:

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

端点和区域值都需要设置。请注意,设置端点后,alluxio.underfs.s3.region=<S3_REGION> 将不再生效。

对于非 Amazon 服务提供商,请将 S3 服务的主机名和端口设置为 <S3_ENDPOINT>

使用 v2 S3 签名

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

[实验性] S3 流式上传

S3 是一个对象存储,由于此功能,整个文件从客户端发送到 worker,存储在本地磁盘临时目录中,并默认在 close() 方法中上传。

要启用 S3 流式上传,您需要修改 conf/alluxio-site.properties 以包含:

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

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

  • 上传时间慢。文件必须先发送到 Alluxio worker,然后 Alluxio worker 负责将文件上传到 S3。这两个过程是顺序的。

  • 临时目录必须有足够的容量来存储整个文件。

  • close() 速度慢。close() 方法的执行时间与文件大小成正比,与带宽成反比。即 O(FILE_SIZE/BANDWIDTH)。

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

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

  • 上传时间更短。Alluxio worker 在接收新数据的同时上传缓冲数据。总上传时间至少与默认方法一样快。

  • 容量要求更小。我们的数据根据分区(默认为 64MB 的 alluxio.underfs.s3.streaming.upload.partition.size)进行缓冲和上传。当一个分区成功上传后,该分区将被删除。

  • close() 速度更快。我们在缓冲数据达到分区大小时开始上传数据,而不是在 close() 中上传整个文件。

如果 S3 流式上传中断,可能会有中间分区上传到 S3,S3 将对存储的数据收费。为了减少费用,用户可以修改 conf/alluxio-site.properties 以包含:

alluxio.underfs.cleanup.enabled=true

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

S3 分段上传

我们使用分段上传方法通过多个部分上传一个文件,每个部分将在一个线程中上传。上传时不会生成任何临时文件。它会消耗更多内存,但比流式上传模式更快

您可以在 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 `16MB`
alluxio.underfs.s3.multipart.upload.partition.size

禁用 S3 分段上传,上传方法会一次性从头到尾完整上传一个文件。您需要修改 conf/alluxio-site.properties 以包含:

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

设置请求重试策略

有时访问 UFS 可能会出错,因为服务器暂时无法响应。您可以为 UFS 请求配置重试策略。

发送到 UnderFS 的每个请求,如 getObjectData、getObjectStatus、listObjects,Alluxio 都会检查响应。如果响应是错误,并且错误代码表明可以重试,则会根据配置中的重试策略重新提交请求。Alluxio 将继续尝试,直到请求成功或达到最大重试次数。连续重试之间的等待间隔将从配置的基本睡眠时间逐渐增加到最大睡眠时间。

以下错误代码被归类为可重试:500 HTTP_INTERNAL_ERROR502 HTTP_BAD_GATEWAY503 HTTP_UNAVAILABLE503 Slow Down504 HTTP_GATEWAY_TIMEOUT

注意:

  • 4xx 状态码通常表示客户端错误,例如 NOT_FOUND、PERMISSION_DENIED、UNAUTHENTICATED 等。此类错误不应重试,因为问题出在客户端。

  • 5xx 状态码通常表示服务器错误,但并非所有 5xx 错误都应重试。例如,501 HTTP_NOT_IMPLEMENTED 不应重试。

如果要为 UFS 访问请求设置重试策略,您需要修改 conf/alluxio-site.properties 以包含:

# the max number of retry in one UnderFS accessing request.
alluxio.underfs.business.retry.max.num=10

# the sleep time between the two retries after the initial failure
alluxio.underfs.business.retry.base.sleep=30ms

# the max sleep time between two retries
alluxio.underfs.business.retry.max.sleep=30s

设置更长的超时时间

如果 S3 连接速度慢,设置更长的超时时间会很有用:

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

针对高并发进行调整

当通过 Alluxio 以大量客户端访问 S3 时,每个 Alluxio 服务器,增加 S3 连接池大小以避免性能问题非常重要。如果连接池大小太小,可能会导致 S3 请求失败,并出现诸如“无法执行 HTTP 请求:等待池中连接超时”之类的错误,这是由于对可用连接的高度竞争造成的。增加池大小可通过设置以下内容确保更顺畅的通信和最佳性能:

alluxio.underfs.s3.connections.max=2048

使用面包屑优化元数据列表

与传统文件系统不同,许多对象存储没有目录的本机概念。常见的文件系统操作(例如检查目录是否存在、检索目录元数据或遍历目录)必须转换为基于前缀的对象列表操作。

当目录包含大量对象并且缺少目录占位符对象(以目录名称为前缀的零大小对象,称为“面包屑”)时,这些操作的成本可能会显着增加。为了减轻这种开销,通常会引入占位符对象来显式表示目录,从而提高与目录相关的元数据操作的性能。

Alluxio 提供了一个选项,通过使用“面包屑”对象来减轻这种开销,这些对象充当表示目录的轻量级占位符。默认情况下,Alluxio 会主动在 UFS 中创建面包屑对象来表示目录。要禁用此功能,请设置以下配置:

alluxio.underfs.object.store.breadcrumbs.enabled=false

面包屑具有以下优点:

  • 提高性能:一旦创建了面包屑,就可以有效地访问目录元数据,避免重复的完整列表扫描。

  • 缓存协同作用:与元数据缓存和预加载策略配合良好,以优化冷启动行为。

面包屑有以下几点需要考虑:

  • 需要写权限:启用此功能需要对对象存储的写访问权限。

  • 潜在的数据影响:关心数据纯度或对象存储外部修改的用户可能希望禁用它。

  • 冷加载开销:创建面包屑对象时,初始目录加载可能会产生一次性写入成本。

建议:

  • 如果 UFS 允许写入并且您正在优化性能(尤其是在列表性能较差的对象存储中),请启用。

  • 如果 UFS 是只读的,或者出于合规性或审计原因不允许修改 UFS,请禁用。

S3 对象的身份和访问控制

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

为什么返回 403 访问被拒绝错误

Alluxio 配置中设置的 S3 凭据对应于一个 AWS 用户。如果此用户没有访问 S3 存储桶或对象所需的权限,将返回 403 权限被拒绝错误。

如果您在访问 S3 服务时在 Alluxio 服务器日志中看到 403 错误,您应该仔细检查

  1. 您使用的是正确的 AWS 凭据。请参阅凭据设置

  2. 您的 AWS 用户有权访问挂载到 Alluxio 的存储桶和对象。

阅读更多AWS 故障排除指南以了解 403 错误。

文件所有者和组

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

默认情况下,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,展开“帐户标识符”选项卡并参考“规范用户 ID”。

更改权限

Alluxio 目录和文件的 chownchgrpchmod 不会传播到底层 S3 存储桶或对象。

使用 AWS AssumeRole

Alluxio 支持通过 AWS AssumeRole API 进行身份验证以连接到 AWS S3。启用 AssumeRole 后,AWS 访问密钥和秘密密钥将仅用于获取临时安全凭据。所有后续访问都将使用这些通过 AssumeRole 生成的临时凭据。

要在 Alluxio 中启用 AssumeRole,worker 和协调器上需要以下属性:

alluxio.underfs.s3.assumerole.enabled=true
alluxio.underfs.s3.assumerole.rolearn=arn:aws:iam::123456:role/example-role

注意:确保指定的角色存在,并且与提供的访问密钥和秘密密钥关联的用户有权代入目标角色 ARN 定义的角色。

除了强制性属性外,您还可以配置以下可选设置,以更好地控制会话行为和网络配置:

# Specifies a name for the session.
# Temporary credentials will be associated with this session.
# A random string is suffixed to ensure uniqueness.
alluxio.underfs.s3.assumerole.session.prefix="alluxio-assume-role"

# Specifies the session duration in seconds. Typically, this is between 900 and 3600 seconds.
# The session will be automatically refreshed by the AWS client,
# so no manual intervention is needed to refresh the temporary credentials.
alluxio.underfs.s3.assumerole.session.duration.second=900

# Enables the HTTPS protocol for AssumeRole requests. The default value is true.
alluxio.underfs.s3.assumerole.https.enabled=true

# Enables the HTTPS protocol for the AssumeRole proxy. The default value is false.
alluxio.underfs.s3.assumerole.proxy.https.enabled=false

# Specifies the proxy host for AssumeRole requests. Both proxy host and proxy port must be set
# in the Alluxio configuration; otherwise, the proxy settings will default to your system's
# environment configuration.
alluxio.underfs.s3.assumerole.proxy.host=<HOSTNAME>

# Specifies the proxy port for AssumeRole requests. Both proxy host and proxy port must be set
# in the Alluxio configuration; otherwise, the proxy settings will default to your system's
# environment configuration.
alluxio.underfs.s3.assumerole.proxy.port=<PORT_NUMBER>

注意:如果 Alluxio 配置中未设置代理主机和端口,JVM/系统环境变量 HTTP(S)_PROXYhttp(s)_proxyhttp(s).proxyHosthttp(s).proxyPort 将被 AWS SDK 自动拾取。

以下是在 Alluxio 中设置 AssumeRole 的示例配置:

aws.accessKeyId=FOO
aws.secretKey=BAR
alluxio.underfs.s3.assumerole.enabled=true
alluxio.underfs.s3.assumerole.session.duration.second=1000
alluxio.underfs.s3.assumerole.session.prefix="alluxio"
alluxio.underfs.s3.assumerole.rolearn=arn:aws:iam::123456:role/example-role

总结:

  • 临时凭据:AWS 访问密钥仅用于请求临时凭据;所有未来的操作都依赖于这些凭据。

  • 自动会话刷新:会话由 AWS SDK 自动刷新,无需手动干预。

  • 可自定义的配置:您可以修改会话持续时间、代理设置和会话前缀以满足您的安全和环境需求。

通过设置这些属性,Alluxio 可以有效地使用通过 AssumeRole 获取的临时凭据对 AWS S3 进行身份验证和管理访问。

故障排除

启用 AWS-SDK 调试级别

如果在使用 SDK v2 针对 S3 后端运行时遇到问题,请启用其他日志记录以跟踪 HTTP 流量。在 conf/alluxio-env.sh 文件中设置 ALLUXIO_WORKER_JAVA_OPTS

ALLUXIO_WORKER_JAVA_OPTS+=" -Daws.crt.log.level=Info  -Daws.crt.log.destination=File  -Daws.crt.log.filename=/opt/alluxio/logs/worker.log"

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

如果正在使用 AWS SDK V1,请修改 conf/log4j.properties 文件,添加以下属性:

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

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

防止创建零字节文件

Alluxio 可能会在 S3 中创建零字节文件,作为列出底层存储内容时的性能优化。如果存储桶以只读访问权限挂载,则将禁止通过 S3 PUT 操作创建零字节文件。要禁用此优化,请设置以下配置。

alluxio.underfs.object.store.breadcrumbs.enabled=false

Last updated