跳到正文

目录

RustFS:用纠删码而不是 Raft 的 S3 对象存储,MinIO 的 Apache 2.0 替代

RustFS:用纠删码而不是 Raft 的 S3 对象存储,MinIO 的 Apache 2.0 替代

先把一个常见误解纠正掉:RustFS 不是"Raft 共识的分布式文件系统"。仓库描述、README 与源码三方一致——它是一个 S3 兼容的分布式对象存储,用 Rust 写成,数据持久性靠 Reed-Solomon 纠删码保证,对标的生态位是 MinIO 与 Ceph 的对象存储部分。全仓库 52 个 workspace crate 里没有任何 Raft 实现,“raft” 一词的词边界命中只出现在 KMS 测试文件里,指的是外部依赖 HashiCorp Vault 自己的 Raft 存储。

把它认成文件系统不奇怪——GitHub topics 里它确实挂着 filesystem 标签,URL slug 也带着 file system 的历史痕迹。但对象存储和文件系统是两类接口:前者暴露的是 bucket + object + S3 API,应用通过 AWS SDK、rclone、mc 这类客户端读写;不提供 POSIX 挂载。理解这一点,后面所有设计才说得通。

本文基准两个时点:文章初稿发布于 2026-04-12,当时 RustFS 处于 1.0.0-alpha.93;2026-10-05 复核时最新版本是 10 月 3 日发布的 1.0.1。半年间项目从"分布式模式还在测试"走到了"全部核心特性转正",变化不小,文中按时点分别标注。

系统地图:一个进程,四个端口面

一个 RustFS 节点启动后暴露的东西(出自仓库 ARCHITECTURE.md):

面端口/通道职责
S3 API9000对象读写主数据路径
Admin API9000(/minio/ 前缀)集群管理、IAM、指标
Web Console9001浏览器管理界面,背后调 Admin API
节点间 RPCgRPC(tonic)分布式模式的集群通信

沿用 /minio/ 前缀不是巧合。RustFS 把"MinIO 平滑迁移"当成一等目标:启动序列第一步就是环境变量兼容转换(MINIO_* 映射到 RUSTFS_*),磁盘上的对象格式也与 MinIO 同族(后文细说)。官方对比表里它对 MinIO 的差异化卖点主要有两条:Apache 2.0 对 AGPL v3(MinIO 2021 年改 AGPL 后,很多公司需要一份宽松许可的替代),以及无遥测(README 原话:防未授权跨境数据外流,自述符合 GDPR/CCPA/APPI)。

代码组织是一个 Cargo workspace,52 个 crate 按域分组:纠删码存储引擎(ecstore)、元数据(filemeta)、修复(heal)、生命周期(lifecycle)、复制(replication)、IAM/KMS/加密、S3 Select、通知、可观测性,外加 FTPS/WebDAV/SFTP/Swift 这些协议扩展。分层规则写进了架构文档:请求自上而下穿过 server → admin/app → storage → ecstore → rio/io-core,禁止反向 import,用脚本在 CI 里守住。

数据可靠性:纠删码的账是怎么算的

RustFS 的容错不靠主从复制,靠纠删码。每个对象写入时被切成分片,加上校验分片,摊到一个纠删集(erasure set)的 N 块盘上。官方规范文档(docs/architecture/erasure-coding.md)把算法和兼容契约写得很硬,几个关键数字:

  • 编解码:Reed-Solomon over GF(2⁸),Vandermonde 生成矩阵,实现是 rustfs-erasure-codec(reed-solomon-erasure v8 的 fork)。这与 MinIO 用的方案同族,正是磁盘格式互通的基础。
  • 集合大小:N 限定在 2 到 16 之间(单盘部署是例外,N=1、无校验)。
  • 默认校验分片数按盘数走:N≤1 时 0,2–3 盘 1 片,4–5 盘 2 片,6–7 盘 3 片,8 盘及以上 4 片。可以用存储类覆盖——STANDARD 与 REDUCED_REDUNDANCY 两档,配置格式 EC:<parity>,也支持 RUSTFS_STORAGE_CLASS_STANDARD 环境变量。注意 AWS 那套 GLACIER、INTELLIGENT_TIERING 标签会被直接拒掉,RustFS 不实现它们的语义。
  • 读写仲裁:数据分片数 = N − parity。读仲裁等于数据分片数;写仲裁也是数据分片数,仅当数据分片恰等于校验分片时加一——对称切分时不允许刚好踩着数据仲裁线提交。
  • bitrot 保护:每分片带 HighwayHash-256 校验和,静默损坏在读取和 heal 时被识别。

