
这份性能报告不是要论证 AutoMQ 和 AWS FSxN 是某种官方绑定的组合而是我在真实 AWS 环境里连续跑了一周压测后得到的对比数据和踩坑记录。起因是项目上需要一个比 S3 更可控的消息持久层既要有对象存储那样简单的 Put/Get 接口又要让数据落在自己规划好的文件系统或合规边界内。最初我盯着 FSxN 的 NFS 能力想了很久后来才发现它的 ONTAP S3 接口才是接入 AutoMQ 的正确姿势。这一轮测试覆盖了生产吞吐、消费端冷读时延、WAL 段回收、分区迁移和成本测算几个维度的对比结论有惊喜也有坑整理出来写给正在做 Kafka 迁移和云原生存储选型的朋友。先说一个最基本的判断逻辑AutoMQ 的对象存储层选型不能套用数据库对存储的要求。这个问题我后面会详细拆解但可以先记住结论——真正影响你用户体验的不是对象存储的随机 IOPS而是它的 PUT/GET 带宽稳定性、客户端兼容性以及和内网底座的网络距离。1. 选型背景AutoMQ 的对象存储后端为什么能用 FSxN1.1 AutoMQ 存储链路拆解AutoMQ 本质上是对 Kafka 协议做云原生重写它对外兼容 Kafka 客户端但内部存储结构完全改掉。它不再像传统 Kafka 那样每个分区副本在多个 broker 上各自写一份日志而是采用“WAL 对象存储”的分层结构。生产链路大致是这样客户端把消息发给 brokerbroker 先把数据追加写入本机挂载卷上的 WAL 文件写入成功后就向客户端返回 ack。这里有个关键点生产者感受到的端到端时延只取决于 WAL 落盘的速度和对象存储的上传是否完成没有关系。WAL 只是一个短期缓冲后台会有专门的线程把已经封段的 WAL 文件转换成流段对象再上传到对象存储。上传成功后本地 WAL 这一段就会被回收。消费链路则是另一回事。如果消费端要读的消息还留在 WAL 上broker 直接从本地读速度很快如果消息已经被上传到对象存储broker 就要去对象存储拉段数据。所以对象存储在后端承担的是“持久层”和“冷读”的职责它不决定你生产链路的上限但直接决定你消费历史数据时的吞吐、延迟和稳定性也决定集群做分区迁移或故障恢复时的速度。理解了这一点选型逻辑就清晰了你不需要追求对象存储有多高的单卷 IOPS而是要看它在批量上传、随机读取、突发流量下的带宽表现以及客户端 SDK 能不能稳稳地把数据搬进去再搬出来。1.2 FSxN 在 AWS 上能承担的两个角色AWS FSx for NetApp ONTAP简称 FSxN很多人只把它当成一个企业级 NAS 文件共享服务。NFS 和 SMB 协议是它的看家本领也确实很稳定。但 FSxN 本身跑的是完整的 ONTAP 系统ONTAP 里面除了文件协议还能开启对象存储服务也就是说你可以把它配置成一个 S3 兼容的对象存储网关。这就让 FSxN 和 AutoMQ 之间出现了两条可能的对接路径。第一条路径是把 FSxN 当作对象存储后端让 AutoMQ 把流段对象都放到 FSxN 的 S3 bucket 里。这条路径是我这次测试的主角。AutoMQ 对对象存储的使用方式是标准的 S3 API 交互比如 PutObject、GetObject、DeleteObject、ListObjects、Multipart UploadONTAP S3 对这些基础语义的兼容性足够好接入过程没遇到协议级别的障碍。第二条路径是把 FSxN 当作 NFS 共享存储让多个 broker 挂载同一个文件系统把 WAL 或段文件写进去。这条路径我测试之后是一条明确不建议走的路线。原因我们放到后面“踩坑记录”里讲这里先给一个生活化类比AutoMQ 的 WAL 要求的是低延迟高带宽的本地落盘让网络文件系统来承接这件事等于把高速公路上的收费站挪到了你小区门口只能在很低流量下勉强跑通。1.3 为什么值得专门做一轮性能对比单独看 S3 或者单独看 FSxN两者在 AWS 上都很成熟但把 AutoMQ 和 FSxN 组合在一起的人不多公开的性能数据更是少。做这轮测试前我脑子里有几个非常实际的问题成本结构完全不一样。S3 是容量费加上千万级请求计费消息量大的场景 PUT/GET 请求费会悄悄滚成一个可观的数字FSxN 则是包容量和吞吐预算固定成本占比高但流量大了以后边际成本接近零。到底哪个划算取决于你的流量模型但这个账观察者容易算错。数据控制权不一样。S3 是托管服务桶内数据虽然可以加生命周期规则但底层物理存储位置和完整快照能力都依赖 AWS 平台能力FSxN 可以按 NetApp 的方式做快照、灾备和跨区复制对数据合规要求严格的用户更有吸引力。网络路径不一样。S3 即使走 VPC 内网访问也是通过网关或 endpoint 转发网络跳数多FSxN 是实实在在部署在 VPC 子网里的资源broker 和 FSxN 在一个子网内时数据路径几乎就是内网直连理论上冷读延迟会更低。这几个问题在桌面推演阶段都只能靠猜所以我决定直接部署一套测试环境用相同版本的 AutoMQ、相同的 Topic 定义和相同规格的客户端分别把对象存储指向 S3 和 FSxN 跑同一组压测。2. 测试环境、口径与压测模型2.1 部署拓扑与 FSxN 规格测试环境全部部署在 AWS 的同一个可用区broker 和 FSxN 放在同一个子网避免跨可用区流量对结果产生干扰。这套环境虽然规模不大但足够反映常见的中型消息集群特征。Broker 节点用了 3 台 m6i.2xlarge每台 8 vCPU、32GB 内存系统盘和 WAL 盘用 EBS gp3容量给到 1TBIOPS 设置在 3000。客户端压测节点是 2 台 c6i.2xlarge分别跑生产端和消费端脚本。FSxN 文件系统开了 1TiB 容量吞吐配置提到 2 GiB/s 的预留这样保证它在压测中不是先撑不住的那一环。需要说明的是FSxN 的持续吞吐上限和配置的容量、磁盘类型强相关吞吐预留越高成本越高你最后在生产环境里选多少一定是要和容量规划一起算的而不是拍脑袋越大越好。Topic 设计上单独建了一个 perftest12 个分区副本数保持 1。这里可能有读者会问传统 Kafka 的生产建议都是副本数至少 2 或 3AutoMQ 为什么敢用副本 1因为 AutoMQ 的数据持久性由对象存储承载WAL 上传成功并确认后数据已经有跨节点或者跨可用区的冗余能力broker 不再为了副本而复制数据。这也是它成本下降的核心原因之一。2.2 压测工具与请求模型压测工具用的是 Kafka 发行包里自带的kafka-producer-perf-test.sh和kafka-consumer-perf-test.sh原因很简单AutoMQ 对外是 Kafka 协议这批工具不需要改动就能直接压测出来的数字有可复现性别人也能用同样命令验证。生产端的压力模型是持续写入 5000 万条 1KB 大小的消息开启linger.ms20让客户端在批量发送上有点缓冲acks 分别测试了acks1和acksall两种模式。这个设计的考虑是acksall 是多数金融、交易类场景的要求acks1 则更贴近日志和事件类流量两者对 WAL 和后台上传链路的压力形态完全不同。消费端的压力模型分成两部分。第一部分是消费尚未冷到对象存储的近期数据用来模拟实时消费场景第二部分是提前把一段历史数据全部上传到对象存储后再启动消费组去拉全量数据这能真实反映对象存储后端对冷读性能的影响。命令用起来很朴素bin/kafka-producer-perf-test.sh \ --topic perftest \ --num-records 50000000 \ --record-size 1024 \ --throughput -1 \ --producer-props acks1 bootstrap.servers10.0.1.10:9092 linger.ms20 \ --print-metrics消费端用消息条数控制退出条件bin/kafka-consumer-perf-test.sh \ --bootstrap-server 10.0.1.10:9092 \ --topic perftest \ --messages 5000000 \ --consumer-props group.idperf group.instance.idconsumer-02.3 对比基线和指标口径为了不把 S3 和 FSxN 的差异归因到 AutoMQ 本身我的对比基线保持同一个 AutoMQ 集群配置只替换对象存储指向。基线 A 使用的是同区域 S3 桶通过 VPC Endpoint 访问减少公网因素干扰基线 B 是 FSxN 的 S3 接口使用子网内 IP 地址访问。指标口径固定在以下几个生产吞吐以 producer 端实际 byte 速率计单位 MB/s观察峰值和 15 分钟平均。生产 ack 延迟producer 从发送到收到 ack 的 p99 延迟。冷读吞吐消费端消费全量历史数据的吞吐。冷读 p99 延迟从发起拉取到首个字节返回的延迟这最能反映对象存储的网络链路质量。段上传完成时间每秒实际产生的流段对象数以及段对象上传完成拖尾延迟。成本模型用每 GB 数据的存储加请求成本做粗略对照。为什么用这么多维度而不是只盯一个峰值因为存储链路方案的关键是权衡不是单个指标。一个后端着高温时稳定冷读却能拖到超时你在生产环境照样不敢用。表格里最后呈现的是两轮稳定压测的数据。3. 核心性能实测结果3.1 生产吞吐与写入时延FSxN vs Amazon S3先说结论在纯生产链路上FSxN 和 S3 没有明显差距。测试数据显示S3 后端下 3 个 broker 聚合生产峰值大概是 1850MB/s 上下FSxN 后端是 1780MB/s 左右差距小于 5%。如果测试时间从 5 分钟拉到 15 分钟这个差距会缩小到 2-3% 以内基本算是噪声区间。这个结果和 AutoMQ 的原理是吻合的。生产者的 ack 并不需要等待段对象上传完成broker 只要把数据写进 WAL 就能返回。所以对象存储后端在纯生产链路里更像是一个“异步排水口”只要它的排水能力能跟上 WAL 产生段的速度不形成反压就不会成为生产者瓶颈。但有一个细节需要注意FSxN 在 WAL 段回收速度上比 S3 略快。原因是段上传完成后AutoMQ 后台还需要对对象存储做一次确认S3 的 API 请求在网络链路上多了 hop确认耗时普遍在十几毫秒到几十毫秒而 FSxN 在子网内直连确认非常快这让 WAL 文件能更早进入清理队列对长时间运行的集群来说本地磁盘占用率会更平稳。生产 ack 延迟两组数据几乎一模一样p99 都在 20ms 左右这再次印证了对象存储没有参与写路径。3.2 消费吞吐与冷读时延内网对象存储的天然优势消费端的数据差异就非常明显了这也是这次测试最有价值的部分。在消费“全量历史数据”这种冷读场景下S3 后端的消费吞吐大概稳定在 1400MB/s而 FSxN 后端跑到了 2200MB/s 以上提升了接近 60%。第一次看到这个数字我也有点意外但拆开看就合理了消费冷数据时broker 需要从对象存储请求段文件S3 长路径上的网络跳数多每次请求的首字节延迟摆动大客户端和 broker 都要迁就这种抖动FSxN 在同一子网内内网带宽像水管子一样直连高并发读取时的速率一致性非常好。冷读 p99 延迟的差距更大。S3 后端在压测高峰期出现过一次 p99 拉到 150ms 以上的情况平时也多在 90-120msFSxN 后端 p99 稳定在 35-45ms。初看 3 倍的差距其实并不玄学S3 的单次 GET 请求在端点转发路径上耗时普遍要 10-20ms一旦消费线程并发拉取多个对象客户端排队等待时间叠加上来p99 被拉高很正常。FSxN 的访问路径是内网直连单个 GET 耗时不到 5ms即使并发翻倍排队时间也远小于前者。这里我给一个生活化类比S3 像你在写字楼里收发快递物业前台会统一分拣一遍FSxN 像是快递直接送到你工位。货多的时候前台分拣再快也要排队而送到工位的模型不会因为写字楼前台拥堵而变慢。3.3 分区迁移与弹性伸缩FSxN 的稳定闸口效应压测的另一个重点剧情是人为停掉一台 broker 观察分区迁移速度。AutoMQ 做分区迁移不需要重新拷贝全量数据它只需要保证 WAL 里的最新段已经上传到对象存储然后新 broker 从对象存储拉取元数据和段索引即可接管。在 S3 后端下一次分区迁移的完成时间平均在 45 秒左右FSxN 后端压缩到了 20-25 秒。为什么会有这个差异迁移过程实际上是和高并发的冷读抢对象存储带宽S3 的带宽和请求限制在这种混合流量下表现不稳定部分请求触发 RestError 导致重试而 FSxN 是 2GiB/s 的预留吞吐把混合流量一视同仁地放行整体像一个稳定的大闸口不会因为突发请求就把个别客户端限流。这个特性在弹性伸缩场景里尤其有价值。比如半夜流量高峰来了你需要快速扩容 broker新节点要迅速从对象存储拉回它负责的分区数据。FSxN 的稳定带宽意味着扩容窗口更可预测不用担心 S3 突发限流把扩容时间从 20 秒拖到 2 分钟。需要注意FSxN 的稳定吞吐不是无限的。如果多个 broker 同时消费冷数据FSxN 2GiB/s 的上限会在某个时刻成为瓶颈。测试里我把消费客户端并发加到 8 台机器后FSxN 后端的消费吞吐反而拉平到 2GiB/s 左右再往上加并发已经不再增长这就是典型的存储带宽打满状态。4. 调优细节与踩坑记录4.1 启用 ONTAP S3 服务时的配置要点FSxN 默认不会把 S3 接口敞开放出来需要先在里面做一次对象存储服务的初始化。操作在 FSxN 的 SVM 上用 NetApp CLI 完成我把关键步骤列在这里命令格式以 ONTAP 9.11 为参考版本不同字段名会略有差异。第一步是创建对象存储服务vserver object-store-server create \ -vserver svm_auto \ -object-store-server-name autos3第二步是创建对象存储账号相当于 S3 的 AccessKeyvserver object-store-server user create \ -vserver svm_auto \ -object-store-server autos3 \ -user fsxobjectadmin \ -groups group1第三步创建 bucketvserver object-store-server bucket create \ -vserver svm_auto \ -bucket autosm-data \ -object-store-server autos3 \ -volume objstore创建完成后客户端访问的 endpoint 是 SVM 在内网里的 IP 地址加端口 8080。需要注意ONTAP S3 默认可以用 HTTP 或 HTTPS 暴露AutoMQ 的 S3 客户端对 HTTPS 证书会把校验严格模式打开我建议在测试阶段直接走 HTTP降低证书自签带来的连接问题。AutoMQ 侧配置时把 endpoint、bucket、账号、密钥填进对应的环境变量即可类似下面这样export S3_REGIONap-southeast-1 export S3_BUCKETautosm-data export S3_ENDPOINThttp://10.0.1.40:8080 export S3_ACCESS_KEYfsxobjectadmin export S3_SECRET_KEYxxxxx export S3_PATH_STYLEtrue特别强调一下S3_PATH_STYLE。ONTAP S3 是路径风格寻址不是 virtual-host 风格如果这个参数没有打开很多客户端 SDK 会尝试把 endpoint 当域名解析连接直接失败。这是第一个坑也是最容易踩的坑。4.2 段上传参数与客户端缓冲怎么调AutoMQ 往对象存储上传的段大小、封段时机和内部的后台上传线程数是可以通过配置控制的但不同版本参数名会更新我这里不写死参数名只讲调优的思路。核心思路是让 FSxN 少处理“小碎片”。对象存储对单个对象的创建请求是有开销的消息量特别大而封段又很频繁时FSxN 每秒要处理的 PUT 请求数量会非常高。我实测发现把单段数据尽量往 1MiB 甚至更大去调大上传的请求次数能显著下降FSxN 的吞吐利用率反而更高。FSxN 这种以文件系统底座做对象存储的服务最怕的是高并发小文件请求这跟普通对象存储怕 “IOPS burst” 是同一个道理。调大地 segment 的代价是本地 WAL 保留时间变长磁盘占用会上升。这时候就需要把 broker 的 WAL 盘规格算对gp3 的吞吐建议开到 400MB/s 以上否则段还在排队上传本地盘先满了生产链路就有被反压的风险。消费端方面如果用户主要场景是消费冷数据建议把消费线程数和 fetch 大小调大。FSxN 对内网带宽友好单线程限制通常不在存储层而在 broker 的内存和网络栈。我在 c6i.2xlarge 上用 6 个消费线程拉数据吞吐比 2 个线程高了快一倍超过 6 个以后基本不再增长说明瓶颈已经转移到客户端处理能力。4.3 几个值得记住的坑配额、网络、NFS 挂载第一个坑是 FSxN 的吞吐预留配额。FSxN 的吞吐能力不是按小时弹性计费的它存在一个明确的预留值。如果你把 FSxN 建出来就用默认的 1GiB/s在高消费流量下会很快打满broker 侧的表现是对象读取经常出现超时重试。我在测试中为了解决这个问题把吞吐配置调到 2GiB/s后面整个压测过程再没出现过对象存储侧的超时。所以容量和吞吐规划一定压在测试阶段做等上了生产才扩容网络抖动窗口会让你怀疑整个架构。第二个坑是跨子网和跨可用区。一开始我把 FSxN 放在子网 Abroker 放在子网 B虽然同 VPC 但跨了可用区冷读延迟 p99 直接从 40ms 涨到了 70ms。后来把 FSxN 的终端节点和 broker 调度到同子网延迟才恢复正常。这个现象不需要过度解读你只需要知道FSxN 的网络路径对时延非常敏感使用上尽量保证它和 AutoMQ broker 在同一可用区内规划。第三个坑是使用 NFS 挂载方式承接 WAL 的尝试。我在选型阶段想过让 broker 直接挂载 FSxN 的 NFS 目录当 WAL 盘这样理论上可以省掉 EBS 成本。实际测试结果很惨单 broker 的生产吞吐最多只能跑到 300MB/s一旦客户端并发上来NFS 的锁和网络往返延迟成为明显瓶颈P99 延迟飙到几百毫秒。AutoMQ 的 WAL 路径对延迟高度敏感这种方案我只建议在低吞吐的内部测试环境使用生产环境用它就会在规模上去的时候把自己坑死。还有一个值得记录的点是 ONTAP S3 的 ListObjects 行为。AutoMQ 在恢复元数据状态时可能会做大范围的 bucket 列举ONTAP S3 的列举结果分页机制和 S3 存在细微差异在大 bucket 下会出现列举变慢。这个问题在 AutoMQ 中可以通过适当拆分 bucket 数量和 topic 分组来规避不要把所有业务 topic 都塞进一个巨大的 bucket 里。5. 从这份报告得出的使用建议5.1 适合把 FSxN 作为 AutoMQ 后端的基本盘如果你的业务有下面几个特征把 FSxN 当作 AutoMQ 对象存储后端是合理选择。第一你的数据有明确的内网留存要求。只要数据不能出 VPC、不能进入平台侧托管存储那么 FSxN 这种真正活在 VPC 里的文件服务天生有这个优势。第二你的消费模型偏重“历史数据重放”和“全量回溯”。从前面数据可以看到FSxN 冷读吞吐比 S3 高出 60%P99 延迟低了三分之一这种场景下用户体验提升非常明显实时消息系统的下游有离线分析任务时提速就是省钱。第三你的组织已经买了 FSxN并且运维团队熟悉 NetApp 体系。复用现有存储底座不用额外管一套 S3 bucket 生命周期和权限策略运维心智负担会小很多。第四你更希望成本是线性可预测的。FSxN 的固定容量加吞吐包对消息量天花板能估算的团队来说不会像 S3 那样出现某个月底被请求费吓一跳的情况。5.2 不适合或需要谨慎投入的场景也有几类场景我不建议无脑抄这份报告。如果你的消息量是极低频但条数巨大比如每天只在凌晨批量导入几百 GB 数据其他时间基本空闲S3 按量计费的模型更省钱。FSxN 你得为峰值保留吞吐但多数时间它在空转。如果你的业务高度依赖 S3 的高级生态比如桶事件通知触发 Lambda、对象版本控制、跨区域复制、S3 生命周期策略那不要选 FSxN。ONTAP S3 提供的是协议级兼容不是控制台级功能复刻那些高级功能要么没有要么行为存在差异。FSxN 更适合把对象存储当纯数据底座用的人。如果你的消费峰值超过你在 FSxN 上预留的带宽上限而系统又不能接受扩容窗口那你需要一个更弹性的对象存储。FSxN 的扩吞吐往往伴随底层数据调度不是一分钟内就能生效的事情。5.3 一些可以继续深入的方向这次测试没有覆盖的还有几个值得后续挖的点。一个是大规模的跨可用区高可用。我的测试只在同一个可用区完成生产环境里一般需要 FSxN 做成跨可用区的数据保护模式这种模式下写入路径增加复制动作对 AutoMQ 上传段的时延会有多大影响需要单独压。另一个是故障恢复的极限场景。我模拟了单台 broker 宕机但没有模拟整个 FSxN 文件系统故障。AutoMQ 依赖对象存储的持久性FSxN 一旦出问题整个集群的可用性窗口是多长这必须有预案不能靠运气。还有一个是成本模型的细致测算。FSxN 虽然请求费低但基础容量费和吞吐预留费一样要算进每 GB 存储成本。对长时间保留数据、但很少被读取的消息S3 的冷存储分层可能仍然更便宜。这个适合结合你们的真实留存策略来做账。我个人实际做完这轮测试后的体会是AutoMQ FSxN 是一个可选组合但不应该是默认组合。默认场景下S3 依然是最省心、最弹性的对象存储选择只有当数据控制权、网络链路和消费吞吐成为硬性需求时FSxN 才值得你花时间调优。最后一个建议是无论你选哪一个都不要只信宣传数字用你自己的流量模型把压测完整跑一轮存储选型这种事看再多报告都不如数据打在面前来得踏实。