Elasticsearch 冷热架构设计如何配置 ILM 策略自动迁移?

文章导读
在 Elasticsearch 中实现冷热架构,最推荐的方式是通过 ILM(Index Lifecycle Management)策略绑定索引模板,适用于日志、监控等时间序列数据场景。
📋 目录
  1. 命令速用版
  2. 核心原理
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
A A

在 Elasticsearch 中实现冷热架构,最推荐的方式是通过 ILM(Index Lifecycle Management)策略绑定索引模板,适用于日志、监控等时间序列数据场景。

先说结论:ILM 是官方原生的生命周期管理方案,配合节点属性(Node Attributes)可自动将旧数据迁移到低成本节点,无需脚本干预。

  • 适合:日志、监控指标等随时间增长且查询频率递减的数据。
  • 先准备:确认集群已有不同存储类型的节点,并规划好节点属性标签(hot/warm/cold)。
  • 验收:通过 _ilm/explain 接口确认索引当前所处的生命周期阶段。

命令速用版

以下是一个完整的冷热归档策略定义及绑定模板的命令片段,包含 Hot、Warm、Cold 及 Delete 阶段,可直接在 Kibana Dev Tools 或 curl 中执行:

PUT _ilm/policy/my_hot_warm_cold_policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_size": "50GB",
            "max_age": "7d"
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "allocate": {
            "number_of_replicas": 1,
            "require": {
              "data": "warm"
            }
          },
          "forcemerge": {
            "max_num_segments": 1
          }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "allocate": {
            "number_of_replicas": 0,
            "require": {
              "data": "cold"
            }
          },
          "freeze": {}
        }
      },
      "delete": {
        "min_age": "90d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

PUT _index_template/my_logs_template
{
  "index_patterns": ["my-logs-*"],
  "template": {
    "settings": {
      "index.lifecycle.name": "my_hot_warm_cold_policy",
      "index.lifecycle.rollover_alias": "my-logs-write"
    }
  }
}

核心原理

冷热架构的核心目的是平衡查询性能与存储成本。热节点通常配置 SSD,适合高频写入和查询;温冷节点通常配置 HDD,适合存储历史数据。ILM 策略允许你定义索引在不同阶段的行为,例如在热阶段执行 Rollover 切分索引,在温阶段调整副本数并迁移节点,在冷阶段强制合并段文件并冻结索引。

自动迁移的关键在于 ILM 的 allocate action 与 Elasticsearch 的 Shard Allocation Awareness 机制配合。当策略进入 warm 或 cold 阶段,ILM 会更新索引 settings 中的分配规则,集群调度器会根据节点属性将分片移动到指定节点。

分步处理

1. 规划节点属性

在 Elasticsearch 配置文件(elasticsearch.yml)中为不同节点打上标签。修改后需重启节点生效。以下是具体配置示例:

# 热节点配置
node.attr.data: hot

# 温节点配置
node.attr.data: warm

# 冷节点配置
node.attr.data: cold

2. 定义 ILM 策略

Elasticsearch 冷热架构设计如何配置 ILM 策略自动迁移?

使用 PUT _ilm/policy 接口定义策略。注意 min_age 字段,它决定了索引创建后多久进入下一阶段。需根据业务查询习惯调整,例如日志通常 7 天后查询减少可转入温节点。

3. 创建索引模板

使用 Index Template 将 ILM 策略关联到索引模式。务必配置 index.lifecycle.rollover_alias,这是实现自动滚动写入的关键。

4. 引导初始索引

手动创建第一个索引并关联别名,例如:

PUT my-logs-000001
{
  "aliases": {
    "my-logs-write": {
      "is_write_index": true
    }
  }
}

后续写入直接使用别名 my-logs-write

Elasticsearch 冷热架构设计如何配置 ILM 策略自动迁移?

怎么验证是否生效

执行以下命令查看索引的生命周期状态:

GET my-logs-000001/_ilm/explain

检查返回 JSON 中的 phase 字段,确认是否为预期的 hot、warm 或 cold。同时观察 step 字段,如果显示 COMPLETE 说明当前阶段动作已完成。若状态卡住,检查 phase_execution 中的错误信息。

此外,可以通过 GET _cat/shards?v 观察分片是否已经迁移到带有对应属性(如 warm 或 cold)的节点上。

常见坑

1. 缺少 Rollover 别名

如果在模板中配置了 ILM 但没配置 rollover_alias,索引不会自动滚动,导致单个索引过大。务必确保写入的是别名而非具体索引名。

2. 节点属性不匹配

如果 ILM 策略要求分配到 data: warm 节点,但集群中没有带该属性的节点,分片将处于未分配状态(Unassigned)。修改策略或补充节点属性可解决。

Elasticsearch 冷热架构设计如何配置 ILM 策略自动迁移?

3. 只读权限问题

进入 warm 阶段后,ILM 默认会将索引设为只读。如果业务仍需写入旧索引,需调整策略或手动解除只读标记,但这违背冷热设计初衷。

4. 强制合并耗时

forcemerge 操作是资源密集型任务,建议在温阶段业务低峰期执行,或者在策略中调低并发限制,避免影响集群整体性能。

5. 冷阶段冻结索引

进入 cold 阶段后建议执行 freeze 操作以降低内存开销,但冻结后的索引查询延迟会增加,需评估业务容忍度。