首页
/ MinIO 桶生命周期(ILM)配置实战:对象过期、版本清理与数据分层转移

MinIO 桶生命周期(ILM)配置实战:对象过期、版本清理与数据分层转移

2026-09-05 19:31:49作者:曹令琨Iris

本篇指南基于 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 包含 IDStatusEnabled/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.UnmarshalXMLnumDays <= 0 即报错);
  • Date 必须是 ISO 8601/RFC 3339 格式,且必须是 GMT 午夜errLifecycleDateNotMidnight:时、分、秒、纳秒必须全为 0,时区必须为 UTC)。这解释了为什么示例中使用 2020-01-01T00:00:00.000Z 而非任意时刻;
  • DaysDate 二选一,不能同时出现(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.goNoncurrentVersionExpiration 同时携带 NoncurrentDaysNewerNoncurrentVersions 两个字段,其 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:SetTieradmin: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-DaysX-Amz-Restore-Request-Datex-amz-restore 等头;恢复期结束后,本地副本由扫描器在周期性运行中自动移除(详见 DESIGN.md)。

要监控源集群与转移层之间的转移事件,可以为源桶启用桶通知并订阅 MinIO 扩展事件 s3:ObjectTransition:Completes3: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 中定义了 TransitionStatusTransitionedObjectNameTransitionTier 等元数据键常量。转移完成/恢复后,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. 延伸阅读

登录后查看全文
热门项目推荐
相关项目推荐