AWS 新发布的 S3 Files 适合作为 Kafka 的存储吗?

Kafka 社区对共享存储的兴趣由来已久:如果所有数据都放在 S3 这样的共享存储上,Broker 就不需要本地磁盘,副本复制可以省掉,跨 AZ 流量费也随之消失。但对象存储的延迟一直让这个想法停留在"理论上很美"的阶段。AWS 最近发布的 S3 Files 改变了这个前提------它给 S3 加上了 NFS 文件系统接口,小文件读取延迟做到了亚毫秒级。于是一个老问题以新的面貌回来了:Kafka 能不能直接跑在 S3 Files 上?

我们在 AutoMQ 从 2023 年起就在解决这个问题------不是把 Kafka 搬到共享文件系统上,而是从存储引擎层重新设计,让 Kafka 真正运行在共享存储架构上。我们是这个领域最早探索用共享文件系统作为存储后端的团队,也是目前唯一做到生产级低延迟的 Diskless Kafka 实现。所以当 S3 Files 出现时,我们自然要评估它的可能性------以及它的边界在哪里。

S3 Files 是什么?

要回答"Kafka 能不能跑在 S3 Files 上",先得理解 S3 Files 到底做了什么。它本质上是 AWS 在 S3 之上加了一层基于 EFS(Elastic File System)的文件系统访问面------你可以通过 NFS 协议把 S3 存储桶挂载到 EC2 实例上,像操作本地文件一样读写,而 S3 始终是数据的 Source of Truth。

这层访问面的核心设计围绕一个 128 KB 的阈值。小于 128 KB 的文件在首次访问时会被导入 EFS 高性能层,读取延迟可以做到亚毫秒到个位数毫秒;128 KB 及以上的文件则绕过 EFS,通过本地代理直接从 S3 流式读取。写入方向上,所有数据都先落到 EFS 层,再由后台异步批量同步回 S3。换句话说,S3 Files 的优化重点是小文件的低延迟读取,而不是让所有数据都常驻在高性能层。

定价模型进一步印证了这个定位。写入按流量计费 0.06/GB,最小计费 I/O 为 6 KiB,没有预置容量选项。数据同步到 S3 后不会立刻从 EFS 淘汰,默认驻留 30 天,期间你同时支付 EFS 高性能层存储费(0.30/GB-月)和 S3 存储费用。对于读多写少的场景,这个定价是合理的。但对于持续高吞吐写入的工作负载,写入成本和 EFS 驻留费用会快速累积。

共享存储对 Kafka 的吸引力

理解了 S3 Files 的能力边界,再来看为什么大家想把 Kafka 构建在上面。传统 Apache Kafka® 是为专用服务器加本地磁盘设计的,这套架构搬到云上会产生三个不断叠加的成本问题。

最直接的是副本复制带来的跨 AZ 流量费。Kafka 通过 ISR(In-Sync Replicas)机制保证持久性,每条消息会被复制到两到三个 Broker。在多 AZ 部署中,这种复制产生大量跨 AZ 网络流量------AWS 对跨 AZ 数据传输双向收费,合计 0.02/GB。一个写入吞吐 500 MB/s、副本因子为 3 的集群,两个 Follower 分布在不同 AZ,每秒产生约 1 GB 的跨 AZ 复制流量,仅这一项就超过 50,000/月。

副本复制还带来了第二个问题:存算耦合。每个 Broker 在本地磁盘上管理自己的数据副本,扩展存储就意味着加机器------即使你只需要更多磁盘空间。而且必须按峰值负载加上故障冗余来预留容量,大部分时间都在为闲置资源付费。

存算耦合又进一步放大了运维复杂度。分区重分配需要在 Broker 之间物理搬迁数据,大 Topic 可能耗时数小时。Broker 故障触发漫长的恢复流程。缩容比扩容更难,因为你得先把数据搬走。

如果所有数据都在 S3 这样的共享存储上,这三个问题可以一次性解决:S3 自带 11 个 9 的持久性,不需要副本复制;Broker 变成无状态计算节点,秒级扩缩容;跨 AZ 流量降到接近零。S3 Files 有 NFS 接口、有亚毫秒延迟,看起来正好是连接 Kafka 和共享存储之间的桥梁。但真正尝试搭建这座桥梁时,会遇到几个根本性的问题。

挑战:直接把 Kafka 跑在 S3 Files 上会怎样?

持久性缺口

最符合直觉的做法是把副本因子设为 1------既然 S3 Files 提供了共享的持久化存储,一份数据就够了。问题出在 Kafka 的写入机制上。

