ES ILM
在 Elasticsearch的日常运维中,日志、监控数据等时序数据会持续写入,导致索引数量和存储占用急剧膨胀。如果依赖人工管理,运维人员需要定期执行索引创建、分片调整、数据迁移、过期删除等操作,不仅耗时费力,还容易因人为疏忽导致数据冗余或误删。
索引生命周期管理(Index Lifecycle Management,ILM) 正是为解决这一问题而生——它能根据预设策略,自动化完成索引从创建到删除的全生命周期操作,大幅降低运维成本,确保集群高效稳定运行。
# 一、什么是ILM?
ILM 是 ES 提供的核心运维工具,通过策略定义和阶段流转,实现索引的自动化管理。其核心目标是:
- 降低热数据(高频读写)的资源占用
- 优化温数据(低频查询、不写入)的存储效率
- 缩减冷数据(极少查询)的存储成本
- 自动清理过期无用数据
# 二、ILM生命周期阶段详解
索引的生命周期可划分为 4 个核心阶段(默认按时间流转,也可按条件触发),每个阶段可配置停留时间和执行操作。
| 阶段 | 数据特征 | 适用场景 | 典型操作及作用 |
|---|---|---|---|
| hot(热阶段) | 高频写入、高频查询 | 近7天的日志、实时监控数据 | 滚动更新(rollover):当索引达到指定大小/文档数/时间后,自动创建新索引承接写入,避免单索引过大 |
| warm(温阶段) | 停止写入、低频查询 | 7~30天的历史日志 | 1. 收缩分片(shrink):将多分片收缩为1个,减少资源占用 2. 合并分段(forcemerge):将多个分段合并为1个,优化查询性能 |
| cold(冷阶段) | 极少查询、长期保留 | 30~180天的归档数据 | 1. 迁移到冷节点(使用低成本存储介质) 2. 降低副本数(减少冗余存储) |
| delete(删除阶段) | 过期无用、无需保留 | 180天以上的过期数据 | 自动删除:释放集群存储资源 |
# 三、ILM策略:定义索引的"生命周期规则"
ILM 策略是索引生命周期管理的核心配置,用于定义索引在每个阶段的行为(何时进入阶段、执行哪些操作)。策略需结合业务场景定制,例如:
- 日志类索引:热阶段保留7天(滚动更新)→ 温阶段保留23天(总30天,收缩+合并)→ 冷阶段保留150天(总180天)→ 删除
- 监控数据索引:热阶段保留1天 → 温阶段保留6天(总7天)→ 删除
# 四、实战:配置日志索引的ILM全流程
以"java应用日志"为例,演示如何配置ILM策略,实现日志索引的自动化管理。
# 步骤1:创建ILM策略
定义日志索引的生命周期规则,包含热、温、删除三个阶段(根据需求可增加冷阶段)。
PUT _ilm/policy/java-logs-rollover-policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms", // 索引创建后立即进入热阶段
"actions": {
// 滚动更新:当索引满足任一条件时,创建新索引
"rollover": {
"max_size": "50gb", // 索引达到50GB时滚动(生产环境建议50~100GB)
"max_docs": 10000000, // 文档数达到1000万时滚动
"max_age": "1d" // 存在超过1天时滚动(按天切割日志)
},
"set_priority": { "priority": 100 } // 热阶段优先级最高(资源调度优先)
}
},
"warm": {
"min_age": "7d", // 热阶段结束后,停留7天进入温阶段(总保留7天)
"actions": {
"shrink": {
"number_of_shards": 1 // 收缩为1个分片(热阶段可能为3分片,减少资源占用)
},
"forcemerge": {
"max_num_segments": 1 // 合并为1个分段(减少文件句柄占用,优化查询)
},
"set_priority": { "priority": 50 } // 温阶段优先级降低
}
},
"delete": {
"min_age": "180d", // 从创建到现在满180天进入删除阶段
"actions": { "delete": {} } // 自动删除索引
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
关键参数说明:
min_age:进入当前阶段的最小时间(从索引创建时间开始计算)rollover:热阶段核心操作,需配合"滚动别名"使用(见步骤3)shrink:收缩分片前需确保索引只读(ILM会自动处理),且分片数需为目标分片数的倍数
# 步骤2:创建索引模板,关联ILM策略
通过索引模板,让所有符合规则的新索引自动应用ILM策略(无需手动配置)。
PUT _index_template/java-logs-rollover-template
{
"index_patterns": ["java-logs-*"], // 匹配所有以"java-logs-"开头的索引
"template": {
"settings": {
"number_of_shards": 3, // 热阶段分片数(根据写入量调整)
"number_of_replicas": 1, // 副本数(保证高可用)
"index.lifecycle.name": "java-logs-rollover-policy", // 关联ILM策略
"index.lifecycle.rollover_alias": "java-logs-current" // 滚动别名(固定写入入口)
},
"mappings": { // 可按需定义日志字段映射(例如时间戳、日志级别等)
"properties": {
"@timestamp": { "type": "date" },
"level": { "type": "keyword" },
"message": { "type": "text" }
}
}
},
"priority": 200, // 模板优先级(数值越高越优先,避免被其他模板覆盖)
"version": 1,
"_meta": { "description": "java日志索引模板,自动关联ILM策略" }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
模板作用:当创建java-logs-000002、java-logs-000003等索引时,会自动继承模板中的分片配置、ILM策略关联等设置。
# 步骤3:初始化索引并绑定滚动别名
使用rollover操作需初始化一个"基础索引",并绑定滚动别名(作为固定写入入口)。
# 创建初始索引(名称必须包含数字后缀,如-000001,用于rollover递增)
PUT java-logs-000001
{
"aliases": {
"java-logs-current": {
"is_write_index": true // 标记为当前可写入索引(rollover后会自动切换)
}
}
}
2
3
4
5
6
7
8
9
工作原理:
- 写入端始终向
java-logs-current别名写入数据 - 当
java-logs-000001满足rollover条件时,ILM自动创建java-logs-000002,并将java-logs-current的写入权限切换到新索引 - 旧索引
java-logs-000001则按策略进入后续阶段
# 步骤4:调整ILM扫描频率(可选)
ILM默认每10分钟扫描一次索引,检查是否需要执行策略动作。可根据需求调整扫描间隔(生产环境建议保留默认,测试可缩短)。
PUT _cluster/settings
{
"transient": { // 临时调整(集群重启后失效)
"indices.lifecycle.poll_interval": "10s" // 每10秒扫描一次(测试用)
}
}
# 永久调整(需重启集群生效)
PUT _cluster/settings
{
"persistent": {
"indices.lifecycle.poll_interval": "1m" // 每1分钟扫描一次
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 步骤5:验证ILM配置
通过以下API确认配置是否生效:
# 1. 查看ILM策略详情
GET _ilm/policy/java-logs-rollover-policy
# 2. 查看索引模板详情
GET _index_template/java-logs-rollover-template
# 3. 查看索引的ILM状态(当前阶段、下一步动作等)
GET java-logs-000001/_ilm/explain
# 4. 查看索引别名绑定情况
GET java-logs-current # 应返回当前写入索引(如java-logs-000001)
2
3
4
5
6
7
8
9
10
11
# 五、ILM执行机制与注意事项
# 执行流程
- ILM按
poll_interval频率扫描所有关联策略的索引 - 检查索引是否满足当前阶段的
min_age和动作触发条件 - 若满足条件,执行阶段定义的动作(如rollover、shrink)
- 动作执行完成后,索引进入下一阶段
# 注意事项
- 索引名称规则:使用
rollover时,索引名称必须以数字后缀结尾(如xxx-000001),否则无法自动递增 - 收缩分片前提:
shrink操作要求索引所有主分片必须在同一个节点,且副本数需临时调整为0(ILM会自动处理,但需确保节点有足够空间) - forcemerge影响:合并分段会消耗大量IO资源,建议在业务低峰期执行(可通过
min_age控制时间) - 策略更新:修改ILM策略后,已存在的索引会自动应用新策略(无需重新关联)
# 六、常见问题排查
策略不生效?
- 检查索引是否匹配模板的
index_patterns - 确认索引
settings中是否正确关联index.lifecycle.name - 查看ILM扫描日志:
GET _cluster/allocation/explain或 ES集群日志
- 检查索引是否匹配模板的
rollover未触发?
- 检查索引名称是否包含数字后缀
- 确认
rollover_alias绑定正确,且is_write_index: true - 验证
max_size/max_docs/max_age条件是否满足(GET java-logs-000001/_stats查看索引信息)
shrink失败?
- 检查索引是否已停止写入(热阶段已结束)
- 确认主分片是否都在同一个节点(
GET _cat/shards/java-logs-000001)
# 总结
ILM 通过自动化索引生命周期管理,解决了时序数据在 ES 中的存储和运维难题。合理配置热、温、冷、删除阶段的策略,既能保证热数据的读写性能,又能降低历史数据的存储成本。