拿一个具体部署算一遍:16 块盘、默认 parity 4,则数据分片 12。任意 12 个分片可重建对象,一组盘最多坏 4 块不丢数据;写入需要 12/16 个分片落盘才算成功。存储开销是 16/12 ≈ 1.33 倍,对比三副本的 3 倍,这是纠删码在容量上的基本盘;代价是重建时要从多块盘并行读。

修复侧有独立的 scanner 和 heal 子系统:扫描器按节奏巡检元数据与数据一致性,发现缺失或损坏分片后由 heal 重建。1.0 后这组能力全部转正,官方还给了扫描器节流、驱动超时等一整套调参文档(docs/operations/ 下 scanner-runtime-controls、drive-timeout-tuning 等)。

一次 PUT 的完整路径

把上面的结构串起来。当客户端发起一次 PutObject:

  1. server/ 层接 HTTP,做 TLS 终结、认证(SigV4)、路由与压缩;
  2. app/object_usecase 做校验,套用策略与生命周期规则;
  3. storage/ecfs 做纠删码编码、服务端加密、校验和计算;
  4. ecstore 选盘池、按对象键哈希选纠删集(V1 用 crc_hash,V2/V3 用带格式 ID 种子的 sip_hash),决定分片落位;
  5. rio 管道执行加密 → 压缩 → 哈希 → 写;
  6. io-core 从缓冲池供给内存、做准入控制,最后落到本地盘或经 gRPC 落到远端盘。

这套层次在 ARCHITECTURE.md 里有明文,行号没引——文档自己说了,行号在重构里活得比符号名短,引用一律落到文件与符号。另一个值得注意的诚实细节:同一份文档专设 “Known Structural Issues” 一节,自曝 ecstore 是个 265 文件、约 28.8 万行的单体(约一半是内联测试),拆分计划挂在 docs/architecture/ecstore-module-split-plan.md。一份敢把自家架构债写成规范文档的项目,读源码时心里有底。

一年走完 1.0:版本线与转正清单

RustFS 的发版节奏非常密。从 releases 页能排出这条线:

时点版本事件
2025-07-021.0.0-alpha.1releases 起点,与 crates.io 包名注册同日
2025-07-161.0.0-alpha.23两周发了 23 个 alpha
2026-04-101.0.0-alpha.93本文初稿发布时点的最新版
2026-04-291.0.0-beta.1alpha 线收官(累计 99 个 alpha),进入 beta(共 15 个)
2026-08-08 ~ 09-111.0.0-rc.1 ~ rc.6六轮候选
2026-09-161.0.0正式版
2026-10-031.0.1复核时最新

一年出 122 个 release,平均不到四天一个,这个节奏本身就说明项目处于高强度迭代期——采用时对"当前版本的行为"要有随版本复核的准备。

初稿发布那天有个容易被忽略的事实:当时 README 的特性状态表里,Distributed Mode、Lifecycle Management、RustFS KMS 三项都标着 “Under Testing”。也就是说,半年前以"分布式对象存储"名义介绍它,严格说介绍的还是一个单机模式可用、分布式模式在测试中的系统。到 1.0,这张表几乎全绿:分布式模式、对象锁(WORM)、服务端加密、修复(healing)与扫描器、池扩容与退役、KMS、生命周期(ILM)、站点复制、桶配额、S3 Select、审计日志、OIDC/SSO、FTPS/WebDAV/SFTP 全部 Available。仍是 Preview 的只剩两项:S3 Tables(Iceberg REST Catalog),和 MinIO 磁盘格式兼容(rio-v2 feature 门控,默认构建不含)。

Star 数的时点对比:初稿发布次日(2026-04-13)Wayback Machine 实拍 25,589,2026-10-05 复核时 34,381,半年净增约 9,000。这也顺带修正初稿的一处数据错误——初稿写"4.8K Stars",发文当时真实读数已在 2.5 万以上。官网另有两处官方自述——“增长最快的开源分布式对象存储”、270 万+ 实例——未见第三方复核,参考即可。