Kafka 是一个异步 I/O 系统。Producer 发送消息并收到 ack 时,数据还在操作系统的 page cache 里,并不一定已经刷到底层存储。这是 Kafka 高吞吐的设计基础------它假设即使 Broker 在刷盘前崩溃,数据仍然安全地存在于 Follower 副本上。但在 replica=1 的 S3 Files 上,这张安全网消失了。Broker 崩溃意味着 page cache 中尚未持久化的数据直接丢失,S3 Files 的 11 个 9 持久性帮不上忙------数据根本还没到达存储层。

要堵住这个缺口,需要改变 Kafka 的写入路径:确保每条被确认的消息在返回 ack 之前就已经持久化。这不是调配置能解决的,这是存储引擎层面的重新设计。

可用性耦合

持久性问题可以通过改造写入路径来解决,但 Kafka 的高可用机制带来了另一个更深层的挑战。

Kafka 的 HA 和多副本设计紧密耦合:Broker 故障时,Controller 将 Follower 副本提升为新 Leader。这个机制的前提是存在 Follower------而 replica=1 意味着没有 Follower 可以提升。你需要一套完全不同的故障转移逻辑:让新 Broker 直接从共享存储读取数据来接管分区,而不依赖本地副本。Kafka 现有的 HA 设计天然阻止了它利用 S3 Files 内置的可用性保障。

这同样需要架构层面的重新设计------不只是写入路径,还有整个故障恢复和分区所有权的管理方式。

延迟现实

即使解决了持久性和可用性问题,延迟仍然是一道坎。S3 Files 宣传的亚毫秒延迟针对的是 EFS 高性能层上的小文件读取,而 Kafka 的核心工作负载是高吞吐的持续顺序写入------这两者的 I/O 模式完全不同。

社区已经有人在 S3 Files 上跑过 Kafka benchmark,数据很说明问题:

指标 1 KiB 最大吞吐 10 KiB 最大吞吐 10 KiB 调优后
平均延迟 31.86 ms 21.86 ms 21.38 ms
P50 0 ms 1 ms 1 ms
P95 12 ms 5 ms 13 ms
P99 1,099 ms 704 ms 801 ms
P99.9 3,173 ms 2,959 ms 2,051 ms
最大值 9,904 ms 4,152 ms 5,139 ms

中位数和 P95 看起来还行------P95 只有 5-13ms,和原生 Kafka 差距不大。但从 P95 到 P99 出现了断崖式跳跃:5ms 直接飙到 704ms,延迟放大了 140 倍。这意味着每一百次请求就有一次要等超过一秒。对于实时流处理场景------风控、实时大屏、事件驱动微服务------这种不可预测的尾延迟是不可接受的。S3 Files 并没有彻底解决共享存储的低延迟问题,相比本地磁盘上的 Kafka 仍然有明显的延迟牺牲。

成本结构

延迟之外,S3 Files 的定价模型对 Kafka 也不友好。S3 Files 采用按流量计费------写入 0.06/GB,小文件读取 0.03/GB,没有预置容量选项。这和 S3 的按 API 请求次数计费是完全不同的模型。Kafka 的工作负载特征是写入和读取都需要走高性能层:Producer 写入的数据落到 EFS 高性能层,Consumer 做 Tailing Read(消费最新数据)也从高性能层读取。两端都按流量计费,成本随吞吐量线性增长。写入端还有双重流量费------数据先写入 EFS(0.06/GB),再由后台同步回 S3(0.03/GB),Kafka 的所有数据都需要同步回 S3,这笔同步费逃不掉。更隐蔽的是 EFS 高性能层的存储驻留费:$0.30/GB-月,是 S3 Standard 存储费的 13 倍,数据默认驻留 30 天才淘汰。

算一笔具体的账。一个 100 MB/s 持续写入的集群,假设消费端吞吐和写入相当(1x fan-out,即一个 Consumer Group),每天写入和读取各约 8,400 GB(100 MB/s × 86,400 秒):

费用项 计算 日费用
写入流量费 8,400 GB × $0.06/GB $504
写入同步费(导出回 S3) 8,400 GB × $0.03/GB $252
Tailing Read 流量费 8,400 GB × $0.03/GB $252
日流量费合计 $1,008
EFS 存储驻留费(30 天累积) 252,000 GB × $0.30/GB-月 $75,600/月
月总计(流量 + 存储驻留) 1,008 × 30 + 75,600 ~$106,000/月

