S3 是文件,但不是文件系统
S3 是什么(以及不是什么)
- 广泛共识:S3 是对象存储 / 键值存储,不是传统文件系统。
- 核心模型:键 → 对象的扁平映射;键是不可解析的字符串,操作是对整个对象进行 GET/PUT/DELETE。
- POSIX 风格语义(inode、作为一等对象的目录、部分写入、原子重命名)从设计上就不存在。
- 也有人认为从广义上说,S3 仍算是“一种文件系统”(“管理文件的系统”),但另一些人坚持这样会稀释这个术语,并让用户产生错误预期。
“文件夹”和路径语义
- S3 没有真正的目录。控制台里的“文件夹”只是基于键前缀的 UI 包装,有时通过 0 字节的“标记”对象来实现。
- 后果:
- 你可以同时拥有
dir、dir/file、dir//file这样的键;斜杠对 S3 来说并不特殊。 - 当删除最后一个带有该前缀的对象时,空的“文件夹”就会消失。
- 重命名一个“文件夹”需要复制并删除该前缀下的每个对象(O(对象数量),且不是原子操作)。
- 你可以同时拥有
操作、性能与列举
- 不支持原地修改或追加;必须重新上传修改后的内容,或者在更高层进行分块。
- 复制和重命名通过 copy+delete 实现,其成本和延迟会随对象大小增长。
- 列举是一个重大的语义和性能差异:
- S3 按前缀和字典序列出,并支持分页;对于基于前缀的扫描和分区,效率可以非常高。
- 递归的、POSIX 风格的目录遍历很慢,需要大量顺序的 list 调用;删除或清空大型 bucket 可能既昂贵又复杂。
在 S3 上运行数据库和文件系统层
- 直接在 S3 上运行传统数据库通常被认为不合适:延迟高、缺少部分写入、没有原子的“若不存在则写入”。
- 成功的模式:
- 只追加或将文件视为不可变分片的系统(例如分析引擎、像 Delta/Iceberg/Hudi 这样的表格式)。
- 使用 S3 作为数据平面、同时配备独立且强一致的元数据/索引层的架构(例如在 S3 上使用 WAL,再配合本地缓存的数据库,或外部元数据服务)。
- FUSE 和 VFS 层(例如 rclone、自定义文件系统)通过本地缓存、分块以及在别处管理元数据来模拟 POSIX——有用,但复杂且容易泄露抽象。
持久性、成本与替代方案
- S3 的持久性受到高度赞扬;被描述为业界领先,使用大量校验和和复制,但没有引用第三方、类似 Jepsen 的验证。
- S3 通常被认为适合大规模、冷数据且成本较低;也有人指出存在更便宜的对象存储,但可能会以可靠性或功能为代价。
- 若需要真正的文件系统语义和低延迟,评论者会指向 EBS/EFS/FSx 或本地文件系统;若想要“像 S3 但更简单”的本地方案,则会建议对象存储服务器或自定义层。