部署实践:路径、端口与几个真实的坑

安装方式现在有六条,按场景挑:

# 一键脚本(Linux)
curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh

# Docker(数据 9000,控制台 9001)
docker run -d -p 9000:9000 -p 9001:9001 \
  -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:latest

# Nix
nix run github:rustfs/rustfs

其余还有 Helm Chart(charts.rustfs.com)、X-CMD、源码构建(docker-buildx.sh 支持 amd64/arm64 多架构)。初稿写的 cargo install rustfs 在发文时点会装到 crates.io 上 2025 年 7 月的 0.0.2——那是包名占位版,与主线隔了 14 个月;直到 1.0.0(2026-09-17)crates.io 才恢复同步。现在 cargo install rustfs 装到 1.0.1,可用,但历史教训是:这个项目的权威分发渠道是脚本、Docker 和 Helm,crates.io 长期掉线过一次。

Docker 部署第一个真正的坑是文件权限:容器以非 root 用户 rustfs(UID/GID 10001)运行,bind mount 的宿主目录必须 chown -R 10001:10001,否则启动直接权限报错。官方 compose 文件(docker-compose-simple.yml)还演示了两个值得抄的细节:四块盘的 ellipsis 写法 RUSTFS_VOLUMES=/data/rustfs{0...3},以及默认凭据 rustfsadmin/rustfsadmin 旁的 CHANGEME 注释——首次部署后先改密。

分布式部署(多节点多盘)官方文档给的形态是 systemd + 环境变量,核心三行:

RUSTFS_VOLUMES="http://node{1...4}:9000/data/rustfs{0...3}"
RUSTFS_ADDRESS=":9000"
RUSTFS_CONSOLE_ADDRESS=":9001"

四个节点各挂四块盘,ellipsis 展开,节点靠 DNS/hosts 解析。README 用 IMPORTANT 块强调了扩容规则,这是运维前必须读的部分:

  • 单节点单盘(SNSD)部署只能作为独立本地路径存在,不能就地扩容,也不能作为一个 Pool 并入多盘集群;要迁多盘拓扑,新建部署走 S3 迁移数据。
  • 多盘 Pool 扩容靠追加新 Pool,已有 Pool 的 endpoint 与纠删集宽度必须保持不变。
  • 拓扑规则沿用 MinIO,但"自动 parity 选择"两家实现不同,官方建议扩容前读 pool-layout-compatibility 文档。

客户端侧,日常读写不需要专门客户端——任何 S3 兼容工具都能接。仓库自带的 rustfs-cli 不是数据操作工具,而是离线诊断入口(connect offline enroll/bundle 签署支持包、inspect bucket-meta 离线检查桶元数据),初稿把它写成 rustfs-cli write/read/ls 的文件操作客户端,是照文件系统的想象编的,实际不存在这些子命令。Nix 安装还会带一个 rc(rustfs-client),那是 S3 兼容客户端。

调优与运维:几个真实的旋钮

初稿的"性能调优"一节教读者改 rustfs.toml 里的 RocksDB 参数——RustFS 既没有 rustfs.toml,也不用 RocksDB(存储引擎是自研 ecstore,配置全走环境变量与 CLI 参数)。真实可调的旋钮里,这两个最值得知道:

Workload profile(自适应缓冲)。rustfs/src/config/workload_profiles.rs 定义了七档:GeneralPurpose(默认)、AiTraining(大顺序读、拉满吞吐)、DataAnalytics(混合读写)、WebWorkload(小文件密集、压内存)、IndustrialIoT(实时流、低延迟优先)、SecureStorage(安全优先、内存受限)、Custom。按文件大小自适应选缓冲尺寸,AI 训练这类顺序大读场景换 profile 是最便宜的性能动作。

fsync 持久性分层。RUSTFS_DURABILITY_MODE 三档:strict(默认,对象写入路径全量 fsync)、relaxed、none(后两者是显式的用断电持久性换延迟/IOPS,官方文档原话)。旧开关 RUSTFS_DRIVE_SYNC_ENABLE=false 映射到 legacy-off,仅为兼容保留。模式进程启动时解析一次,改配置要重启;新桶默认继承进程级模式,也可用 RUSTFS_NEW_BUCKET_DURABILITY_MODE 单独覆盖。生产上建议保持 strict,把 relaxed/none 留给可重建的中间数据。