这还是 1x fan-out 的保守估算。如果有多个 Consumer Group(在 Kafka 场景中很常见),Tailing Read 的流量费会成倍增长。2x fan-out 下月成本就超过 113,000,3x 超过 120,000。而且这还没算 S3 本身的存储费。S3 Files 的定价模型是为"读多写少、活跃工作集小"的场景设计的------Kafka 恰好相反:持续高吞吐写入,所有数据都是"活跃"的,读取端也是持续高吞吐。

这些挑战加在一起意味着什么?

持久性缺口要求重新设计写入路径。可用性耦合要求重新设计故障转移机制。延迟问题要求在对象存储之前加一层高性能写入缓冲。成本问题要求对小写入进行攒批优化。把这四项加在一起,你实际上需要的是一个全新的 Kafka 存储引擎------而这正是 AutoMQ 从 2023 年就在构建的东西。

AutoMQ:已经被验证的 Shared Storage 架构

AutoMQ 的架构分为两层。S3 是主存储层,所有数据最终都持久化在 S3 上------这是和 Tiered Storage 的根本区别。Tiered Storage 仍然把热数据放在本地磁盘上,S3 只存冷数据;而 AutoMQ 让 S3 成为唯一的 Single Source of Truth,Broker 上没有任何持久化状态(关于两者的详细对比,可以参考这篇文章)。

但直接把每条消息都写到 S3 有两个问题:S3 的写入延迟太高,而且 S3 API 调用是按次计费的------每条消息一次 PUT 请求,API 成本会随消息数线性爆炸。这就是 WAL(Write-Ahead Log)层存在的意义。

WAL 是一块固定大小的高性能存储空间,充当 S3 前面的写入缓冲。所有 Produce 请求先写入 WAL,使用 Direct IO 绕过 page cache,在返回 ack 之前就保证数据持久化------这直接堵住了上面说的持久性缺口。然后 WAL 中的数据被异步压缩、攒批,再批量上传到 S3。这个攒批过程至关重要:不是每条消息一次 S3 PUT,而是每批数千条消息一次 PUT,S3 API 成本从随消息数增长变成了随吞吐量增长,降低了一到两个数量级。

WAL 带来的另一个关键好处是让用户可以在延迟和成本之间做 trade-off。WAL 层是可插拔的,不同的云存储后端对应不同的延迟和成本特征:EBS/Regional EBS WAL 提供亚毫秒延迟,NFS WAL(AWS 上基于 FSx for NetApp ONTAP)提供平均 6ms、P99 约 13ms 的写入延迟。Producer 的体验和原生 Kafka 没有区别。

而且 WAL 的成本很低。它只需要一小块固定大小的存储空间------不是存全量数据,只是一个循环写入的缓冲区。对于大部分云存储的定价模型来说,这非常友好:每月几美元到几十美元的 WAL 支出,就能换来低延迟持久化、S3 API 成本优化、以及真正的无状态 Broker。

因为所有持久化状态都在 WAL 和 S3 中,Broker 是真正无状态的。一个 Broker 故障时,另一个 Broker 在秒级内接管分区映射,不需要数据迁移,Zero RPO------这解决了可用性耦合的问题。

最终效果是 Kafka on S3 Files 所承诺的一切------零跨 AZ 流量、无副本复制、弹性无状态 Broker------但没有持久性缺口、秒级尾延迟和高昂的流量成本。

S3 Files 作为 WAL:技术上可行,经济上还不成熟

既然 AutoMQ 的 WAL 层是可插拔的,S3 Files 能不能作为又一个 WAL 后端?从架构上看,答案是肯定的。S3 Files 提供 NFS 接口,底层基于 EFS 构建------而 AutoMQ 的 NFS WAL 已经支持 EFS 和 FSx for NetApp ONTAP 作为实现,技术路径是通的。

但当前的定价模型让这个方案的经济账算不过来。Kafka 不是一个轻量级的应用层服务,它是数据密集型的基础设施------AutoMQ 的一些生产客户集群吞吐超过 1 GiB/s,7×24 小时不间断写入。在这个量级下,S3 Files 的纯按量计费模型会产生惊人的费用。

以一个相对温和的工作负载为例------写入吞吐 100 MB/s、平均消息大小 4 KiB:

维度 EFS(作为 WAL) S3 Files(作为 WAL)
写入定价 EFS 弹性吞吐计费 0.06/GB 写入 + 0.03/GB 同步回 S3
高性能存储驻留费 包含在 EFS 定价中 $0.30/GB-月(默认驻留 30 天)
月成本估算(100 MB/s) ~$15,500 ~$100,000(流量费 + 存储驻留费)

