---
title: Amazon S3
weight: 2
type: docs
aliases:
  - /zh/deployment/filesystems/s3.html
  - /zh/ops/filesystems/s3.html
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

# Amazon S3

[Amazon Simple Storage Service](http://aws.amazon.com/s3/) (Amazon S3) 提供用于多种场景的云对象存储。S3 可与 Flink 一起使用以读取、写入数据，并可与 [流的 **State backends**]({{< ref "docs/ops/state/state_backends" >}}) 相结合使用。



通过以下格式指定路径，S3 对象可类似于普通文件使用：

```plain
s3://<your-bucket>/<endpoint>
```

Endpoint 可以是一个文件或目录，例如：

```java
// 读取 S3 bucket
FileSource<String> fileSource = FileSource.forRecordStreamFormat(
            new TextLineInputFormat(), new Path("s3://<bucket>/<endpoint>")
    ).build();
env.fromSource(
    fileSource,
    WatermarkStrategy.noWatermarks(),
    "s3-input"
);

// 写入 S3 bucket
stream.sinkTo(
    FileSink.forRowFormat(
        new Path("s3://<bucket>/<endpoint>"), new SimpleStringEncoder<>()
    ).build()
);


// 使用 S3 作为 checkpoint storage
Configuration config = new Configuration();
config.set(CheckpointingOptions.CHECKPOINT_STORAGE, "filesystem");
config.set(CheckpointingOptions.CHECKPOINTS_DIRECTORY, "s3://<your-bucket>/<endpoint>");
env.configure(config);
```

注意这些例子并*不详尽*，S3 同样可以用在其他场景，包括 [JobManager 高可用配置]({{< ref "docs/deployment/ha/overview" >}}) 或 [RocksDBStateBackend]({{< ref "docs/ops/state/state_backends" >}}#the-rocksdbstatebackend)，以及所有 Flink 需要使用文件系统 URI 的位置。

在大部分使用场景下，可使用 `flink-s3-fs-hadoop` 或 `flink-s3-fs-presto` 两个独立且易于设置的 S3 文件系统插件。然而在某些情况下，例如使用 S3 作为 YARN 的资源存储目录时，可能需要配置 Hadoop S3 文件系统。

### Hadoop/Presto S3 文件系统插件

{{< hint info >}}
如果您在使用 [Flink on EMR](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-flink.html)，您无需手动对此进行配置。
{{< /hint >}}

Flink 提供两种文件系统用来与 S3 交互：`flink-s3-fs-presto` 和 `flink-s3-fs-hadoop`。两种实现都是独立的且没有依赖项，因此使用时无需将 Hadoop 添加至 classpath。

  - `flink-s3-fs-presto`，通过 *s3://* 和 *s3p://* 两种 scheme 使用，基于 [Presto project](https://prestodb.io/)。
  可以使用[和 Presto 文件系统相同的配置项](https://prestodb.io/docs/0.272/connector/hive.html#amazon-s3-configuration)进行配置，方式为将配置添加到 [Flink 配置文件]({{< ref "docs/deployment/config#flink-配置文件" >}})中。如果要在 S3 中使用 checkpoint，推荐使用 Presto S3 文件系统。

  - `flink-s3-fs-hadoop`，通过 *s3://* 和 *s3a://* 两种 scheme 使用, 基于 [Hadoop Project](https://hadoop.apache.org/)。
  本文件系统可以使用类似 [Hadoop S3A 的配置项](https://hadoop.apache.org/docs/stable/hadoop-aws/tools/hadoop-aws/index.html#S3A)进行配置，方式为将配置添加到 [Flink 配置文件]({{< ref "docs/deployment/config#flink-配置文件" >}})中。
  
     例如，Hadoop 有 `fs.s3a.connection.maximum` 的配置选项。 如果你想在 Flink 程序中改变该配置的值，你需要将配置 `s3.connection.maximum: xyz` 添加到 [Flink 配置文件]({{< ref "docs/deployment/config#flink-配置文件" >}})中。Flink 会内部将其转换成配置 `fs.s3a.connection.maximum`。 而无需通过 Hadoop 的 XML 配置文件来传递参数。
  
    另外，它是唯一支持 [FileSystem]({{< ref "docs/connectors/datastream/filesystem" >}}) 的 S3 文件系统。
  
`flink-s3-fs-hadoop` 和 `flink-s3-fs-presto` 都为 *s3://* scheme 注册了默认的文件系统包装器，`flink-s3-fs-hadoop` 另外注册了 *s3a://*，`flink-s3-fs-presto` 注册了 *s3p://*，因此二者可以同时使用。
例如某作业使用了 [FileSystem]({{< ref "docs/connectors/datastream/filesystem" >}})，它仅支持 Hadoop，但建立 checkpoint 使用 Presto。在这种情况下，建议明确地使用 *s3a://* 作为 sink (Hadoop) 的 scheme，checkpoint (Presto) 使用 *s3p://*。这一点对于 [FileSystem]({{< ref "docs/connectors/datastream/filesystem" >}}) 同样成立。

在启动 Flink 之前，将对应的 JAR 文件从 `opt` 复制到 Flink 发行版的 `plugins` 目录下，以使用 `flink-s3-fs-hadoop` 或 `flink-s3-fs-presto`。

```bash
mkdir ./plugins/s3-fs-presto
cp ./opt/flink-s3-fs-presto-{{< version >}}.jar ./plugins/s3-fs-presto/
```

#### 配置访问凭据

在设置好 S3 文件系统包装器后，您需要确认 Flink 具有访问 S3 Bucket 的权限。

##### Identity and Access Management (IAM)（推荐使用）

建议通过 [Identity and Access Management (IAM)](http://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) 来配置 AWS 凭据。可使用 IAM 功能为 Flink 实例安全地提供访问 S3 Bucket 所需的凭据。关于配置的细节超出了本文档的范围，请参考 AWS 用户手册中的 [IAM Roles](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html) 部分。

如果配置正确，则可在 AWS 中管理对 S3 的访问，而无需为 Flink 分发任何访问密钥（Access Key）。

##### 访问密钥（Access Key）（不推荐）

可以通过**访问密钥对（access and secret key）**授予 S3 访问权限。请注意，根据 [Introduction of IAM roles](https://blogs.aws.amazon.com/security/post/Tx1XG3FX6VMU6O5/A-safer-way-to-distribute-AWS-credentials-to-EC2)，不推荐使用该方法。

 `s3.access-key` 和 `s3.secret-key` 均需要在 Flink 的 [Flink 配置文件]({{< ref "docs/deployment/config#flink-配置文件" >}}) 中进行配置：

```yaml
s3.access-key: your-access-key
s3.secret-key: your-secret-key
```

You can limit this configuration to JobManagers by using [Flink configuration file]({{< ref "docs/deployment/security/security-delegation-token" >}}).

```yaml
# flink-s3-fs-hadoop
fs.s3a.aws.credentials.provider: org.apache.flink.fs.s3.common.token.DynamicTemporaryAWSCredentialsProvider
# flink-s3-fs-presto
presto.s3.credentials-provider: org.apache.flink.fs.s3.common.token.DynamicTemporaryAWSCredentialsProvider
```

## 配置非 S3 访问点

S3 文件系统还支持兼容 S3 的对象存储服务，如 [IBM's Cloud Object Storage](https://www.ibm.com/cloud/object-storage) 和 [Minio](https://min.io/)。可在 [Flink 配置文件]({{< ref "docs/deployment/config#flink-配置文件" >}}) 中配置使用的访问点：

```yaml
s3.endpoint: your-endpoint-hostname
```

## 配置路径样式的访问

某些兼容 S3 的对象存储服务可能没有默认启用虚拟主机样式的寻址。这种情况下需要在 [Flink 配置文件]({{< ref "docs/deployment/config#flink-配置文件" >}}) 中添加配置以启用路径样式的访问：

```yaml
s3.path.style.access: true
```

## S3 文件系统的熵注入

内置的 S3 文件系统 (`flink-s3-fs-presto` and `flink-s3-fs-hadoop`) 支持熵注入。熵注入是通过在关键字开头附近添加随机字符，以提高 AWS S3 bucket 可扩展性的技术。

如果熵注入被启用，路径中配置好的字串将会被随机字符所替换。例如路径 `s3://my-bucket/_entropy_/checkpoints/dashboard-job/` 将会被替换成类似于 `s3://my-bucket/gf36ikvg/checkpoints/dashboard-job/` 的路径。
**这仅在使用熵注入选项创建文件时启用！**
否则将完全删除文件路径中的 entropy key。更多细节请参见 [FileSystem.create(Path, WriteOption)](https://nightlies.apache.org/flink/flink-docs-release-1.6/api/java/org/apache/flink/core/fs/FileSystem.html#create-org.apache.flink.core.fs.Path-org.apache.flink.core.fs.FileSystem.WriteOptions-)。

{{< hint info >}}
目前 Flink 运行时仅对 checkpoint 数据文件使用熵注入选项。所有其他文件包括 checkpoint 元数据与外部 URI 都不使用熵注入，以保证 checkpoint URI 的可预测性。
{{< /hint >}}

配置 *entropy key* 与 *entropy length* 参数以启用熵注入：

```
s3.entropy.key: _entropy_
s3.entropy.length: 4 (default)

```

`s3.entropy.key` 定义了路径中被随机字符替换掉的字符串。不包含 entropy key 路径将保持不变。
如果文件系统操作没有经过 *"熵注入"* 写入，entropy key 字串将被直接移除。
`s3.entropy.length` 定义了用于熵注入的随机字母/数字字符的数量。

## s5cmd

Both `flink-s3-fs-hadoop` and `flink-s3-fs-presto` can be configured to use the [s5cmd tool](https://github.com/peak/s5cmd) for faster file upload and download.
[Benchmark results](https://cwiki.apache.org/confluence/display/FLINK/FLIP-444%3A+Native+file+copy+support) are showing that `s5cmd` can be over 2 times more CPU efficient.
Which means either using half the CPU to upload or download the same set of files, or doing that twice as fast with the same amount of available CPU.

In order to use this feature, the `s5cmd` binary has to be present and accessible to the Flink's task managers, for example via embedding it in the used docker image.
Secondly, the path to the `s5cmd` has to be configured via:
```yaml
s3.s5cmd.path: /path/to/the/s5cmd
```

The remaining configuration options (with their default value listed below) are:
```yaml
# Extra arguments that will be passed directly to the s5cmd call. Please refer to the s5cmd's official documentation.
s3.s5cmd.args: -r 0
# Maximum size of files that will be uploaded via a single s5cmd call.
s3.s5cmd.batch.max-size: 1024mb
# Maximum number of files that will be uploaded via a single s5cmd call.
s3.s5cmd.batch.max-files: 100
```
Both `s3.s5cmd.batch.max-size` and `s3.s5cmd.batch.max-files` are used to control resource usage of the `s5cmd` binary, to prevent it from overloading the task manager.

It is recommended to first configure and making sure Flink works without using `s5cmd` and only then enabling this feature.

### Credentials

If you are using [access keys](#access-keys-discouraged), they will be passed to the `s5cmd`.
Apart from that `s5cmd` has its own independent (but similar) of Flink way of [using credentials](https://github.com/peak/s5cmd?tab=readme-ov-file#specifying-credentials).

### Limitations

Currently, Flink will use `s5cmd` only during recovery, when downloading state files from S3 and using RocksDB.

{{< top >}}
