RustFS 平替 MinIO:S3 对象存储部署与选型对比
替换背景与结论
MinIO 社区版已从 Docker Hub、quay.io、dl.min.io 全面下架:dl.min.io 二进制地址返回 410,Docker Hub 上 minio/minio 任意 tag 均为 not found,quay.io/minio/minio 返回 401。逐个试 tag 只会浪费时间,应先确认上游已整体下架。
因此把对象存储换成 RustFS:同为标准 S3 API,端口布局与 MinIO 一致(9000 / 9001),鉴权走标准 SigV4,可以做到业务侧零改动迁移。
保留历史命名的原因很直接——容器名仍是 **milvus-minio,服务名仍是 minio**,它与 Milvus 已无关系;它现在是 OSS 的唯一文件实体存储,挂在 app 网络供两个后端访问。这样 Milvus 的 MINIO_ADDRESS=minio:9000、应用侧 MINIO_* 系列配置、密钥、端口全部不用改。
RustFS 是什么
名称与项目归属
不是 MinIO 改名,也不是 MinIO 的 Fork,而是一个独立的全新项目:
-
Rust:从零用 Rust 编写,底层存储引擎、元数据、内存模型、GC 全部自研,没有复用 MinIO 的 Go 源码。
-
FS:File System,做对象存储,对外提供 S3 文件语义。
-
许可:Apache 2.0,修改与分发没有 AGPLv3 那样的强制开源义务。
-
归属:独立开源项目,与 MinIO Inc 无隶属、赞助或商标关系;官方也明确澄清过这一点。
它为什么和 MinIO 长得这么像
因为它刻意对齐了 MinIO 的运维习惯,就是为了让存量系统平滑迁移:
-
端口对齐:9000 为 S3,9001 为 Console。
-
环境变量与凭据习惯对齐,
RUSTFS_ACCESS_KEY/RUSTFS_SECRET_KEY对应原来的 accessKey / secretKey。 -
单盘、多盘、分布式纠删码三种模式的用法模仿 MinIO。
-
mc工具可以直接拿来操作,绝大多数子命令正常。
它只兼容标准 S3 API,MinIO 的私有扩展(桶通知、ILM 私有接口、S3 Select、部分管理接口)并不存在,选型与测试时必须把这一点纳入验证范围。
Docker Compose 部署配置
下面这段直接替换原来 minio 那一段即可,服务名、容器名、端口、网络与历史配置保持一致。
services:
minio:
image: rustfs/rustfs:1.0.0
container_name: milvus-minio
hostname: minio
restart: unless-stopped
ports:
- "9000:9000"
- "9001:9001"
environment:
- RUSTFS_VOLUMES=/data
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_ACCESS_KEY=minioadmin
- RUSTFS_SECRET_KEY=minioadmin
- RUSTFS_OBS_LOGGER_LEVEL=warn
volumes:
- ./rustfs-data:/data
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:9000/health"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app
networks:
app:
# 与现有 compose 的 app 网络配置保持一致
关键配置说明
-
数据目录:
RUSTFS_VOLUMES=/data声明数据卷;早期写法用command: /data,两者等价,二选一即可,不要重复声明。 -
端口映射:集群内部通信走
minio:9000,若只在 compose 内部互通,ports可以注释掉;但需要浏览器直连预签名地址时,必须把 9000 映射到宿主机。 -
版本锁定:不要长期用
latest。锁定具体 tag,并避开发布早期存在漏洞的 beta 版本;实测rustfs/rustfs:1.0.4可正常启动、建桶、上传下载。 -
探活:
GET http://127.0.0.1:9000/health返回 200 即就绪,可直接作为 healthcheck。
启动后的可用性验证
# 1. 探活
curl -fsS http://127.0.0.1:9000/health
# 2. 配置 mc 别名并建桶
mc alias set rustfs http://127.0.0.1:9000 minioadmin minioadmin
mc mb rustfs/oss # RustFS 不会自动建桶,必须先建
# 3. 上传后从宿主机直接下载,确认 200 且内容一致
mc cp ./test.txt rustfs/oss/test.txt
RustFS / MinIO 社区版 / SeaweedFS 完整对比
| 对比项 | RustFS | MinIO(社区版) | SeaweedFS |
|---|---|---|---|
| 开发语言 | Rust | Go | Go |
| 许可证 | Apache 2.0,商业友好,无强制开源义务 | AGPLv3,网络分发与托管服务的衍生代码需开源 | Apache 2.0,商业友好 |
| 项目归属 | 独立新项目,不是 MinIO Fork | MinIO Inc 官方项目,社区版已冻结,重心转向商业版 AIStor | 独立开源项目,长期活跃 |
| 核心架构 | 对等节点 + Set 纠删码,无中心元数据节点,S3 与控制台单进程一体化 | 同上,最成熟稳定,池化扩容 | 三层:Master + Volume Server + Filer,存在中心元数据角色 |
| S3 兼容范围 | 标准 S3 SigV4、桶与对象、分片上传、版本、生命周期;无 MinIO 私有扩展 | 标准 S3 + 大量私有扩展:桶通知、站点复制、ILM、S3 Select、内部运维接口 | S3 网关模式,支持 IAM、STS、对象锁、服务端加密;底层是 Filer 网关包装 |
| 默认端口 | 9000(S3)/ 9001(Console),与 MinIO 完全一致 | 9000 / 9001 | 无固定 9000 / 9001 约定,控制台独立 |
| mc 工具兼容 | 可直接使用,大部分命令正常 | 原生支持 | 可用,部分 MinIO 专属子命令不支持 |
| 纠删码 EC | 原生内置,按 Set 划分,启动时固定 Set 布局 | 原生内置,成熟,按 Pool 扩展 | 社区版固定比例 EC,企业版可自定义;读放大为 O(1) |
| 单节点部署 | 支持单盘 / 多盘单机,适合 Milvus 附属存储 | 非常成熟 | 一键启动,但 Master 仍是单点 |
| K8s 生态 | 官方 Helm Chart,支持 StatefulSet | 官方 Operator,生态最强 | Helm,社区维护 |
| 控制台 UI | 自研,简洁;桶管理、密钥、日志等基础功能为主 | 功能极强,运维、监控、策略、复制、告警齐备 | 基础 WebUI,重心在 S3 与 FUSE |
| 小文件场景 | 一般,对象存储思路,与 MinIO 接近 | 一般 | 强项,原始设计即解决海量小文件,亿级规模优势明显 |
| 大文件 / AI 数据集 | Rust 无 GC 抖动,尾延迟稳定,NVMe 下吞吐表现好 | 成熟稳定,高并发下 Go GC 有延迟抖动 | 可用,但不是为大对象流式场景设计 |
| 元数据瓶颈 | 分散在各 Set,无中心瓶颈 | 分散在各 Pool,无中心瓶颈 | 瓶颈在 Filer / Master,海量文件时是上限 |
| 扩容逻辑 | 新增 Set;Set 创建后磁盘数量不可改 | 新增 Pool;Pool 内规模固定,不能在线扩盘 | 可直接新增 Volume 节点,扩容更灵活 |
| 站点跨集群复制 | 支持,逐步完善 | 成熟稳定,企业级核心能力 | 支持,机制不同 |
| S3 Select | 暂不支持 | 原生支持 | 不支持 |
| 桶通知 / Webhook | 标准 S3 事件部分支持,无 MinIO 专属通知 | 完善,Kafka / Redis / Webhook 等 | 支持标准 S3 事件 |
| POSIX / FUSE | 不支持,纯对象存储 | FUSE 为额外扩展 | 原生 FUSE,同一份数据同时支持 POSIX、S3、HDFS |
| Iceberg | 内置 Iceberg REST Catalog(特色) | 需外部组件 | 支持 S3 Tables |
| 成熟度 | 已 GA,新项目迭代快,社区规模中等,踩坑文档偏少 | 社区版停止维护,镜像下架,存量可用、新部署不建议 | 多年稳定项目,生产案例多 |
| 是否适配 Milvus 场景 | 最合适:零改配置、端口对齐、mc 直接可用、Apache 2.0 | 不适合新部署:镜像拿不到、许可风险、停更 | 能用,但要改 endpoint 与端口、部署更重,没有必要 |
选型建议
-
只要能平替 MinIO、不改代码与配置:选 RustFS。代价是放弃 MinIO 私有扩展(桶通知、S3 Select 等),只依赖标准 S3;项目较新,运维案例不如老牌方案多。
-
海量图片 / 小附件、需要 FUSE 挂载、要 POSIX 文件访问:选 SeaweedFS,但它的 Master 是单点,生产必须做 Master 集群。
-
MinIO 社区版:只适合存量老集群继续运行。许可(AGPLv3)+ 停更 + 镜像下架三重问题,新项目不要再上;如果产品是对外托管的 SaaS,AGPLv3 风险尤其高。
迁移踩坑清单
部署与运维
-
不自动建桶:RustFS 与老 MinIO 一样不会自动创建 bucket,Milvus 启动前必须预建,否则 Milvus 侧报桶不存在。最好用 init 容器一次性建好。
-
Set 规模一次性定死:和 MinIO 相同,Set 创建后不能增减磁盘,规划集群时就要定好每个 Set 的盘数。
-
控制台不一样:UI 是 RustFS 自研,基础上传与桶管理够用,但和 MinIO Console 的操作路径不同,交接文档要重写一遍。
-
混合配置里别留 MinIO 残留:加密、站点复制、ILM 的私有配置项搬到 RustFS 会直接失效,迁移时清理掉。
SigV4 与预签名地址(手写签名时的高频故障)
-
建桶请求的规范 URI 不带尾斜杠:真实请求是
PUT /bucket,按/bucket/计算签名会返回SignatureDoesNotMatch403,而上传对象却正常,很容易误判成凭据错误。 -
附加 query 参数必须参与签名:如
response-content-disposition要放进 canonical query 一起算,签完再拼会表现为「地址能生成但下载 401 / 403」。 -
对外端点与内部端点分开配置:签名只与 host 有关。服务端调用走
minio:9000,预签名地址必须用宿主机可访问的对外端点,否则签出来的链接浏览器打不开。 -
验证方式:上传后从宿主机
curl下载,确认 HTTP 200 且内容与上传一致;只看上传返回 200 不足以证明签名正确。
(注:部分内容由豆包工作 AI 生成)