100 MB/s 已经是一个保守的数字了。如果换成 1 GiB/s 的生产集群,S3 Files 的月成本会突破百万美元------流量费和 EFS 存储驻留费都随吞吐量线性增长。核心问题在于 S3 Files 的定价模型是为"读多写少、活跃工作集小"的场景设计的,而 Kafka 恰好相反:持续高吞吐写入,所有数据都是"活跃"的。S3 Files 作为 WAL 的开销远高于直接使用 EFS,而延迟上并没有优势。

不过云存储的定价在持续演进。如果 AWS 为 S3 Files 引入预置吞吐模型或降低最小计费 I/O,这笔账可能很快就会变。AutoMQ 的架构已经为那一天做好了准备。

一套架构,适配所有云存储

S3 Files 的故事其实揭示了一个更大的趋势:云存储在加速分化。AWS 在过去两年推出了 S3 Express One Zone(个位数毫秒延迟的 S3)、S3 Files(NFS over S3)、以及对 EFS 和 FSx for NetApp ONTAP 的持续改进。GCP 和 Azure 也在各自的存储服务上走着类似的路线。每种存储服务针对不同的访问模式、成本模型和持久性保障做了优化。

AutoMQ 的可插拔 WAL 架构意味着我们不需要押注某一个赢家------每一次云存储创新都会成为 WAL 后端菜单上的一个新选项:

WAL 后端 延迟 多 AZ 成本 适合场景
EBS WAL 亚毫秒 单 AZ(多副本) AWS 上所有 Kafka 工作负载
Regional EBS WAL 亚毫秒 多 AZ(多副本) Azure / GCP / 阿里云上的生产环境(推荐)
S3 WAL 百毫秒级 多 AZ 延迟不敏感场景(日志、监控),开源版默认
NFS WAL(AWS 上使用 EFS / FSxN) 毫秒级 多 AZ 中等 AWS 上的低延迟场景(核心交易撮合等)

用户不需要被锁定在某一种存储方案上,而是可以根据自己的延迟要求和成本预算自由选择------并且随着需求变化或云定价演进随时切换。在 AWS 上,NFS WAL 已经支持 EFS 和 FSx for NetApp ONTAP 两种实现;在 Azure 和 GCP 上,Regional EBS WAL 利用各自的多 AZ 块存储提供亚毫秒延迟。让这一切成为可能的 WAL 抽象层,从第一天起就是这么设计的。

回到最初的问题

Kafka 构建在 S3 Files 上,是个好主意吗?如果说的是把原生 Kafka 直接挂载上去------不是。Kafka 的异步 I/O、基于副本的 HA、对本地存储的假设,这些设计决策会让你回到原点:还是要管副本、管故障转移、管容量规划。共享存储就在那里,但 Kafka 的架构用不上。

但 Kafka 向 Shared Storage 架构演进的方向是确定的------经济账和运维收益太有说服力了。AutoMQ 基于 WAL 的 Shared Storage 架构已经交付了这个承诺,而且每当云存储向前迈进一步,可插拔的 WAL 层就把这次创新变成用户的一个新选项。一套架构,适配所有云存储。

相关推荐
MY_TEUCK5 小时前
从零开始:使用Sealos Devbox快速搭建云原生开发环境
人工智能·spring boot·ai·云原生·aigc
byoass12 小时前
企业云盘文件预览技术深度剖析:从10种常见格式到渲染架构实战
网络·安全·架构·云计算
墨客希17 小时前
AWS PCA
云计算·aws
没有口袋啦18 小时前
《基于 GitOps 理念的企业级自动化 CI/CD 流水线》
阿里云·ci/cd·云原生·自动化·k8s
柯西劝我别收敛20 小时前
Koordinator-Scheduler 调度器源码解析
后端·云原生
сокол1 天前
【网安-等保评测-基础记录】网络安全等级保护2.0 详解(定级、备案、测评、整改一站式指南)
网络·笔记·网络安全·云计算
byoass1 天前
企业云盘私有化部署:存储架构设计与安全运维全流程实战
运维·网络·安全·云计算
Ztopcloud极拓云视角1 天前
阿里云涨价生效日:多云成本优化实战指南(含Claude Opus 4.7接入对比)
阿里云·云计算·anthropic·claude opus 4.7
OpenClawID1 天前
2026年怎么安装OpenClaw?腾讯云1分钟喂奶级流程+大模型APIKey配置、Skill集成指南
云计算·腾讯云