1、 S3 URI 写法与常见使用场景
在 Flink 里,S3 路径通常写成:
s3://<bucket>/<endpoint>
这里的 <endpoint> 可以是单个文件,也可以是目录前缀。
常见场景包括:
- FileSource 从 S3 读取文件/目录
- FileSink 写入 S3(落文件)
- 把 S3 作为 Checkpoint/Savepoint 的存储(强烈常见)
- HA 元数据目录、或 EmbeddedRocksDBStateBackend 的远端状态文件等(只要该处需要 FileSystem URI)
2、代码示例:读、写、Checkpoint 存到 S3
2.1 从 S3 读(FileSource)
java
FileSource<String> fileSource = FileSource.forRecordStreamFormat(
new TextLineInputFormat(),
new Path("s3://<bucket>/<endpoint>")
).build();
env.fromSource(
fileSource,
WatermarkStrategy.noWatermarks(),
"s3-input"
);
2.2 写到 S3(FileSink)
java
stream.sinkTo(
FileSink.forRowFormat(
new Path("s3://<bucket>/<endpoint>"),
new SimpleStringEncoder<String>()
).build()
);
2.3 用 S3 作为 Checkpoint Storage
java
Configuration config = new Configuration();
config.set(CheckpointingOptions.CHECKPOINT_STORAGE, "filesystem");
config.set(CheckpointingOptions.CHECKPOINTS_DIRECTORY, "s3://<bucket>/<endpoint>");
env.configure(config);
经验建议:如果你在生产上把 checkpoint 放 S3,一定要优先把"插件选型 + 凭证方式 + 性能策略"弄稳,否则最容易出现"checkpoint 慢、恢复慢、偶发失败"。
3、插件选型:flink-s3-fs-presto vs flink-s3-fs-hadoop
Flink 提供两套自带的 S3 文件系统插件,都是"自包含"的:不需要把 Hadoop 整套依赖塞进 classpath 就能用。
3.1 flink-s3-fs-presto
- scheme:
s3://和s3p:// - 基于 Presto 的实现
- 推荐用于把 checkpoint 写到 S3(官方推荐点在这里)
- 配置项使用 Presto 文件系统的配置键(写到 Flink 配置里)
3.2 flink-s3-fs-hadoop
- scheme:
s3://和s3a:// - 基于 Hadoop S3A 实现
- 配置项使用 Hadoop 的 s3a 配置键(但写法是 Flink 风格,Flink 会翻译回
fs.s3a.*) - 在需要更"传统 Hadoop 生态兼容"的场景更常用(例如你要对齐 s3a 的各种高级参数)
3.3 同时使用两套插件:最实用的组合
两套插件都可以"接管" s3://,所以要同时用时,建议显式区分 scheme:
- Sink/普通读写:用
s3a://(走 Hadoop 插件) - Checkpoint:用
s3p://(走 Presto 插件)
这样可以做到:作业某些 IO 用 Hadoop 体系的能力,同时 checkpoint 享受 Presto 插件的推荐路径。
4、安装方式:把插件 JAR 放到 plugins 目录
以 presto 插件为例(2.2.0):
bash
mkdir ./plugins/s3-fs-presto
cp ./opt/flink-s3-fs-presto-2.2.0.jar ./plugins/s3-fs-presto/
hadoop 插件同理,建议一个插件一个子目录,方便隔离和排查。
提示:如果你跑在 EMR 上,很多情况下不需要手动配这一步(环境通常已经处理好了)。
5、访问凭证:优先 IAM Roles,不推荐 Access Keys
5.1 推荐:IAM(角色)方式
生产上最推荐用 IAM Roles,把访问权限"绑在运行 Flink 的实例/容器身份上",避免在 Flink 配置里分发 access key/secret key。
优点:
- 不需要在集群里散落密钥
- 权限治理更集中(AWS 原生 IAM)
5.2 不推荐:Access Keys(但可以用)
如果必须使用 AK/SK,需要在 Flink 配置里写:
yaml
s3.access-key: your-access-key
s3.secret-key: your-secret-key
还可以限制只在 JobManager 配置(减少泄露面)。
5.3 动态临时凭证 Provider(插件对应不同配置键)
如果你用动态临时凭证(例如配合 STS),文档给了两套插件对应的 provider 配置键:
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
6、非 AWS S3:MinIO / IBM COS 等 S3 兼容存储
很多公司内网会用 MinIO 或其他 S3 兼容对象存储,Flink 的 S3 文件系统也支持:
6.1 配置 endpoint
yaml
s3.endpoint: your-endpoint-hostname
6.2 Path Style 访问(MinIO 常见)
如果对象存储默认没开 Virtual Host Style,可能需要启用 Path Style:
yaml
s3.path.style.access: true
这个在"本地单机 MinIO 测试"里很常见,否则你会遇到奇怪的域名解析/访问失败。
7、性能优化一:Entropy Injection(熵注入,提升 bucket 可扩展性)
熵注入的核心思路:在 key 前部插入随机字符,打散热点前缀,提升并发扩展性。
启用方式:
yaml
s3.entropy.key: _entropy_
s3.entropy.length: 4
例如路径:
s3://my-bucket/_entropy_/checkpoints/dashboard-job/
可能会变成:
s3://my-bucket/gf36ikvg/checkpoints/dashboard-job/
重要细节:Flink 运行时当前只会对"checkpoint 数据文件"传递"注入熵"的 write option;checkpoint 元数据、外部可见 URI 等不会注入熵,以保持 URI 可预测。
落地建议:
- 如果你 checkpoint 写 S3 压力大、并发高、出现前缀热点迹象,可以考虑启用
- 但要确保运维侧理解"目录前缀会被打散"的行为,避免用人工路径规则做强依赖
8、性能优化二:s5cmd 加速上传/下载(更省 CPU)
两套插件都支持调用 s5cmd 来提升 S3 文件传输效率。文档提到基准结果可达到 2 倍以上的 CPU 效率提升(同样数据更省 CPU,或同样 CPU 更快)。
启用前提:
s5cmd二进制需要存在于 TaskManager 可访问的位置(常见做法:打进 Docker 镜像)- 配置
s3.s5cmd.path
yaml
s3.s5cmd.path: /path/to/the/s5cmd
控制资源使用的参数(防止把 TaskManager 打爆):
yaml
s3.s5cmd.args: -r 0
s3.s5cmd.batch.max-size: 1024mb
s3.s5cmd.batch.max-files: 100
使用建议:
- 先确保"不启用 s5cmd 时"系统稳定可用,再开启 s5cmd
- 如果你用 AK/SK,它会被传给 s5cmd;同时 s5cmd 自己也有独立的凭证机制(注意一致性)
限制说明(很关键):
- 当前 Flink 只在"恢复阶段"使用 s5cmd:当 RocksDB 从 S3 下载 state 文件进行恢复时会用到
9、一份推荐的生产配置组合(可直接改)
如果你打算:sink 用 Hadoop、checkpoint 用 Presto,且使用 IAM/临时凭证:
yaml
# 建议:sink 用 s3a://,checkpoint 用 s3p://(作业代码/配置里体现)
# 插件:同时安装 flink-s3-fs-hadoop 与 flink-s3-fs-presto
# checkpoint 推荐 presto provider(如果用临时凭证)
presto.s3.credentials-provider: org.apache.flink.fs.s3.common.token.DynamicTemporaryAWSCredentialsProvider
# sink/普通 IO 走 s3a 参数(如需临时凭证)
fs.s3a.aws.credentials.provider: org.apache.flink.fs.s3.common.token.DynamicTemporaryAWSCredentialsProvider
# 非 AWS S3(如 MinIO)按需开启
# s3.endpoint: minio.mycompany.local:9000
# s3.path.style.access: true
# checkpoint 高并发可考虑熵注入
# s3.entropy.key: _entropy_
# s3.entropy.length: 4