Elasticsearch 索引生命周期管理(ILM)实战指南
Elasticsearch 索引生命周期管理(ILM)实战指南
随着业务数据的持续增长,Elasticsearch 集群中的索引数量会呈爆炸式增长。如果不加以管理,海量索引不仅会消耗大量磁盘空间,还会拖慢集群的查询和写入性能。Elasticsearch 从 6.6 版本开始引入了索引生命周期管理(Index Lifecycle Management,ILM),让开发者可以用声明式策略自动管理索引从创建到删除的全过程。本文将从原理到实战,带你全面掌握 ILM。
一、为什么需要 ILM
1. 索引数量控制
在日志、监控等时序数据场景中,Elasticsearch 每天甚至每小时都会创建新索引。一个中等规模集群如果不加控制,几个月内就可能积累数万个索引。过多的索引会带来以下问题:
- 集群状态(Cluster State)膨胀:所有索引的元数据都保存在集群状态中,索引过多会导致集群状态过大,影响节点间心跳和同步效率。
- 分片管理开销:每个索引至少有一个分片,大量分片会耗尽节点的文件句柄和内存资源。
- 查询性能下降:搜索请求需要遍历更多索引,协调节点的开销显著增加。
2. 存储成本优化
数据的热度是随时间递减的——刚刚产生的日志需要频繁查询(热数据),一周前的日志查询频率大幅降低(温数据),一个月前的日志几乎不再访问(冷数据)。为所有数据使用相同的存储策略是一种巨大的浪费。ILM 允许我们:
- 热数据存放在 SSD 高性能节点上。
- 温数据迁移到 HDD 普通节点。
- 冷数据进一步压缩以节省空间。
- 超过保留期限的数据自动删除。
据统计,通过合理的 ILM 策略,存储成本最高可降低 60%~80%。
在引入 ILM 之前,很多团队使用 Elasticsearch Curator(一个独立的 Python 工具)通过定时任务完成类似工作。但 Curator 需要额外部署和维护,而 ILM 内嵌于 ES 引擎,配置更简洁、执行更可靠。
二、ILM 四个阶段:Hot → Warm → Cold → Delete
ILM 将索引的生命周期划分为最多 4 个阶段(Phase),每个阶段可以定义不同的 Action(动作):
| 阶段 | 说明 | 典型动作 |
|---|---|---|
| Hot | 正在积极写入和查询的热数据 | rollover(滚动)、set_priority |
| Warm | 不再写入但还会被查询的温数据 | allocate(迁移)、forcemerge(段合并)、shrink(缩减分片) |
| Cold | 很少访问的冷数据,可接受较慢查询 | allocate(迁移到冷节点)、freeze 或 downsample |
| Delete | 数据过期,彻底删除 | delete |
索引在每个阶段停留的时间由 min_age 参数控制(从索引创建时开始计时),到达指定时间后会自动触发该阶段定义的动作。
三、配置示例:创建策略并关联到索引模板
1. 创建 ILM 策略
以下策略定义了:索引在 Hot 阶段停留 7 天后滚动;滚动后进入 Warm 阶段,合并段并迁移到 warm 节点;30 天后进入 Cold 阶段;60 天后删除。
PUT _ilm/policy/nginx_logs_policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50GB",
"max_age": "7d"
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"forcemerge": {
"max_num_segments": 1
},
"allocate": {
"require": {
"data": "warm"
}
},
"set_priority": {
"priority": 50
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"allocate": {
"require": {
"data": "cold"
}
},
"set_priority": {
"priority": 0
}
}
},
"delete": {
"min_age": "60d",
"actions": {
"delete": {}
}
}
}
}
}
2. 创建索引模板关联策略
将策略绑定到索引模板,这样所有匹配 nginx-logs-* 的新索引都会自动应用该策略:
PUT _index_template/nginx_logs_template
{
"index_patterns": ["nginx-logs-*"],
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"index.lifecycle.name": "nginx_logs_policy",
"index.lifecycle.rollover_alias": "nginx-logs"
}
}
}
四、Rollover 滚动索引机制
Rollover(滚动)是 ILM 中最核心的机制之一,它解决的是"单个索引过大"的问题。当写入索引满足指定条件时,ILM 会自动:
- 创建一个新索引作为写入别名的新目标。
- 将旧的索引标记为只读,等待进入下一阶段。
Rollover 的触发条件可以组合使用:
"rollover": {
"max_size": "50GB", // 索引大小超过 50GB
"max_age": "7d", // 索引创建超过 7 天
"max_docs": 10000000 // 文档数超过 1000 万
}
多个条件之间是 OR(或) 关系——任何一个条件满足就会触发滚动。首次创建写入索引时需要手动设置别名:
PUT nginx-logs-000001
{
"aliases": {
"nginx-logs": {
"is_write_index": true
}
}
}
之后应用系统统一向别名 nginx-logs 写入数据,ILM 会自动完成滚动。
五、冷热数据架构(node.attr.data 配置)
要实现数据在不同阶段迁移到不同性能的节点,需要先对节点打标签。Elasticsearch 通过 node.attr 实现自定义节点属性。
1. 节点配置
在 elasticsearch.yml 中为每个节点设置属性:
# hot 节点(SSD,高性能)
node.attr.data: hot
# warm 节点(普通 HDD)
node.attr.data: warm
# cold 节点(大容量 HDD,可配置便宜存储)
node.attr.data: cold
2. 验证节点属性
配置完成后,通过 API 验证:
GET _cat/nodeattrs?v&h=node,attr,value
输出示例:
node1 data hot
node2 data warm
node3 data cold
3. 拓扑建议
- 至少 2 个 Hot 节点:保证写入高可用,建议使用 SSD。
- 2~4 个 Warm 节点:用于承载温数据查询,普通 HDD 即可。
- 2~N 个 Cold 节点:大容量 HDD,可配置较少的 CPU 和内存资源。
- Dedicated Master 节点:建议独立部署,不承担数据角色。
ILM 策略中的 allocate 动作会通过 require 条件匹配这些标签,自动将索引迁移到对应节点。
六、ILM 与 Curator 的对比
在 ILM 出现之前,Elasticsearch Curator 是管理索引生命周期的主流工具。以下是两者的详细对比:
| 维度 | ILM | Curator |
|---|---|---|
| 架构 | 内置于 ES 引擎,无需额外组件 | 独立 Python 工具,需额外部署和定时调度(cron) |
| 配置方式 | 声明式 API(RESTful JSON) | YAML 或命令行动作 |
| 实时性 | Master 节点自动检查并执行,延迟低 | 依赖 cron 调度频率(通常每小时执行一次) |
| Rollover | 原生支持,自动滚动索引 | 不支持自动滚转,需手动或借助 alias 操作 |
| 冷热迁移 | 通过 allocate action 自动完成 | 通过 action.routing.allocation.require 手动指定 |
| 可视化 | Kibana 提供 ILM 管理界面 | 无 |
| 灵活性 | 策略固定,动作类型有限 | 动作丰富,支持 snapshots、replicas、close 等 |
| 适用版本 | Elasticsearch 6.6+ | 所有版本,尤其适合 ES 6.6 之前的集群 |
结论:如果你的集群版本 ≥ 7.x,强烈推荐使用 ILM;对于无法升级的老集群或需要复杂快照管理的场景,Curator 仍是一个可选的补充工具。
七、实际案例:Nginx 日志按天轮转、30 天后删除
下面是一个完整的生产级 Nginx 日志管理方案,每天自动滚动索引,保留 30 天后删除。
1. 创建 ILM 策略
PUT _ilm/policy/nginx_daily_policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_age": "1d",
"max_size": "30GB"
},
"set_priority": {
"priority": 100
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}
2. 索引模板与初始索引
PUT _index_template/nginx_daily_template
{
"index_patterns": ["nginx-logs-*"],
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"index.lifecycle.name": "nginx_daily_policy",
"index.lifecycle.rollover_alias": "nginx-logs",
"routing.allocation.require.data": "hot"
},
"mappings": {
"properties": {
"@timestamp": { "type": "date" },
"remote_addr": { "type": "ip" },
"request": { "type": "text" },
"status": { "type": "integer" },
"body_bytes_sent": { "type": "long" },
"http_user_agent": { "type": "text" },
"request_time": { "type": "float" }
}
}
}
}
PUT nginx-logs-000001
{
"aliases": {
"nginx-logs": {
"is_write_index": true
}
}
}
3. 接入流程
- Filebeat 或 Logstash 采集 Nginx 日志,指定 Elasticsearch 输出到别名
nginx-logs。 - ILM 每天触发
rollover,创建nginx-logs-000002等新索引。 - 旧索引在创建满 30 天后进入
delete阶段,自动删除。
4. 验证与监控
使用以下命令查看 ILM 执行状态:
# 查看策略执行情况
GET _ilm/policy/nginx_daily_policy
# 查看特定索引处于哪个阶段
GET nginx-logs-000001/_ilm/explain
# Kibana 中查看
# Stack Management → Index Lifecycle Policies
总结
Elasticsearch ILM 是管理时序数据的利器。通过 Hot → Warm → Cold → Delete 四个阶段的自动流转,结合 Rollover 滚动索引和冷热节点部署,可以显著降低存储成本、简化运维工作、保障集群性能。相比 Curator,ILM 的声明式配置更简洁、实时性更高,是 Elastic Stack 用户的最佳选择。
实战中需要注意:合理设置 Rollover 条件(避免滚动过于频繁或过慢);冷热节点属性要提前规划;ILM 策略创建后不可修改部分关键参数如 max_age(需要删除重建)。掌握这些要点,你就能在生产环境中自信地部署 ILM 了。
系列文章导航:
← 上一篇:Elasticsearch 集群监控与报警实战
下一篇:Elasticsearch SQL 查询与 JDBC 集成 →





