MinIO 迁移到 RustFS:生产级实战教程

封面

MinIO 社区版在 2026 年初归档后,仍有大量实例停留在不再接收安全更新的旧版开源分支上。把对象存储从 MinIO 迁到 RustFS,最耗时间的环节不是数据拷贝,而是迁移路径的决策:原地接管数据目录和全量搬迁,两条路的停机窗口、数据风险与回滚成本差得很远。

这篇文章把整条生产迁移流程拆开讲:先给决策表,再分别给出原地替换与数据搬迁两套可复制配置,然后是切流那天的验收顺序、回滚预案,以及一份生产环境绕不开的配置迁移、业务影响评估和异常预案。数据迁移一旦开始就很难回头,路径选错,后面每一步都在为这个错误付费。

迁移决策:原地替换还是数据搬迁

对象存储迁移的常规做法是全量导出再导入,几百 TB 数据来回搬,校验成本高,窗口也长。S3 兼容层给了另一条更短的路径:如果新进程能直接接管旧数据目录,连导出这步都可以省掉。

原地替换的适用前提是部署形态不变:单机换单机,或同拓扑换同拓扑。原因在于存储引擎的单节点与分布式是两套数据布局,互不兼容,指望单机迁过去顺便扩成分布式集群,在原地替换这条路上走不通,那属于数据搬迁的活。数据搬迁没有这个限制,新集群独立部署,用标准 S3 工具同步,适合跨硬件、跨机房、顺带扩容的场景。

两条迁移路径怎么选

两边的取舍用一张表说清楚:数据量在百 TB 级、部署形态能保持不变时优先考虑原地替换;要动拓扑、动硬件或要跨机房,就走数据搬迁。无论走哪条,第一步都是给数据盘做快照或整盘备份,这条没有例外。

原地替换:换掉容器镜像,数据路径原封不动

原地替换的原理是直接复用 MinIO 的数据目录:把容器镜像换成目标存储的镜像,挂载同一批数据盘,原桶、原对象就由新进程接管,应用侧的 endpoint、密钥习惯都不变。下面这份 docker-compose 以官方迁移指南的配置为基础,补上了正式版的安全要求(密钥必须显式指定,默认占位已不允许启动):

services:
  rustfs:
    image: rustfs/rustfs:1.0.0
    container_name: rustfs
    hostname: rustfs
    environment:
      - RUSTFS_VOLUMES=/data{1...4}
      - RUSTFS_ADDRESS=0.0.0.0:9000
      - RUSTFS_CONSOLE_ENABLE=true
      - RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
      - RUSTFS_ACCESS_KEY=<换成强随机值>
      - RUSTFS_SECRET_KEY=<换成强随机值>
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - data1:/data1
      - data2:/data2
      - data3:/data3
      - data4:/data4

几点注记。镜像 tag 固定到 1.0.0,上线前 docker pull rustfs/rustfs:1.0.0 核对 digest,别用 latest。RUSTFS_ACCESS_KEY 和 RUSTFS_SECRET_KEY 在 1.0.0 正式版必须显式指定,保留默认占位符服务会拒绝启动,这是官方明确的安全要求;如果旧环境里还沿用默认密钥,需要额外设置 RUSTFS_RPC_SECRET,且其值必须与 RUSTFS_SECRET_KEY 不同。卷映射沿用原 MinIO 段的四块数据盘,RUSTFS_VOLUMES 的 {1...4} 展开语法与官方迁移指南一致。

替换后访问 http://ip:9001 进控制台,确认原桶和对象都在,再进下一步。二进制部署的路径同理,官方迁移指南给的启动命令是 ./rustfs /data/minio --address ":9000" --console-enable --console-address ":9001" --access-key ... --secret-key ...,命令格式以官方指南为准,版本换成你下载的正式版标签。

目标要上分布式时,把所有节点的端点写进同一个 RUSTFS_VOLUMES 即触发分布式;节点之间只要能直连彼此的 RustFS 服务端口、能解析主机名,就能组起集群。--network host 只是最省心的避坑做法,用自定义 bridge 或 overlay 网络配好端口映射与 DNS 解析同样可行,并不是只能用 host 网络。

数据搬迁:mc mirror 双跑,预同步先锁删除

跨硬件或要扩容的场景走数据搬迁。新集群按正常流程部署好之后,用标准 S3 客户端做双跑同步。预同步阶段的关键是先挡住源端删除的传播:

mc alias set minio-old https://minio.example.com:9000 <旧AK> <旧SK>
mc alias set rustfs-new http://127.0.0.1:9000 <新AK> <新SK>

mc mirror --watch --overwrite --preserve --no-remove minio-old/data rustfs-new/data

几个旗标说清楚。--preserve 把对象级元数据一起搬(Content-Type、自定义 metadata、对象标签),但它不搬桶策略,桶策略属于桶级配置,mc mirror 完全不碰。--no-remove 是预同步阶段的护身符:调试期万一在源端误删了对象,目标端不会跟着删,避免把事故放大到新集群。等割接前业务停止写入、要做最终对齐时,再去掉 --no-remove 跑一轮,让源端已经删掉的对象在目标端也删掉:

