Operations Guide · OpenSearch Index State Management

使用 Index Rollover 管理日志索引

一套面向 OpenSearch 与 Amazon OpenSearch Service 的实操手册:按时间、分片大小或文档数自动滚动索引;按保留期删除历史数据;以及将只读数据迁移到 Warm / Cold 层。

1. 概念与前提

Rollover 会在当前写入索引达到某个阈值时创建下一代索引,例如 logs-app-000002,并将写别名切换到新索引。业务方、Filebeat 或 Logstash 始终向同一个别名 logs-app 写入,因此不需要感知实际索引名称变化。

写入端别名 logs-applogs-app-000001logs-app-000002
最重要的约束:所有写请求必须指向写别名,不要写入具体索引名。否则 rollover 虽然会创建新索引,但日志仍会继续进入旧索引。

适用范围与版本说明

  • 本文主流程使用 Index State Management(ISM)插件,适用于 OpenSearch 集群和 Amazon OpenSearch Service 的托管域。
  • 文中的 warm_migrationcold_migrationcold_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 个副本;请按数据量、节点数和容灾要求调整。

  1. 创建 ISM 策略。后续章节从该策略的 rollover 参数开始选择具体方案。
  2. 创建 composable index template,将策略通过 ism_template 自动附加给匹配的新索引,并声明 rollover_alias
  3. 手动创建第一代索引,给别名设定 is_write_index: true。之后由 ISM 创建和切换后续索引。

2.1 创建基础索引模板

模板不负责创建第一个索引,只为所有后续索引继承 settings、mappings 和别名设置。不要在模板的 aliases 内设置 is_write_index,写索引标记只在首代索引创建时设置。

Dev Tools / REST
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 创建首代索引和写别名

Dev Tools / REST
PUT logs-app-000001
{
  "aliases": {
    "logs-app": {
      "is_write_index": true
    }
  }
}
摄入端配置:把 Filebeat / Logstash output 的 index 设置为 logs-app。不要继续使用类似 logs-app-%{+YYYY.MM.dd} 的按日直写名称,否则它绕过了写别名和 ISM rollover。

3. 只做 Index Rollover

选择一个主阈值,再加一个兜底阈值。日志工作负载通常优先以 主分片大小 控制;按天滚动适合数据量稳定、查询天然按日进行的场景;按文档数适合每条记录大小比较稳定的结构化数据。

3.1 策略 A:按天滚动

每天至少生成一个新索引。若流量极大,建议同时加入 min_primary_shard_size,避免单个分片超过目标大小。

Dev Tools / REST
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。

Dev Tools / REST
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 统计该索引内的文档数。应配合时间兜底,防止低流量索引长期保持写入状态。

Dev Tools / REST
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 天后删除。删除不可恢复,生产前请确认快照策略、合规保留期与恢复演练。

Hot:写入并滚动Delete:30d 后删除
Dev Tools / REST
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。先确定部署模型,再选择下方对应方案。

Hot:可写Warm:只读、低频查询Cold:极低频删除

5.1 Amazon OpenSearch Service:UltraWarm 和 Cold Storage

这是 Amazon OpenSearch Service 托管域的专用方案。UltraWarm 使用 S3 与缓存存储只读数据,适合日志等不可变数据;Cold Storage 用于更低频的长期留存。先在域配置中启用相应容量,并确保执行策略的角色具有 UltraWarm/Cold 权限。

迁移前检查:索引必须不再写入;迁移会消耗资源并可能耗时。不要让当前写索引进入 Warm/Cold。对于高频实时搜索、需要更新或删除文档的索引,应继续保留在 Hot 层。
Amazon OpenSearch Service ISM 策略
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 可使用同样的节点属性方式,或采用快照归档后删除。

自建集群 Warm 迁移状态片段
{
  "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" }
  }]
}
自建集群建议:迁移前先将索引设为只读;确认 Warm 节点可容纳主分片,且 shard allocation 没有被磁盘水位、分配过滤器或集群恢复限额阻塞。若需要长期低成本存储,快照到对象存储通常比在线 Cold 节点更合适。

6. 验证、监控与常见故障

6.1 部署后立即验证

Dev Tools / REST
# 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 确认现有索引状态。
  • 依据真实查询延迟和恢复时间调整主分片目标大小,不以单一经验值替代压测。

参考资料

文档生成日期:2026-08-04。部署前请以目标 OpenSearch / Amazon OpenSearch Service 版本的官方文档为准,确认插件动作与服务特性可用性。