1. 概念与前提
Rollover 会在当前写入索引达到某个阈值时创建下一代索引,例如 logs-app-000002,并将写别名切换到新索引。业务方、Filebeat 或 Logstash 始终向同一个别名 logs-app 写入,因此不需要感知实际索引名称变化。
适用范围与版本说明
- 本文主流程使用 Index State Management(ISM)插件,适用于 OpenSearch 集群和 Amazon OpenSearch Service 的托管域。
- 文中的
warm_migration、cold_migration、cold_delete是 Amazon OpenSearch Service 的 UltraWarm/Cold Storage 专用动作;自建 OpenSearch 请使用节点属性与 shard allocation 的方案。 - 用
min_*配置 ISM 的 rollover 动作。任意一个已配置的最小阈值满足即会滚动,这正对应“达到最大允许年龄/大小/文档数即切换”的语义。
命名约定
| 对象 | 示例 | 用途 |
|---|---|---|
| 索引模式 | logs-app-* | 模板和 ISM 自动附加策略的匹配范围 |
| 写别名 | logs-app | 生产者唯一的写入目标 |
| 首代索引 | logs-app-000001 | 必须以递增序号结尾,便于自动创建下一代 |
| ISM 策略 | logs-app-rollover | 定义 rollover、迁移和删除动作 |
2. 通用初始化:模板、策略、首代索引
以下三步是三个场景共用的基线。示例采用 3 个主分片、1 个副本;请按数据量、节点数和容灾要求调整。
- 创建 ISM 策略。后续章节从该策略的
rollover参数开始选择具体方案。 - 创建 composable index template,将策略通过
ism_template自动附加给匹配的新索引,并声明rollover_alias。 - 手动创建第一代索引,给别名设定
is_write_index: true。之后由 ISM 创建和切换后续索引。
2.1 创建基础索引模板
模板不负责创建第一个索引,只为所有后续索引继承 settings、mappings 和别名设置。不要在模板的 aliases 内设置 is_write_index,写索引标记只在首代索引创建时设置。
PUT _index_template/logs-app-template
{
"index_patterns": ["logs-app-*"],
"priority": 200,
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "30s",
"plugins.index_state_management.rollover_alias": "logs-app"
},
"mappings": {
"dynamic": true,
"properties": {
"@timestamp": { "type": "date" },
"message": { "type": "text" },
"level": { "type": "keyword" }
}
}
}
}2.2 创建首代索引和写别名
PUT logs-app-000001
{
"aliases": {
"logs-app": {
"is_write_index": true
}
}
}index 设置为 logs-app。不要继续使用类似 logs-app-%{+YYYY.MM.dd} 的按日直写名称,否则它绕过了写别名和 ISM rollover。3. 只做 Index Rollover
选择一个主阈值,再加一个兜底阈值。日志工作负载通常优先以 主分片大小 控制;按天滚动适合数据量稳定、查询天然按日进行的场景;按文档数适合每条记录大小比较稳定的结构化数据。
3.1 策略 A:按天滚动
每天至少生成一个新索引。若流量极大,建议同时加入 min_primary_shard_size,避免单个分片超过目标大小。
PUT _plugins/_ism/policies/logs-app-rollover
{
"policy": {
"description": "Roll over logs-app daily or when a primary shard becomes large",
"default_state": "hot",
"ism_template": [{
"index_patterns": ["logs-app-*"],
"priority": 200
}],
"states": [{
"name": "hot",
"actions": [{
"rollover": {
"min_index_age": "1d",
"min_primary_shard_size": "40gb",
"copy_alias": true
}
}],
"transitions": []
}]
}
}3.2 策略 B:按 shard 数据量滚动
优先使用 min_primary_shard_size,它以每个主分片为单位,更符合 shard 规划。不要只看整个索引大小:3 个主分片的 90 GB 索引,平均每个主分片约 30 GB。
PUT _plugins/_ism/policies/logs-app-rollover
{
"policy": {
"description": "Roll over when any primary shard reaches 40 GiB",
"default_state": "hot",
"ism_template": [{
"index_patterns": ["logs-app-*"],
"priority": 200
}],
"states": [{
"name": "hot",
"actions": [{
"rollover": {
"min_primary_shard_size": "40gb",
"min_index_age": "7d",
"copy_alias": true
}
}],
"transitions": []
}]
}
}3.3 策略 C:按文档数量滚动
min_doc_count 统计该索引内的文档数。应配合时间兜底,防止低流量索引长期保持写入状态。
PUT _plugins/_ism/policies/logs-app-rollover
{
"policy": {
"description": "Roll over after 50 million documents or seven days",
"default_state": "hot",
"ism_template": [{
"index_patterns": ["logs-app-*"],
"priority": 200
}],
"states": [{
"name": "hot",
"actions": [{
"rollover": {
"min_doc_count": 50000000,
"min_index_age": "7d",
"copy_alias": true
}
}],
"transitions": []
}]
}
}阈值怎么选
| 信号 | 建议 | 说明 |
|---|---|---|
| 主分片大小 | 以 30-50 GiB 为常见起点 | 根据查询延迟、恢复窗口和节点磁盘吞吐压测后调整;UltraWarm 官方建议最大分片约 50 GiB。 |
| 索引年龄 | 1d 或 7d 作为兜底 | 不是所有日志流量都均匀,年龄阈值保证生命周期持续推进。 |
| 文档数 | 按平均文档大小估算 | 文档大小变化明显时,优先用分片大小。 |
| 副本数 | 热数据常用 1 | 副本会增加总磁盘占用,但不计入 min_primary_shard_size。 |
4. 可选:Rollover 后按保留期删除
在同一 ISM 策略中加入 delete 状态即可。以下示例在索引创建 30 天后删除。删除不可恢复,生产前请确认快照策略、合规保留期与恢复演练。
PUT _plugins/_ism/policies/logs-app-retention
{
"policy": {
"description": "Roll over at 40 GiB per primary shard and delete after 30 days",
"default_state": "hot",
"ism_template": [{
"index_patterns": ["logs-app-*"],
"priority": 200
}],
"states": [
{
"name": "hot",
"actions": [{
"rollover": {
"min_primary_shard_size": "40gb",
"min_index_age": "7d",
"copy_alias": true
}
}],
"transitions": [{
"state_name": "delete",
"conditions": {
"min_index_age": "30d"
}
}]
},
{
"name": "delete",
"actions": [{
"delete": {}
}],
"transitions": []
}
]
}
}min_index_age 基于索引创建时间,而非每条日志的 @timestamp。若存在大量迟到日志或必须按事件时间合规删除,应使用单独的归档/删除流程,而不是仅依赖索引年龄。5. 热温冷分层
分层解决的是成本与性能的取舍:新数据在 Hot 层接受持续写入和低延迟查询;只读、低频查询数据转到 Warm;极少访问的数据可转 Cold。先确定部署模型,再选择下方对应方案。
5.1 Amazon OpenSearch Service:UltraWarm 和 Cold Storage
这是 Amazon OpenSearch Service 托管域的专用方案。UltraWarm 使用 S3 与缓存存储只读数据,适合日志等不可变数据;Cold Storage 用于更低频的长期留存。先在域配置中启用相应容量,并确保执行策略的角色具有 UltraWarm/Cold 权限。
PUT _plugins/_ism/policies/logs-app-tiered
{
"policy": {
"description": "Hot to UltraWarm to Cold Storage, then delete",
"default_state": "hot",
"ism_template": [{
"index_patterns": ["logs-app-*"],
"priority": 200
}],
"states": [
{
"name": "hot",
"actions": [{
"rollover": {
"min_primary_shard_size": "40gb",
"min_index_age": "1d",
"copy_alias": true
}
}],
"transitions": [{
"state_name": "warm",
"conditions": { "min_index_age": "7d" }
}]
},
{
"name": "warm",
"actions": [{
"warm_migration": {}
}],
"transitions": [{
"state_name": "cold",
"conditions": { "min_index_age": "30d" }
}]
},
{
"name": "cold",
"actions": [{
"cold_migration": {
"timestamp_field": "@timestamp"
}
}],
"transitions": [{
"state_name": "delete",
"conditions": { "min_index_age": "90d" }
}]
},
{
"name": "delete",
"actions": [{ "cold_delete": {} }],
"transitions": []
}
]
}
}示例时间线第 0-7 天 Hot,7-30 天 Warm,30-90 天 Cold,90 天后删除。按业务检索频率、恢复目标和成本预算修改,不要直接照搬。
5.2 自建 OpenSearch:节点属性和 shard allocation
开源/自建集群没有 UltraWarm S3 tier 动作。为节点标记层级,例如 Hot 节点配置 node.attr.box_type: hot、Warm 节点配置 node.attr.box_type: warm,再通过 ISM 的 allocation 动作把只读索引迁移到 Warm 节点。Cold 可使用同样的节点属性方式,或采用快照归档后删除。
{
"name": "warm",
"actions": [
{ "read_only": {} },
{
"allocation": {
"require": { "box_type": "warm" },
"wait_for": true
}
},
{ "replica_count": { "number_of_replicas": 0 } }
],
"transitions": [{
"state_name": "delete",
"conditions": { "min_index_age": "90d" }
}]
}6. 验证、监控与常见故障
6.1 部署后立即验证
# 1. 确认模板和首代索引已生效 GET _index_template/logs-app-template GET _alias/logs-app GET logs-app-000001/_settings?filter_path=*.settings.index.plugins.index_state_management* # 2. 确认策略与索引受管状态 GET _plugins/_ism/policies/logs-app-rollover GET _plugins/_ism/explain/logs-app-000001 # 3. 查看分片大小、文档数、索引健康 GET _cat/indices/logs-app-*?v&s=index GET _cat/shards/logs-app-*?v&s=index,shard,prirep # 4. 需要时手动执行一次 rollover 验证写别名切换 POST /logs-app/_rollover
6.2 常见问题
| 症状 | 原因与处理 |
|---|---|
Missing rollover_alias index setting | 索引没有匹配到模板或模板缺少 plugins.index_state_management.rollover_alias。先检查 GET index/_settings,再修正模板;对现有索引可补充 setting 后重试。 |
| 新索引已创建,但日志仍写进旧索引 | 摄入端直写了具体索引名,或别名没有 is_write_index: true。将 output 改成写别名,并用 GET _alias/logs-app 检查。 |
| ISM 策略没有附加到新索引 | 检查 ism_template.index_patterns、优先级和索引名称。已有索引需要手动附加策略,模板只影响新建索引。 |
| Hot 到 Warm 迁移卡住 | 确认索引不再写入、UltraWarm 已启用且有容量;检查用户角色权限、分片大小和集群健康。自建集群还要检查 allocation 约束与 Warm 节点磁盘。 |
| 删除比预期晚 | ISM 按其 job interval 轮询,不是精确到秒的定时器;同时检查策略 explain 输出及索引的实际创建时间。 |
7. 生产上线清单
- 写入端只使用别名,读请求使用别名或索引模式,避免耦合到代际索引名。
- 先在非生产域用小阈值验证:写入、rollover、新索引模板继承、别名切换、查询和删除全流程。
- 为 rollover、ISM 失败、磁盘水位、unassigned shards、Warm/Cold 容量设置告警。
- 删除策略上线前确认自动快照覆盖范围、保留天数、恢复责任人和恢复演练结果。
- 每次修改模板或策略后记住:通常只影响后续新建索引;用 explain API 确认现有索引状态。
- 依据真实查询延迟和恢复时间调整主分片目标大小,不以单一经验值替代压测。
参考资料
- OpenSearch Documentation: Index State Management policies and actions
- OpenSearch Documentation: Roll Over Index API
- Amazon OpenSearch Service Developer Guide: UltraWarm storage and automated migrations
- 内部参考:
[Public]Amazon OpenSearch 日志分析.md中的日志存储、ISM、滚动索引与冷热分层章节。
文档生成日期:2026-08-04。部署前请以目标 OpenSearch / Amazon OpenSearch Service 版本的官方文档为准,确认插件动作与服务特性可用性。