MinIO 桶生命周期(ILM)配置实战:对象过期、版本清理与数据分层转移
本篇指南基于 MinIO 官方桶生命周期文档,讲解如何在桶上启用对象生命周期配置:按天数或固定日期自动删除对象、在版本化桶上清理非当前版本与删除标记,以及在 Erasure 模式下将冷数据分层转移(transition)到 GCS、S3、Azure 或其他 MinIO 集群。读完后你既能用 mc ilm 命令完成完整配置,也能从 internal/bucket/lifecycle 等源码理解规则校验与执行机制。
1. 生命周期配置的核心能力
MinIO 的桶生命周期配置(Lifecycle,内部常称 ILM)允许对桶内对象设置自动过期策略:在指定天数后或指定日期自动删除对象。生命周期配置通过 S3 兼容 API 或 mc ilm 客户端命令管理,配置持久化在桶元数据中,由服务端后台扫描器周期性评估并执行。
前置条件:
- 已部署 MinIO 服务端;
- 已安装 MinIO Client(
mc)。
一个完整的生命周期配置由若干 Rule 组成,每条 Rule 包含 ID、Status(Enabled/Disabled)、Filter(前缀/标签过滤)以及过期动作 Expiration。
2. 基础过期规则:按日期或天数删除对象
官方快速入门给出一个典型场景:将 old/ 前缀下的对象在 2020-01-01T00:00:00.000Z 过期,将 temp/ 前缀下的对象在 7 天后过期。使用 mc ilm import 从标准输入导入 JSON 配置:
$ mc ilm import play/testbucket <<EOF
{
"Rules": [
{
"Expiration": {
"Date": "2020-01-01T00:00:00.000Z"
},
"ID": "OldPictures",
"Filter": {
"Prefix": "old/"
},
"Status": "Enabled"
},
{
"Expiration": {
"Days": 7
},
"ID": "TempUploads",
"Filter": {
"Prefix": "temp/"
},
"Status": "Enabled"
}
]
}
EOF
导入成功后输出:
Lifecycle configuration imported successfully to `play/testbucket`.
使用 mc ilm ls 查看当前配置,可以直观看到每条规则的过期方式(日期或天数):
$ mc ilm ls play/testbucket
ID | Prefix | Enabled | Expiry | Date/Days | Transition | Date/Days | Storage-Class | Tags
------------|----------|------------|--------|--------------|--------------|------------------|------------------|------------------
OldPictures | old/ | ✓ | ✓ | 1 Jan 2020 | ✗ | | |
------------|----------|------------|--------|--------------|--------------|------------------|------------------|------------------
TempUploads | temp/ | ✓ | ✓ | 7 day(s) | ✗ | | |
------------|----------|------------|--------|--------------|--------------|------------------|------------------|------------------
2.1 配置字段的校验规则(源码级说明)
Expiration 结构的定义与校验位于 expiration.go。从源码可以看到几条硬性约束,配置不满足时服务端会拒绝导入:
Days必须为正整数(ExpirationDays.UnmarshalXML中numDays <= 0即报错);Date必须是 ISO 8601/RFC 3339 格式,且必须是 GMT 午夜(errLifecycleDateNotMidnight:时、分、秒、纳秒必须全为 0,时区必须为 UTC)。这解释了为什么示例中使用2020-01-01T00:00:00.000Z而非任意时刻;Days与Date二选一,不能同时出现(errLifecycleInvalidExpiration);ExpiredObjectDeleteMarker不能与Days/Date同时指定(errLifecycleInvalidDeleteMarker);ExpiredObjectAllVersions必须搭配Days使用(errLifecycleInvalidDeleteAll)。
规则动作的解析入口在 bucket-lifecycle.go,其中 LifecycleSys 负责从桶元数据中获取配置(Get 调用 globalBucketMetadataSys.GetLifecycleConfig),并为每条过期/转移操作生成 TraceILM 类型的审计 trace,便于通过 tracing 机制观察 ILM 执行过程。
3. 版本化桶上的版本清理
以下能力仅在启用了版本控制的桶上生效(非当前版本、删除标记等概念都依赖版本化)。
3.1 按天数自动清理非当前版本
非当前版本(non-current version)指某对象中不是最新的那一版。可以配置“版本变为非当前状态 N 天后删除”:
以扫描 user-uploads/ 前缀、删除变成非当前版本超过一年的旧版本为例:
{
"Rules": [
{
"ID": "Removing all old versions",
"Filter": {
"Prefix": "users-uploads/"
},
"NoncurrentVersionExpiration": {
"NoncurrentDays": 365
},
"Status": "Enabled"
}
]
}
该 JSON 规则等价于如下 mc 命令:
mc ilm rule add --noncurrent-expire-days 365 --prefix "user-uploads/" myminio/mydata
3.2 保留最近 N 个非当前版本
通过 NewerNoncurrentVersions 可以在版本成为非当前状态 30 天后清理旧版本,同时保留最近的 5 个非当前版本:
{
"Rules": [
{
"ID": "Keep only most recent 5 noncurrent versions",
"Status": "Enabled",
"Filter": {
"Prefix": "users-uploads/"
},
"NoncurrentVersionExpiration": {
"NewerNoncurrentVersions": 5,
"NoncurrentDays": 30
}
}
]
}
等价客户端命令:
mc ilm rule add --noncurrent-expire-days 30 --noncurrent-expire-newer 5 --prefix "user-uploads/" myminio/mydata
源码层面的实现见 noncurrentversion.go:NoncurrentVersionExpiration 同时携带 NoncurrentDays 与 NewerNoncurrentVersions 两个字段,其 Validate 要求二者不能同时为 0、且不能为负数。该文件还保留了对旧版 MinIO 字段 MaxNoncurrentVersions 的兼容解析——如果 XML 中出现旧字段,会直接映射到 NewerNoncurrentVersions,保证老配置可以平滑升级读取。
3.2.1 MinIO 扩展:非当前版本立即超额清理
这是 MinIO 对 NewerNoncurrentVersions 功能的扩展:当某对象的非当前版本数超过 N 个时,立即删除超出的旧版本,无需等待天数:
{
"Rules": [
{
"ID": "Keep only most recent 5 noncurrent versions",
"Status": "Enabled",
"Filter": {
"Prefix": "users-uploads/"
},
"NoncurrentVersionExpiration": {
"NewerNoncurrentVersions": 5
}
}
]
}
注意:该规则隐含 NoncurrentDays 为 0,即“超额”的非当前版本会立即过期,而不是延迟清理。
3.2.2 MinIO 扩展:过期时一次性清除对象全部版本
这是 MinIO 对标准 Expiration 功能的扩展:当对象的最新版本满足过期条件时,该对象的所有版本一并删除:
注意:如果最新版本是一个删除标记(delete marker),则基于
Filter.Tags的过滤会被忽略;若该 DELETE 标记的 modTime 满足Expiration.Days,对象的所有版本会立即被清除。
{
"Rules": [
{
"ID": "Purge all versions of an expired object",
"Status": "Enabled",
"Filter": {
"Prefix": "users-uploads/"
},
"Expiration": {
"Days": 7,
"ExpiredObjectAllVersions": true
}
}
]
}
对应源码中 Expiration 结构的 DeleteAll 字段(XML 标签 ExpiredObjectAllVersions),其注释明确说明:判断仅针对对象的最新版本,若为 true 则删除全部版本,为 false 时该动作不产生任何行为。
3.3 自动清理孤立删除标记
当对象的唯一版本只剩一个删除标记时,可以配置在若干天后自动移除该标记,避免删除标记长期占用命名空间:
{
"Rules": [
{
"ID": "Removing all delete markers",
"Expiration": {
"ExpiredObjectDeleteMarker": true
},
"Status": "Enabled"
}
]
}
对应的删除标记过期判断逻辑位于 delmarker-expiration.go,并在 delmarker-expiration_test.go 中由单元测试覆盖;各动作的统一评估入口是 evaluator.go。
4. ILM 转移(Transition)与分层存储
在 Erasure 模式下,MinIO 支持通过 ILM 转移功能把对象分层到公共云(GCS、AWS S3、Azure)或其他 MinIO 集群。这允许把较冷、访问频率低的数据转移到更便宜的存储,同时不牺牲数据可访问性——转移后的对象仍可通过原有 S3 接口访问。
关键区别:设置转移规则时,指定的是 MinIO 上定义的转移层(transition tier),而不是传统意义的 storage class。
4.1 创建转移层
例如,将 Azure Blob 上 azurebucket 桶中 testprefix1/ 前缀关联为名为 AZURETIER 的层:
mc admin tier add azure source AZURETIER --endpoint https://blob.core.windows.net --access-key AZURE_ACCOUNT_NAME --secret-key AZURE_ACCOUNT_KEY --bucket azurebucket --prefix testprefix1/
若非以 root 用户执行该命令,执行用户需要
admin:SetTier和admin:ListTier权限。
对于 S3 场景,如果源 MinIO 运行在 EC2 上,可以使用 EC2 绑定的 AWS Role 代替 access key/secret key:
mc admin tier add s3 source S3TIER --bucket s3bucket --prefix testprefix/ --use-aws-role
也可以把另一个 MinIO 集群作为转移目标。仓库自带的演示脚本 setup_ilm_transition.sh 就完整展示了这一流程:它启动两个 4 盘的 Erasure 站点,然后执行
mc ilm tier add minio sitea WARM-TIER --endpoint http://localhost:9004 --access-key minioadmin --secret-key minioadmin --bucket bucket
4.2 配置转移规则并验证
使用上面创建的层,为源桶配置转移规则(例如 365 天过期、45 天后转移):
mc ilm add --expiry-days 365 --transition-days 45 --storage-class "AZURETIER" myminio/srcbucket
演示脚本中使用 --transition-days 0(立即转移)并轮询对象的 X-Amz-Storage-Class 元数据,直到其变为层名 WARM-TIER,以此确认转移完成:
until $(./mc stat sitea/bucket/README.md --json | jq -r '.metadata."X-Amz-Storage-Class"' | grep -q WARM-TIER); do
echo "waiting until the object is tiered to run heal"
sleep 1s
done
4.3 恢复与监控转移对象
对象转移完成后,GET/HEAD 请求会从远端层流式返回内容。如果对象需要临时恢复到本地集群,可以使用 S3 的 RestoreObject API:
aws s3api restore-object --bucket srcbucket \
--key object \
--restore-request Days=3
恢复期间对象会带上 X-Amz-Restore-Expiry-Days、X-Amz-Restore-Request-Date、x-amz-restore 等头;恢复期结束后,本地副本由扫描器在周期性运行中自动移除(详见 DESIGN.md)。
要监控源集群与转移层之间的转移事件,可以为源桶启用桶通知并订阅 MinIO 扩展事件 s3:ObjectTransition:Complete 和 s3:ObjectTransition:Failed(转移事件通知是 MinIO 扩展,不是标准 S3 事件)。事件名在源码 name.go 中定义,s3:ObjectTransition:* 可一次订阅全部转移事件:
mc event add --event ilm <target> myminio/srcbucket
5. 底层机制:扫描器、远端对象命名与内部元数据
从 DESIGN.md 的设计文档可以看到转移执行的底层机制:
- 扫描器驱动:MinIO 数据扫描器以约一分钟为间隔运行,每轮扫描命名空间的 1/16。当桶内对象满足转移规则、成为可分层对象时,扫描器会将其选中执行转移;数据整体拷贝到远端层,本地只保留对象元数据。
- 远端对象命名:后端数据存放在层配置的
bucket/prefix之下,使用随机 UUID 派生的自定义名称,例如0b/c4/0bc4fab7-2daf-4d2f-8e39-5c6c6fb7e2d3——前两级目录是 UUID 第 1-2、3-4 位字符。这种格式使转移不依赖目标云是否支持版本控制。 - 内部元数据:转移对象的名称、目标层记录在本地
xl.meta的内部元数据中,例如:
"MetaSys": {
"x-minio-internal-transition-status": "Y29tcGxldGU=",
"x-minio-internal-transition-tier": "R0NTVElFUjE=",
"x-minio-internal-transitioned-object": "ZDIvN2MvZDI3Y2MwYWMtZGIzNC00ZGM1LWIxNDUtYjI5MGNjZjU1MjY5"
}
对应地,bucket-lifecycle.go 中定义了 TransitionStatus、TransitionedObjectName、TransitionTier 等元数据键常量。转移完成/恢复后,HEAD/GET 响应上会出现 X-Minio-Transition(MinIO 扩展头,可预测对象的预期转移日期)、x-amz-storage-class(显示对象已转移到的层名)以及恢复相关的 X-Amz-Restore-* 头。
- 加密与合规:SSE-S3/SSE-C 加密对象以加密态整体拷贝到远端层,
GET/HEAD时流式解密;处于保留期(retention)的对象由本地元数据保护,保留期结束前不会被生命周期删除。生产环境需自行确保远端层桶的访问控制。 - 删除行为:处于转移层的对象在到达过期日、或被
mc rm删除(指定版本用mc rm --vid)时才会从远端删除;legal hold 与对象锁规则优先于任何生命周期规则。
适用前提:分层(tiering)与生命周期转移仅适用于 Erasure/分布式模式的 MinIO;单机 fs 模式不具备该能力。
6. 延伸阅读
- 桶生命周期官方指南:README.md
- 分层转移设计文档:DESIGN.md
- 转移功能端到端演示脚本:setup_ilm_transition.sh
- 规则模型与校验实现:internal/bucket/lifecycle/lifecycle.go、rule.go、expiration.go、noncurrentversion.go、transition.go
- 生命周期子系统与执行入口:cmd/bucket-lifecycle.go
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00