安全侧还有一个容易踩的默认行为:自 1.0.0-beta.11 起,webhook 通知指向私网地址(Docker 服务名、host.docker.internal、RFC 1918 段)默认被阻断,须在 RUSTFS_OUTBOUND_ALLOW_ORIGINS 里逐个放行 origin。这是 SSRF 防护,不是故障——本地联调 webhook 不通时先查它。

性能怎么说:官方给了环境,没给数字

初稿的"~100K ops/s"“延迟 <5ms p99"“故障恢复 <30s"三行数字在官方任何材料里都找不到出处,本文不予保留。官方 README 的性能段实际内容是一段对比视频加一份压测环境表:2 核 Xeon Platinum 8475B、4GB 内存、15Gbps 网络、4 块 40GB 盘(每盘 IOPS 3800)。也就是说官方展示的是"这套小配置下能跑满硬件"的演示,而不是一份可引用的基准报告。第三方独立评测目前也没看到成体系的。对性能敏感的选型,唯一可靠的做法是用自己的负载和硬件跑一遍——S3 兼容的好处正是 benchmark 工具(warp、s3-benchmark 这类)可以直接对它跑。

采用建议

把上面的事实收敛成决策:

可以认真评估的场景:已被 MinIO AGPL 困扰的商业部署;想要无遥测、数据主权可控的对象存储;AI/大数据的数据湖后端(官方集成文档覆盖 Ray、vLLM、ClickHouse、Airflow 及 Kopia、Longhorn、restic、Velero 等备份方案);已有 MinIO 集群想渐进迁移的团队——环境变量兼容、磁盘格式同族、mc 管理习惯可复用,迁移摩擦是同类里最低的。

建议观望或小规模验证后再上的场景:把 1.0 之前的稳定印象带进关键决策之前,注意项目正式版发布至今只有两周(1.0.0 于 2026-09-16),大规模生产案例还主要来自快速迭代的 alpha/beta 时代;S3 兼容官方措辞也从初稿时代的 “100% S3 Compatible” 收敛为 “broad S3 API compatibility for supported features”,并提供了兼容矩阵文档——依赖冷门 S3 特性前先查矩阵;MinIO 磁盘格式直读仍是 Preview 且默认构建不含,MinIO 加密过的对象 RustFS 读不了,混合部署方案要先验证这条边界。

上手顺序:单机 Docker 跑通控制台(默认凭据先改掉)→ 用 rclone/aws-cli 压一遍自己的读写负载 → 四节点 compose 或 systemd 起多节点多盘集群验证纠删码容错(拔盘测试)→ 再决定生产化,生产化时通读 docs/operations/ 下的 KMS、扫描器与 drive-timeout 调参文档。

一句话收尾:RustFS 用一年时间把"MinIO 的 Apache 2.0 替代"从口号做成了 1.0 版本——纠删码、分布式、站点复制、KMS 都已转正。它的架构没有花活,账都摊在官方规范文档里,这正是存储系统最该有的样子。剩下的不确定性不在代码,在生态时间的积累。

资源

资源链接
GitHub 仓库https://github.com/rustfs/rustfs
官方文档https://docs.rustfs.com
架构总览(仓库内)https://github.com/rustfs/rustfs/blob/main/ARCHITECTURE.md
纠删码规范(仓库内)https://github.com/rustfs/rustfs/blob/main/docs/architecture/erasure-coding.md
S3 兼容矩阵https://github.com/rustfs/rustfs/blob/main/docs/architecture/s3-compatibility-matrix.md
Helm Charthttps://charts.rustfs.com
GitHub Discussionshttps://github.com/rustfs/rustfs/discussions

资料口径:本文事实核查于 2026-10-05,基于 GitHub API 当次读数、main 分支源码浅克隆(era 基准 commit 64508ae7,2026-04-11)、era/现行 README 双时点对照、crates.io API 与 Wayback Machine 快照(2026-04-13)。性能段官方数字口径与限制见正文;官网 270 万实例数为官方自述。

参与讨论

使用 GitHub 登录。欢迎补充事实、异议与实践。