mc mirror --overwrite --preserve minio-old/data rustfs-new/data

--overwrite 建议加上,尤其是重复跑全量同步、增量追数据的场景,它能保证源端更新后的对象覆盖目标旧副本。首次干净跑不强制带它,但重跑场景下强烈建议,否则大小或修改时间恰好一致、内容却没更新的对象会被跳过。

一个硬性前提要记牢:mc mirror 只处理对象及其对象级元数据,对桶策略、生命周期、事件通知、IAM 策略、服务端加密(SSE)、对象锁(WORM)等桶级 / 账号级配置一律不动。这些配置后面有专门的章节讲怎么迁移,这里先建立认知,别指望 mirror 一键带过去。

双跑窗口内,写流量继续进旧端,mirror 持续把增量搬过去。窗口期长短取决于数据量和带宽,几百 TB 的规模建议按天排计划,别指望一夜搬完。mc mirror 处理大量小对象的桶时,启动阶段会先做一轮目录列举,几千万对象的桶这一轮可能就要跑几小时,期间不要拿 diff 的输出判断进度,看 mirror 自身日志里的传输计数更靠谱。

校验:diff 只是快速预检,必须补抽样内容核对

很多人收口迁移只跑一句 mc diff,这不够。mc diff 默认比对对象名称、大小、修改时间,它不做内容哈希校验,也不会下载对象实体。所以它是快速预检,不是内容一致的保证:两端大小相同、mtime 不同会被判不一致;而内容不同但大小 / mtime 恰好相同的对象,反而会被漏判。生产不能只靠 mc diff 收口。

mc diff minio-old/data rustfs-new/data

mc cat minio-old/data/bucket/obj | md5sum
mc cat rustfs-new/data/bucket/obj | md5sum

对随机抽样的对象做端到端 MD5 比对,覆盖 mc diff 漏判的情况。这里还有一个 ETag 的坑要提醒:S3 的 ETag 对分片上传对象等于各分片 MD5 再求 MD5,同一个文件用不同分片大小上传,ETag 就不一样。跨存储迁移时不要拿 ETag 相等当作内容一致的唯一证据,可靠的还是抽样内容 MD5。

桶级与账号级配置:没有自动迁移工具

这是生产迁移最容易翻车的地方。IAM 用户与策略、桶策略、生命周期规则、事件通知、服务端加密(SSE)、对象锁(WORM),全部要从 MinIO 手工导出,在 RustFS 重建,再逐条校验,没有任何一键迁移这些配置的工具。下面挑几个坑讲透。

版本化桶要单独评估。开了版本控制的桶,mc mirror 默认只搬当前版本(latest),历史版本留在源端。要搬全量历史版本得自己写脚本遍历 ListObjectVersions 逐版本拷贝,版本量大时 API 限流和性能都是实打实的问题,而且 RustFS 的版本 ID 语义、删除标记行为要和 MinIO 逐项验证。建议先在 POC 环境抽样迁移几十个版本,确认回滚、删除标记在 RustFS 上表现符合预期,再决定全量策略。

对象锁 / WORM 尤其要谨慎。桶一旦开启对象锁通常无法简单关闭,RustFS 的对象锁语义(合规保留期、合法持有、优先级)务必在 POC 里验证,不要等上线才发现行为和原平台有差异。

业务影响评估:两处高频踩坑

预签名 URL 是迁移后最容易被忽略的爆点。旧 MinIO 生成的预签名 URL 是用源端 AK/SK 签的,迁移后这批链接全部失效。前端、移动端、第三方集成里凡是硬编码或缓存了旧预签名 URL 的地方,迁移后都会直接 403。迁移前先排查预签名 URL 的使用面,规划用 RustFS 新 AK/SK 重新签发的过渡方案,比如加一层签发代理,或给业务一个明确的切换窗口。

分片上传残留碎片也要清。割接窗口内业务正在进行、尚未完成的 multipart upload,mc mirror 不会同步。割接前要么等这些分片上传自然完成,要么在源端 abort 掉并清理碎片,否则那部分数据会丢、对应上传任务失败。切流前可以用 mc ls --incomplete 之类的方式清点未完成的碎片。

同步任务的稳定性边界:客户端轮询不是服务端复制

mc mirror --watch 是客户端持续轮询同步,不是服务端原生桶复制。mc 进程挂了同步就停;海量对象、高并发场景下,客户端轮询有延迟、也有漏变更的风险。生产跑 --watch 必须加进程保活(systemd / supervisor)、落日志、监控同步延迟。

如果规模大到客户端轮询扛不住,RustFS 1.0.0 已支持服务端桶复制 / 站点复制,那是被动复制、不依赖客户端进程,适合做大规模持续同步的替代或补充。简单说:小到中等规模用 mc mirror 足够,超大规模或要求强一致持续同步的,优先评估服务端复制。

