尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

MinIO 存储池下线(Pool Decommission)全流程操作与源码原理解析

发布时间:2026/9/8 23:54:54

资讯中心
01
ARTICLE

MinIO 存储池下线(Pool Decommission)全流程操作与源码原理解析

MinIO 存储池下线(Pool Decommission)全流程操作与源码原理解析
MinIO 存储池下线Pool Decommission全流程操作与源码原理解析【免费下载链接】minioMinIO is a high-performance, S3 compatible object store, open sourced under GNU AGPLv3 license.项目地址: https://gitcode.com/GitHub_Trending/mi/minio技术指南定位本文基于docs/distributed/DECOMMISSION.md系统讲解 MinIO 分布式部署中“存储池Server Pool下线 / 退役”机制的完整操作链路——包括启动、状态查询、取消、失败恢复、完成后的清理步骤以及驱动该机制的核心数据结构与后台搬迁逻辑。读完本文你将能够安全地把旧硬件池上的数据在线迁移至新池并正确地从启动参数中摘除退役池。什么是 Pool Decommissioning为什么需要下线一个存储池MinIO 支持把一组独立启动的驱动器组合通常由MINIO_VOLUMES环境变量或命令行参数里的一组端点表示如http://minio{1...4}/data{1...4}组织成一个Server Pool存储池。集群可以横向扩展新增一个 pool 即扩容但反过来——当旧硬件需要更换、集群需要收缩或整体迁移到性能更好的硬件上时就需要一种安全、在线、可恢复的机制把旧 pool 中的数据搬出去这就是decommissioning下线/退役。其工作方式与同目录 docs/distributed/DECOMMISSION.md 描述一致是下线是“排空并扩散”的过程把被下线 pool如pool1中的数据均匀扩散到剩余的所有 pool如pool2、pool3上而不是整体搬去某一个池全程在线进行读写不中断由管理员在后台编排执行。三个核心特性退役期仍可读、新写入自动绕开处于 decommission 状态的 pool 仍然允许对其全部内容进行 READ 访问同时新产生的 WRITE 请求会被自动调度到“非 decommission 状态”的 pool 上避免把新数据写入即将退役的池docs/distributed/DECOMMISSION.md。版本化顺序保持对于所有开启了版本化的 bucket对象在被迁移到其他 pool 后各“版本”的相对顺序保持不变——这对依赖 GetBucketVersions / 版本链语义的应用至关重要。断点续跑下线过程中若被打断例如集群重启任务会从上次的进度处自动恢复而非从头再来。前置概念集群中的 Pool 状态机从源码结构看每个 pool 的下线状态被持久化在名为pool.bin的元数据文件中格式常量见 cmd/erasure-server-pool-decom.go#L478-L483并由以下三层结构描述cmd/erasure-server-pool-decom.go#L46-L163poolMeta集群级的 pool 元数据清单版本号 各 pool 状态数组save()会把该文件写入所有 pool以保证对第一块盘退役操作本身的高可用PoolStatus单个 pool 的登记信息含ID、命令行标识CmdLine、最后更新时间LastUpdate和可选的Decommission详情PoolDecommissionInfo真正承载下线进度包括StartTime、StartSize/TotalSize/CurrentSize、Complete/Failed/Canceled状态位以及逐 bucket、逐前缀、逐对象的游标QueuedBuckets/DecommissionedBuckets/Bucket/Prefix/Object和统计计数已迁移/失败的对象数与字节数。因此mc admin decommission显示的状态位与上面结构一一对应我们可以归纳出完整的生命周期状态含义对应结构位Active正常服役中未参与下线Decommission nilDraining正在排空数据下线进行中Decommission存在三个结束位均为 falseDraining(Canceled)下线被取消Canceled trueDraining(Failed)下线失败Failed trueComplete下线完成可安全摘除 poolComplete true状态位互斥切换由poolMeta.DecommissionComplete / DecommissionFailed / DecommissionCancel方法保证cmd/erasure-server-pool-decom.go#L184-L217。开始下线mc admin decommission start使用mc admin decommission start把目标 pool用与启动参数一致的通配端点表达式标识标记为排空。这里的alias指mc中已配置的 MinIO 集群别名λ mc admin decommission start alias/ http://minio{1...2}/data{1...4}从管理侧 API 的实现看cmd/admin-handlers-pools.go#L39-L116该命令最终会命中 REST 接口POST /minio/admin/v3/pools/decommission注册于 cmd/admin-router.go#L184。服务端会做几层合法性校验仅支持新式ellipses 风格启动参数globalEndpoints.Legacy()的旧式集群返回ErrNotImplemented集群必须多于一个 pool且对象层必须是*erasureServerPools若已有下线任务在跑IsDecommissionRunning()返回errDecommissionAlreadyRunning若 rebalance 已启动则拒绝并发执行请求还会被代理到目标 pool 的首个端点所在节点执行proxyDecommissionRequest以就近操作。请求需要具备 admin 权限DecommissionAdminAction对应 mc 中的mc admin decommission。查看下线状态mc admin decommission status不带参数列出所有 pool 的概况λ mc admin decommission status alias/ ┌─────┬─────────────────────────────────┬──────────────────────────────────┬────────┐ │ ID │ Pools │ Capacity │ Status │ │ 1st │ http://minio{1...2}/data{1...4} │ 439 GiB (used) / 561 GiB (total) │ Active │ │ 2nd │ http://minio{3...4}/data{1...4} │ 329 GiB (used) / 421 GiB (total) │ Active │ └─────┴─────────────────────────────────┴──────────────────────────────────┴────────┘表内的Capacity一列来自对 pool 容量已用 / 总量的探测Status列则对应当前状态机中的状态。服务端对应GET /minio/admin/v3/pools/statuscmd/admin-router.go#L182。指定 pool查看迁移进度λ mc admin decommission status alias/ http://minio{1...2}/data{1...4} Decommissioning rate at 36 MiB/sec [4 TiB/50 TiB] Started: 1 minute ago进度以“迁移速率 累计搬迁量/总量”的方式呈现底层计数即PoolDecommissionInfo.BytesDone、TotalSize等字段。需要说明的是文档docs/distributed/DECOMMISSION.md 的 TODO 一节指出目前还没有更丰富的进度 UImc只展示数据传输速率与用量增长更精细的进度可视化将在后续版本中完善。下线完成时当所有数据搬移完毕后状态查询会提示可以安全地从启动参数中移除该 poolλ mc admin decommission status alias/ http://minio{1...2}/data{1...4} Decommission of pool http://minio{1...2}/data{1...4} is complete, you may now remove it from server command line未参与下线的 pool对未处于 decommission 状态的 pool 执行 status 会得到明确的错误提示λ mc admin decommission status alias/ http://minio{1...2}/data{1...4} ERROR: This pool is not scheduled for decommissioning currently.取消下线mc admin decommission cancel当系统负载过高、希望把下线调度到更合适的时间点时可以停止一个正在进行的下线任务。不带参数时列出所有正在进行的下线任务λ mc admin decommission cancel alias/ ┌─────┬─────────────────────────────────┬──────────────────────────────────┬──────────┐ │ ID │ Pools │ Capacity │ Status │ │ 1st │ http://minio{1...2}/data{1...4} │ 439 GiB (used) / 561 GiB (total) │ Draining │ └─────┴─────────────────────────────────┴──────────────────────────────────┴──────────┘指定 pool 后真正执行取消λ mc admin decommission cancel alias/ http://minio{1...2}/data{1...4} ┌─────┬─────────────────────────────────┬──────────────────────────────────┬────────────────────┐ │ ID │ Pools │ Capacity │ Status │ │ 1st │ http://minio{1...2}/data{1...4} │ 439 GiB (used) / 561 GiB (total) │ Draining(Canceled) │ └─────┴─────────────────────────────────┴──────────────────────────────────┴────────────────────┘重要警告取消不会让 pool 回到 ActiveNOTE: Canceled decommission will not make the pool active again, since we might have potentially partial namespace on the other pools, to avoid this scenario be absolutely sure to make decommissioning a planned well thought activity. This is not to be run on a daily basis.这是一条关键约束见 docs/distributed/DECOMMISSION.md由于迁移过程中数据可能已经被部分地写入其他 pool产生 partial namespace取消下线后该 pool无法回退为 Active只能处于Draining(Canceled)这一“静止排空”态。因此decommission 应当被当作一次经过充分规划的迁移活动而不是日常运维动作。在管理 API 的实现中取消会校验请求权限DecommissionAdminAction、拒绝旧式集群并通过pools.DecommissionCancel(ctx, idx)把状态位置为Canceled并清空StartTimecmd/admin-handlers-pools.go#L118-L158、cmd/erasure-server-pool-decom.go#L207-L217。失败状态若下线过程因任何原因失败状态列会显示Draining(Failed)λ mc admin decommission status alias/ ┌─────┬─────────────────────────────────┬──────────────────────────────────┬──────────────────┐ │ ID │ Pools │ Capacity │ Status │ │ 1st │ http://minio{1...2}/data{1...4} │ 439 GiB (used) / 561 GiB (total) │ Draining(Failed) │ │ 2nd │ http://minio{3...4}/data{1...4} │ 329 GiB (used) / 421 GiB (total) │ Active │ └─────┴─────────────────────────────────┴──────────────────────────────────┴──────────────────┘重启被取消或失败的下线对于Canceled或Failed的 pool可以直接再次执行 start 来恢复迁移任务λ mc admin decommission start alias/ http://minio{1...2}/data{1...4}对应的服务端逻辑允许在Complete/Failed/Canceled三个终态之上重新初始化一个新的PoolDecommissionInfo重新记录StartTime与空间基线只有“正在排空中”的任务三者皆非才会拒绝二次 starterrDecommissionAlreadyRunning见 cmd/erasure-server-pool-decom.go#L289-L308。断点续跑集群重启后的自动恢复机制“被打断后从上次位置恢复”在源码中有清晰实现这也是 Decommission 最值得信赖的特性之一当集群启动、erasureServerPools.Init()初始化时会先从盘上读取pool.bincmd/erasure-server-pool-decom.go#L377-L416随后通过poolMeta.validate()与当前命令行指定的 pools 做交叉比对若发现仍有残留的未完成 pool就据此重建元数据returnResumablePools()只挑出既非Complete也非Canceled的 pool——也就是说Complete 与 Canceled 不会被续跑其余任何中间态都会在重启后被列入恢复清单cmd/erasure-server-pool-decom.go#L167-L182恢复动作并非立刻执行只有 local 端点上的 leader 节点会启动后台 goroutine先sleep 3 * time.Minute等待集群稳定再调用z.Decommission()若发现任务其实已经在跑errDecommissionAlreadyRunning则直接以doDecommissionInRoutine重新接管各 pool 的迁移例程cmd/erasure-server-pool-decom.go#L519-L558续跑所依赖的游标正是PoolDecommissionInfo中持久化的Bucket/Prefix/Object与QueuedBuckets/DecommissionedBuckets见ResumeBucketObject、bucketPop等实现从而做到逐对象级别的精确续传。数据是怎么“搬”过去的对象级迁移原理深入 cmd/erasure-server-pool-decom.go 的排空循环可以还原一条数据迁移的完整链路逐 bucket 排空decommissionPool针对decomBucketInfo{Name, Prefix}逐 erasure set 启动并发 worker。worker 数默认等于该 pool 的 set 数每额外增加一个 set 还会再加一个 List worker合计2 * len(pool.sets)规模并可通过内部环境变量_MINIO_DECOMMISSION_WORKERS覆盖cmd/erasure-server-pool-decom.go#L744-L761。以版本为单位处理读取对象的全部版本fileInfoVersions然后用versionsSorter.reverse()做时间逆序排序以保证目标 pool 上重建出与源一致、正确的版本栈顺序cmd/erasure-server-pool-decom.go#L824-L826。不同对象类型走不同路径普通/版本化对象以GetObjectNInfo读回再用PutObject写入其他 pool迁移时显式设置DataMovement: true、SrcPoolIdx、MTime、UserDefined并通过PreserveETag与IndexCB保留原始 ETag 与分片索引保证压缩/校验和等元数据语义一致cmd/erasure-server-pool-decom.go#L675-L695多段上传multipart对象重建为一个新的 multipart 会话逐 part 写入并CompleteMultipartUpload保留每个 part 的 ETag、Index 及各类 checksumcmd/erasure-server-pool-decom.go#L618-L668删除标记delete marker以DeleteObjectVersioned: trueDeleteMarker: trueSkipDecommissioned: true的方式在目标池重建一个等价的删除标记从而保住版本链的完整性cmd/erasure-server-pool-decom.go#L855-L896。迁移前先消化生命周期规则每个对象在搬迁前都会按 bucket 的版本化配置、生命周期策略、对象锁与复制配置做一次评估已过期expired的对象/版本会被跳过并由生命周期系统按原计划清理不再搬去新池filterLifecycle见 cmd/erasure-server-pool-decom.go#L791-L810。成功与失败都记账CountItem精确累计成功/失败的对象数与字节数并周期性把进度写回所有 pool 的pool.binupdateAfter按距上次落盘超过阈值才写见 cmd/erasure-server-pool-decom.go#L433-L476。当状态变为 Complete如何安全摘除 pool一旦所有数据排空状态列为Complete就表示现在可以安全地把第一个 pool 参数从 MinIO 启动命令行中移除了。三种典型部署形态的操作如下docs/distributed/DECOMMISSION.md裸机baremetal假设当前环境变量为MINIO_VOLUMEShttp://minio{1...2}/data{1...4} http://minio{3...4}/data{1...4} 则删除第一段http://minio{1...2}/data{1...4}更新MINIO_VOLUMES然后并行重启所有 serversystemctl restart minio。Kubernetes修改 StatefulSet 中 MinIO 容器的命令行输入参数应用变更kubectl apply -f statefulset.yaml。MinIO Operator修改tenant.yaml的pools:段把两个条目缩减为单个条目再执行kubectl apply -f tenant.yaml。硬性约束没有Complete状态标记的Active或Drainingpool 一律不允许从配置中移除。这一点在源码侧同样被强约束poolMeta.validate()在发现命令行中仍包含一个“已标记为 complete”的 pool 时会持续输出形如“pool(1st) ... is decommissioned, please remove from server command line”的警告cmd/erasure-server-pool-decom.go#L356-L358提醒你完成摘除动作。管理 API 一览mc 客户端命令与服务端 REST 端点的对应关系注册见 cmd/admin-router.go#L182-L185mc 命令服务端端点说明mc admin decommission status alias/GET /minio/admin/v3/pools/status查询全部/指定 pool 下线状态mc admin decommission start alias/ poolPOST /minio/admin/v3/pools/decommission启动/恢复下线mc admin decommission cancel alias/ poolPOST /minio/admin/v3/pools/cancel取消进行中的下线三个端点均要求具备policy.DecommissionAdminAction权限并且都会在“对象层不是*erasureServerPools”或“pool 数不足 2”等前提下返回ErrNotImplemented。当前限制与 Roadmap根据文档docs/distributed/DECOMMISSION.md该机制尚有以下边界与规划中的能力空删除标记不迁移只有纯 delete marker、且对象没有其他后继版本的“空删除标记”不会迁移到新池以避免在目标池产生空的元数据。如果确有迁移这类空删除标记的需求官方建议在 GitHub 上提交 issue 讨论。进度 UI 仍显简陋目前只有数据传输速率与已用空间增长的展示更丰富的进度界面将在后续版本补齐。热分层Hot Tier与 ILM Transition 兼容性文档指出 pooled setup 下“过渡的热分层尚不被支持”试图对带 ILM Transition 的 bucket 执行下线会被服务端拒绝规划在未来版本支持。作为佐证当前仓库的迁移循环里已经为远端remote/tiered版本预留了独立分支DecomTieredObject见 cmd/erasure-server-pool-decom.go#L899-L919说明远端对象处理是持续演进的关注点。实际使用前请务必结合你所部署版本的 Release Notes 确认 ILM Transition 桶的兼容性。Console UI 暂未开放嵌入式的 MinIO Console 目前还不提供通过界面触发 decommission 的能力该能力规划在后续版本中支持现阶段一律通过mc完成。在本地验证整个下线流程仓库提供了可复现的端到端验证脚本 docs/distributed/decom.sh它完整覆盖了“构建版本化数据 → 创建温层warm tier→ 触发下线 → 校验”的场景适合作为学习与演练素材。其关键步骤包括用minio server http://localhost:9000/tmp/xl/{1...10}/disk{0...1}拉起多盘本地集群设置CItrue、MINIO_SCANNER_SPEEDfastest加速测试通过mc创建用户、策略并建立开启版本化的 bucketmc mb -l myminio/versioned用mc mirror internal myminio/versioned/灌入真实源码目录作为对象数据随后执行软删除mc rm -r --force制造 delete marker再二次 mirror 生成新版本以构造多版本、含删除标记的复杂命名空间额外拉起一个:9002端口的小集群作为温层创建 bucket 与 lifecycle 策略验证分层对象参与数据排空的行为配合同目录下的多份变体脚本如decom-compressed-sse-s3.sh、decom-encrypted.sh、decom-encrypted-kes.sh等还可覆盖压缩、SSE-S3/SSE-KMS 加密等组合场景并最终校验对象 checksum 与用户/策略计数以确认迁移无损。仓库内的单元测试 cmd/erasure-server-pool-decom_test.go 与*_gen.gomsgp 序列化生成亦可作为进一步研究状态机与持久化格式的参考。关于多池集群的容量规划与扩展模型还可结合 docs/distributed/DESIGN.md 与 docs/distributed/SIZING.md 阅读。结语Pool Decommissioning 是 MinIO 多池架构里“可进可退”的关键一环它让集群在硬件换代、容量收缩时无需整体重建即可把旧池数据在线扩散到新池并以pool.bin持久化 启动续跑的方式保证了过程的可靠与可审计。正确使用它只需记住三条铁律把下线当作规划性变更、不随意取消、未出现Complete之前绝不摘除 pool。配合mc admin decommission的三条命令与本文梳理的源码链路你就可以在裸机、Kubernetes 与 Operator 三种部署形态下安全地完成存储池的平滑退役。【免费下载链接】minioMinIO is a high-performance, S3 compatible object store, open sourced under GNU AGPLv3 license.项目地址: https://gitcode.com/GitHub_Trending/mi/minio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。