优先用ilm自动管理,避免手动调用_rollover;因后者是一次性操作、无后台检查、依赖别名正确配置,易失败;ilm需策略+模板+初始索引别名三者缺一不可。

直接上结论:别手动轮询或定时调用 _rollover,优先用 ILM(Index Lifecycle Management)自动管理;手动 rollover 仅适合调试、小规模或临时场景,否则容易漏触发、别名错乱、索引命名断裂。
为什么不能只靠 _rollover API 定时调用
很多人一上来就写个 cron 脚本每天跑 POST logs-alias/_rollover,结果发现:索引没滚动、别名没切、甚至报 no write index is defined。根本原因是:_rollover 不是“开启自动滚动”的开关,它是一次性操作——只对当前 可写的那个索引 检查条件并执行一次滚动,且要求该索引必须满足 is_write_index: true 的别名配置。
- 如果上次滚动后你忘了更新别名指向,或者新索引没正确设置
is_write_index,下一次调用就直接失败 -
max_age是从索引创建时间算起,不是从上次 rollover 算起;如果你手动延迟执行,可能跳过窗口导致堆积 - 没有后台守护机制,ES 不会主动检查条件是否满足;全靠你调度,可靠性低
必须配齐的三个组件:ILM 策略 + 索引模板 + 初始索引别名
缺一不可。顺序错了或漏了任意一个,ILM 就不会绑定到索引,滚动永远不会发生。
-
_ilm/policy/my-policy:定义hot阶段的 rollover 条件(比如"max_docs": 5000000或"max_size": "40gb"),delete阶段的清理逻辑(如"min_age": "60d") -
_index_template/my-template:在template.settings里显式写入"index.lifecycle.name": "my-policy"和"index.lifecycle.rollover_alias": "logs-write" - 初始索引(如
logs-000001)必须带别名:"aliases": { "logs-write": { "is_write_index": true } }—— 这是 ILM 找到“当前写索引”的唯一依据
max_size 和 max_primary_shard_size 到底该选哪个
看你的分片数是否固定。如果用了默认 1 主分片,二者效果一样;但一旦设了 number_of_shards: 5,差别就大了:
-
max_size: "40gb":整个索引总大小超 40GB 就滚动(5 个分片加起来) -
max_primary_shard_size: "8gb":任一主分片超过 8GB 就滚动(更公平,防热点分片撑爆) - 生产环境强烈建议用
max_primary_shard_size,尤其日志类数据容易倾斜;max_docs可作为兜底,避免小文档塞满分片但体积不达标
滚动后查不到新写入的数据?检查别名和查询路径
滚动成功后,新文档写进去了,但 GET logs-write/_search 却查不到最新数据——大概率是你查询时没用写别名,而是直接查了旧索引名或读别名。
- 写操作必须始终发往
logs-write(那个带is_write_index: true的别名) - 读操作推荐用另一个别名(如
logs-read),并在模板里统一 alias 所有匹配索引("logs-*") - 别混用:不要对
logs-write做GET查询,它只保证写路由正确;也不要用logs-000002这种具体索引名写入,否则 ILM 失效
最易被忽略的一点:ILM 策略生效有延迟,首次绑定后可能要等 10 分钟才开始监控;可以用 GET logs-000001/_ilm/explain 看当前阶段和下一个检查时间。











