评审存储方案的时候,有三类需求最常见:把 MySQL 的数据目录挪过去、给虚拟机提供磁盘、给全公司当一个共享网盘。这三类需求听着都像"存东西",但对象存储对其中两类是接不住的。先分清三种存储各自承诺了什么,再决定要不要上 S3,比先选产品再补课省事得多。
块、文件、对象,接口语义先分清
块存储承诺的是"一块磁盘":应用拿到的是一段固定大小的 LBA 地址空间,可以原地覆写任意扇区,数据库靠这个语义和 fsync 配合保证事务落盘。文件存储承诺的是"一棵目录树":POSIX 语义,重命名、目录遍历、文件锁都是基本操作。对象存储承诺的是另一套东西:扁平的 key,通过 HTTP 接口以整个对象为单位做读写。
这三种承诺没有高低之分,差别在语义。数据库要的是第一种,共享目录要的是第二种,S3 提供的是第三种。
数据库和虚拟机的盘,放不进去
把 MySQL 的 datadir 放到对象存储上,最先撞上的是覆写语义。S3 的 PUT 是整对象替换,改一个 16KB 的页也要重写整个对象,InnoDB 每秒成百上千次的页修改会把这个放大量放大到不可用。虚拟机磁盘同理,qemu 需要的是块设备语义,随机写、discard、精简置备,这些在对象接口上都没有对应物。
RustFS 的协议列表是 S3、WebDAV、FTP(S)、Swift 和 MCP,里面没有块接口。这不是功能缺失,是定位:它服务的是"整对象"的工作负载。虚拟机磁盘和数据库盘,该留在块存储或本地盘上。FTP(S)、Swift 这两个协议也在列表里,但都改变不了结论:FTP 传的还是整文件,Swift 说的还是对象语义。列表里真正的分界线是 WebDAV,它把目录和重命名这两个文件操作带了进来,下一节展开说。
共享目录的需求,WebDAV 能接一部分
部门共享盘是中间地带。RustFS 内置了一个 WebDAV 网关,编译在标准二进制里,支持 PROPFIND 列目录、MKCOL 建目录、PUT 上传、GET 下载、MOVE 重命名、DELETE 删除。Windows 资源管理器、macOS Finder、GNOME Files 都能直接挂:
| 客户端 | 地址写法 |
|---|---|
| Windows 资源管理器 | https://<host>:8080/ |
| macOS Finder | http://<host>:8080/ |
| GNOME Files | dav://<host>:8080/或davs://<host>:8080/ |
认证用的是 HTTP Basic,用户名和密码就是 RustFS 的 access key 和 secret key,网关拿它过一遍 IAM,用户自己的 S3 策略对每个操作照样生效。授权失败的 MOVE 不动源对象,这点比很多自建网盘实现得干净。MOVE 的代价也要先有预期:S3 层没有重命名原语,官方对 MOVE 的权限要求是读取和删除源对象、写入目标位置,这个组合暴露了它的本质,落到底层就是复制加删除。大对象改名等于一次完整搬运再加一次删除请求,开销和文件体积成正比;POSIX 那种纯元数据的轻量重命名,在这条路上不存在,把重命名当轻操作反复做的应用会先撞上它。
上传体积也有一条线:WebDAV 走单次 PUT,RUSTFS_WEBDAV_MAX_BODY_SIZE默认 5 GiB 封顶,放文档、安装包、设计源文件都够用;几百 GB 的数据集备份这类大件,脚本里走 S3 接口做 multipart,就不受这条线管。
边界也要说清楚:WebDAV 补的是目录和重命名这类文件操作,POSIX 文件锁和局部覆盖依然没有。官方支持的方法列表里没有 LOCK,多客户端同时写同一路径也没有冲突保护,后完成的写入直接盖掉先完成的,双方都不会收到任何提醒。共享盘场景要防这个,要么按人划目录各写各的,要么明确接受最后写入者赢的规则。还在用 Excel 共享编辑、依赖文件锁的老应用,这条路走不通。客户端侧还有一个甩不到存储头上的坑:Windows 自带的 WebDAV 客户端在大文件和高延迟链路上历来不稳,这类超时和中断多半出在客户端层,排查时别急着把锅扣到服务端,官方文档给的排查法是用 curl 直连隔离问题,curl 通了而资源管理器不通,答案就在客户端那头。另外文档明确写了,对目录发 GET 请求会返回405 Method Not Allowed,列目录要用 PROPFIND,有些老客户端默认发 GET,挂载失败先查这里。列举的语义也和目录树不同:PROPFIND 沿着层级往下走,S3 的 ListObjects 是拿前缀在扁平 key 空间里分页扫,走的是两条完全不同的路径,从文件系统脚本迁过来的工具要重看这一段。
对象存储接得住的活
写一次、读多次的场景是对象存储的主场:备份包、容器镜像、视频素材、训练数据集、日志归档。拿 MySQL 说,同一个数据库的两种形态在这里分家:datadir 是运行中的数据目录,靠原地覆写活命,前面说过它放不进来;mysqldump 出来的备份包是写一次读多次的整对象,天生就是这层的主场。同一个库,形态不同,答案相反,评估前先分清手里的是哪种。RustFS 在这些场景上的能力有测试背书,官方 S3 兼容矩阵里版本化、对象锁、range 读取、multipart 上传都在已测试列表里。对象锁给归档数据提供 WORM 语义,range 读取让大文件不用整个拉回来。还有一样常被忽略的能力:事件通知。桶上配好规则,对象上传、删除这类事件可以推到 webhook,解析管线拿它做触发器,文件一落存储下游就开工,轮询都省了。这套通知跟 WebDAV 那条路不冲突:人从网盘拖一个文件进去,程序照样收到事件。这些管理能力落到选型判断上也很直白:备份包要回滚到上周,是版本化的活;归档数据要防篡改,是对象锁的活;文件一落存储就要触发下游,是事件通知的活。过去在文件系统边上写脚本维护的那套杂务,在这里变成桶的属性,跟着桶走,不跟着客户端走。
配置 WebDAV 网关的完整参数是这五个,TLS 默认是开的:
exportRUSTFS_WEBDAV_ENABLE=true# 默认 falseexportRUSTFS_WEBDAV_ADDRESS=0.0.0.0:8080# 默认 0.0.0.0:8080exportRUSTFS_WEBDAV_TLS_ENABLED=true# 默认 trueexportRUSTFS_WEBDAV_CERTS_DIR=/path/to/certs# 开 TLS 必填exportRUSTFS_WEBDAV_MAX_BODY_SIZE=5368709120# 默认 5 GiBS3 那条路不需要任何开关,主监听端口 9000 自带 S3 API。同一个集群,程序走 9000 的 S3 接口写备份包,人走 8080 的 WebDAV 挂网盘看文件,两条路落到同一份数据上。写入模型也顺带说一句:S3 没有文件锁的概念,并发写的正确姿势是各写各的对象,key 不同就互不干扰,撞同一个 key 才有覆盖问题。备份、日志、镜像仓库这类工作负载天然就是各写各的,这正是它们和对象存储合得来的底层原因。
拿需求对表
判断顺序建议倒过来走:先列出应用对存储做的每一种操作,出现原地覆写、文件锁、高频重命名,这份数据留在块或文件存储;操作全是整对象的 PUT/GET/DELETE,对象存储就够,而且备份、版本化、生命周期这些管理能力是白送的。
拿不准的应用有个成本很低的验证法:把它的存储操作在 RustFS 的 S3 接口上跑一遍冒烟测试,哪一步的语义对不上,哪一步就是分界线。这套验证用mc加一个 alias 十分钟就能跑完,比上线后发现日志写不进去再回退便宜得多。语义对不上的操作清单,也是日后跟团队解释"为什么这块不上对象存储"时最省力的材料。
验证用的接口清单不用凭记忆列,官方文档的 S3 兼容矩阵把已测试与计划中的能力逐项分开写。RustFS 的 1.0.0 正式版在 2026 年 9 月 16 日发布,版本化、对象锁、事件通知都已生产可用,源码在 GitHub 的 rustfs/rustfs 仓库。