切流那天的验收顺序

切流当天按固定顺序验收,别跳步:

  1. diff 预检归零:mc diff 两端无差异输出,增量已收敛。
  2. 配置一致性校验:桶策略、IAM、生命周期、事件通知、SSE、对象锁逐条比对两端。
  3. 抽样内容 MD5 比对:随机抽桶,比对对象数量、总大小,再抽对象做端到端 MD5。
  4. 应用重连:把应用配置里的 endpoint 指到新端,跑一遍应用自带的健康检查或读写探针。
  5. 性能基准:用 warp 或应用自身压测打一轮,和旧端记录对比。

性能给一个官方基准做参照:官方压测环境(2 核 Xeon Platinum 8475B、4GB 内存、15Gbps 网络、4 块盘)下,4KB 小对象 PUT 吞吐约为 MinIO 的 2.3 倍,这组数据同时标注在官方仓库的介绍里。

PUT 吞吐对照:1.0.0 GA 官方数据

验收通过后,把备份脚本、日志归档这类低频作业先跑一轮,确认它们在新端上按原节奏工作,再宣布切流完成。

回滚预案:镜像保留三天,观察窗口留一周

切流不是终点。原地替换路径下,回滚的代价最低:停掉新进程,起回旧镜像,数据盘没动过,直接就能回来。所以旧镜像和旧配置至少保留三天,不要当天清理。数据搬迁路径下,回滚依赖双跑期的同步链路,在确认新端稳定前,不要关掉 mirror 任务,旧端也保持只读在线。

观察窗口建议留一周,重点看三样东西:控制台的集群健康状态、事件通知是否正常投递、备份与归档作业是否完整跑完一轮。一周后没有异常,再停旧端、删临时同步任务,迁移正式收口。记得旧 MinIO 的 AK/SK 也要在观察期结束后轮换并下线,避免两套密钥长期并存。

POC 验证清单

在测试环境复刻一份生产数据子集,逐项验证后再动生产:

  • 版本控制:回滚、删除标记在 RustFS 上的行为是否与 MinIO 一致。
  • 对象锁:合规保留期、合法持有、优先级是否符合预期。
  • SSE 加密:服务端加密对象的读写是否正常,密钥路径是否对齐。
  • 预签名 URL:用 RustFS 新 AK/SK 签发的 URL 在业务侧可用。
  • 分片上传:大对象分片上传完整,无残留碎片。
  • 生命周期:过期删除规则按预期触发。
  • 桶策略权限:跨账号、跨应用的访问控制行为与源端一致。

迁移前置检查清单

  • 桶清单与对象量估算,按桶排好迁移优先级。
  • 哪些桶开了版本控制、哪些开了对象锁,分别制定策略。
  • 是否有常驻的分片上传业务,切流窗口怎么避让。
  • 预签名 URL 使用面:前端、移动端、第三方集成各用到什么程度。
  • IAM 用户与策略清单,权限边界是否要随迁移收紧。
  • 生命周期规则清单,避免过期删除在切换期误触发。
  • 事件通知目标(webhook / 消息队列)盘点,确认新端能重新接上。

迁移监控项

  • 同步任务进程存活与日志,靠保活自动拉起。
  • 同步延迟:源端最后写入到目标端出现的时间差,设阈值告警。
  • RustFS 接口错误率:对象读写 4xx / 5xx 比例。
  • 带宽与磁盘 IO,提前发现瓶颈。
  • 对象数与容量增长,两端是否对齐。

异常场景预案

  • mc mirror 进程中断:靠进程保活自动拉起;中断期间源端新增对象会在重启后继续搬,--overwrite 保证覆盖;定位中断原因后再补一轮 diff。
  • 发现对象不一致:先抽样 MD5 确认是真不一致还是 ETag / mtime 误报;确属真不一致,单独重 mirror 对应前缀。
  • 割接突发流量:保留旧端只读在线兜底,必要时把写流量回退到旧端。

密钥管理提醒

  • 新旧 AK/SK 都从密钥管理服务取,别硬编码进镜像或脚本。
  • 迁移完成、观察窗口结束后,轮换旧 MinIO 的 AK/SK 并下线旧端。
  • RustFS 端用强随机密钥,rc 阶段起已不允许默认口令,强密钥是上线前提。

收尾时把备份、路径决策、部署、校验、验收、回滚窗口、观察期这些环节串成一张清单,逐项打勾后再下线旧端。RustFS 在 2026-09-16 发布 1.0.0 GA,Apache 2.0 协议,官方迁移文档里有二进制与容器两种替换命令,仓库在 https://github.com/rustfs/rustfs ,动手前值得先翻一遍。

posted @ 2026-09-25 06:48  对象存储与RustFS  阅读(2)  评论(0)    收藏  举报