ZeroFS vs. Amazon S3 Files
AI 深度解读
背景
云对象存储(如 Amazon S3)以其高耐用性、低成本和大规模可扩展性成为存储基础设施的主流选择,但传统的 POSIX 文件系统接口与 S3 的扁平键值模型之间存在根本性差异。近年来,出现了多种试图在对象存储之上提供 POSIX 语义的解决方案,其中 Amazon S3 Files(基于 Amazon EFS 构建)和开源项目 ZeroFS 是两种截然不同的设计。两者都通过挂载点暴露 POSIX 文件系统,底层依赖对象存储,但它们在存储布局、对象互操作性、性能和成本等方面做出了不同的权衡。这篇来自 Hacker News 的讨论深入比较了这两种方案,尤其关注用户应根据场景如何选择。
核心内容
存储布局
S3 Files 的核心特性是保持文件与对象的一一对应关系:挂载点上的 images/cat.jpg 在底层 S3 存储桶中对应同一个键名,且双向同步变更。活跃数据和元数据位于 AWS 所谓的“高性能存储”低延迟层中。换言之,在 S3 Files 中,写入挂载点的文件最终会成为一个普通的 S3 对象,GetObject 可以直接读取。
ZeroFS 则刻意放弃了这种一一对应关系。其元数据存储于 LSM 树(Log-Structured Merge-tree)中;文件内容被分割成多个 extent,经过压缩和加密后,打包到不可变的 segment 对象中。从 S3 客户端视角看,存储桶内是一个不透明的内部布局,而非挂载的文件结构。这意味着无法通过 S3 API 直接获取 ZeroFS 挂载下的文件路径。
两种挂载都使用客户端页面缓存(page cache)。以下性能对比中的写操作路径从客户端发送写入到服务器之后开始计算。
对象互操作性
保持一一映射意味着通过 S3 Files 挂载写入的文件,经过约 60 秒无写入的静默期后,会导出(export)为普通 S3 对象,从而可以被现有工具通过 GetObject 读取。在导出完成前,持续写入会推迟 S3 可见性。如果导出过程中,S3 侧和文件系统侧同时修改同一文件,S3 侧会胜出,文件系统侧的版本会被移至 lost+found 目录。
ZeroFS 的路径名无法通过 S3 API 获取,segment 也无法作为 Parquet 文件扫描。作为交换,小文件不需要为每个文件创建一个数据对象或执行一次 PUT 操作:它们的 extent 被压缩、加密并打包在一起。存储桶和原始本地缓存中只包含密文,因此挂载或恢复必须使用 ZeroFS 及其加密密码。其加密文档列出了哪些结构元数据仍然可见。
如果其他应用需要在文件系统写入后立即通过 S3 API 看到数据,两种方案都无法满足:S3 Files 的导出是异步的,而 ZeroFS 从不通过 S3 API 暴露挂载的文件。
冷访问
首次访问 S3 Files 挂载的文件时,可能会触发导入(import):列出目录会加载每个对象的元数据,并异步将小于默认导入阈值(128 KiB)的文件复制到高性能存储中。AWS 表示,首次列出 1000 个对象可能需要几秒钟。更大的文件保留在 S3 中,读取至少 1 MiB 的数据会直接通过 S3 进行。
ZeroFS 则通过读取和上传来填充本地 RAM 和磁盘缓存。新密封的 segment 从已持有的字节进入缓存,因此写后读不需要 GET 请求;缓存不是写回(write-back)的,写入仍然会在 segment 密封和元数据刷盘时到达对象存储。冷未命中时,通过 LSM 树解析请求的 extent,并将相邻的帧合并为范围 GET 请求。它只支付第一次对象存储往返的开销,而不会导入整个文件或目录下的所有小文件;一旦工作集在本地缓存中,数据读取几乎不产生 S3 请求。
两种方案都支持顺序访问的预读(read-ahead):ZeroFS 在 segment 对象内和跨 segment 对象预取,S3 Files 则依赖 Linux NFS 预读以及其直接 S3 路由。
成本
两种方案都需要支付 S3 存储和请求费用。S3 Files 额外收取高性能存储层的费用:按月计算的每 GB 驻留存储费,以及每 GB 的读写费。AWS 在发布时提供的定价示例使用了以下费率:
- 高性能存储驻留:每 GB 每月 $0.30
- 文件系统写入:每 GB $0.06
- 文件系统读取:每 GB $0.03
驻留在高性能存储中的数据量取决于配置的导入阈值和过期窗口。列出操作会导入元数据和符合条件的小文件,读取操作可能加载更多数据,而文件元数据永不过期。导入按文件系统写入计费,导出按读取计费;最小操作大小:文件数据 32 KiB,元数据 4 KiB。AWS 在 CloudWatch 中报告驻留字节数和 inode 数,但仅靠存储桶总大小无法预测账单。
说明性模型:存储 10,000 GiB 并读取一次
这是一个说明性场景,并非通用成本比较。假设在 us-east-1 区域的 S3 Standard 中存储 10,000 GiB 逻辑数据,单价 $0.023/GB/月。直接场景假设读取 1 MiB 的数据已存在于 S3 中;驻留场景假设读取小于 1 MiB 且所有数据也在高性能存储中。排除互联网出口流量。
ZeroFS 的数值为估算值:压缩减少有效载荷字节,而元数据、临时合并数据以及请求会增加成本。在理想的 8 MiB GET 大小下,以 2:1 压缩率读取文件数据成本约 $0.26,以 1:1 压缩率约 $0.51,这还未计入元数据以及短读取或随机读取。ZeroFS 还需要一台服务器(高可用性需要两台)以及本地磁盘缓存;每个节点除配置的内存缓存外,还需要约 2 GB 的 RAM。因此,对于大文件流式读取,S3 Files 的成本可能更低。当数据被导入或通过高性能存储写入时,差异会进一步扩大:通过 S3 Files 写入 10,000 GiB 将增加 $600 的文件系统写入费和 $300 的导出费,而一个月的驻留费为 $3,000。
实际成本取决于文件数量、压缩率、I/O 大小、驻留时间、fsync 频率以及基础设施。S3 Files 还需要开启存储桶版本控制,因此非当前版本需要配置适当的生命周期规则。
fsync 与 S3 可见性
在 S3 Files 中,持久化(durability)和 S3 可见性是两个独立的事件。写入高性能存储后立即获得持久化,但导出仅在大约 60 秒无写入后开始;调用 fsync 不会使对象立即通过 S3 API 可见。ZeroFS 没有第二个可见性事件,因为不存在导出步骤。在 9P 协议中,成功的 fsync 会在对象存储确认数据段及其 LSM 元数据后返回,从而确保文件在冷重启后仍可恢复。
重命名
S3 没有目录概念,也不支持通用存储桶的原子重命名。S3 Files 在挂载点上执行重命名时,会复制每个受影响的对象到新键名,并删除旧键名;在目录重命名期间,两个前缀都可能可见。AWS 表示同步 100,000 个重命名文件需要几分钟。ZeroFS 只更改 LSM 目录条目,无需为每个子文件复制,也不会向对象客户端暴露任何 S3 前缀。
关键要点
- 存储布局差异:S
