Skip to content

ElasticSearch ILM

Index lifecycle management (ILM) & ILM policy

通过配置索引生命周期管理策略(index lifecycle management policy) 自动管理索引实现:

  • 达到预定文档数或预订存储容量后,轮转创建新索引(Spin up a new index, rotating)
  • 每天、每周或每月创建新索引并存档之前的索引
  • 删除过时的索引以执行数据保留标准
  • 实现热温冷存储架构 (hot-warm-cold architectures)

注:使用 ILM policy 功能要求集群中所有节点 ES 是同一个版本。

索引生命周期策略可以触发如下操作:

  • 滚动 rollover: 当当前写入索引达到一定的大小、文档数量或年龄时,创建一个新的写入索引;
  • 收缩 shrink: 减少索引中主分片 (primary shard) 的数量;
  • 强制合并 force merge: 强制合并:触发强制合并以减少索引分片中的段数 (segment);
  • 冻结 freeze: 冻结索引并使其变为只读;
  • 删除 delete: 永久删除索引,包括其所有数据和元数据。

ILM 定义了五个索引生命周期阶段 (phase):

  • 热 hot :索引正在被积极更新和查询。
  • 温 warm :索引不再被更新,但仍在被查询。
  • 冷 cold :索引不再被更新,查询频率不高。信息仍然需要可搜索,但如果这些查询速度较慢,也没关系。
  • 冻结 frozen :索引不再被更新,查询频率不高。信息仍然需要可搜索,但如果这些查询速度极慢,也没关系。
  • 删除 delete :索引不再需要,可以安全删除。

阶段转变 (Phase transition)

  • 根据年龄转变,为每个阶段设置最小年龄
  • 要使索引进入下一阶段,当前阶段的所有操作都必须完成,并且索引必须大于下一阶段的最小年龄。如 warm 为 10d,则下一阶段 cold 必须 >= 10d 或留空不设置
  • 如果一个索引在 cluster health 为 yellow 时有未分配的分片,系统依然会按策略执行阶段转变;但由于只有 cluster health 为 green 时 ES 才会执行清理任务,因此可能会有未知副作用;为了避免磁盘使用量增加和可靠性问题,请及时解决任何集群健康问题。

阶段执行 (phase execution)

  • 相关系统设置 indices.lifecycle.poll_interval

阶段操作 (phase action)

TBD.

策略更新 (policy update)

TBD.

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/update-lifecycle-policy.html

Manage time series data without data streams

Steps

  • create a lifecycle policy
  • create a index template
  • bootstrap an index as the initial write index
  • verify indices are moviing through the lifecycle phases as expected

CRUD ILM policy

http
GET _ilm/policy
GET _ilm/policy/<name>
DELETE _ilm/policy/<name>

Show the built-in ILM policy '7-days-default'

http
GET _ilm/policy/7-days-default

{
  "7-days-default" : {
    "version" : 1,
    "modified_date" : "2025-01-09T03:36:34.691Z",
    "policy" : {
      "phases" : {
        "warm" : {
          "min_age" : "2d",
          "actions" : {
            "shrink" : {
              "number_of_shards" : 1
            },
            "forcemerge" : {
              "max_num_segments" : 1
            }
          }
        },
        "hot" : {
          "min_age" : "0ms",
          "actions" : {
            "rollover" : {
              "max_primary_shard_size" : "50gb",
              "max_age" : "7d"
            }
          }
        },
        "delete" : {
          "min_age" : "7d",
          "actions" : {
            "delete" : {
              "delete_searchable_snapshot" : true
            }
          }
        }
      },
      "_meta" : {
        "managed" : true,
        "description" : "built-in ILM policy using the hot and warm phases with a retention of 7 days"
      }
    },
    "in_use_by" : {
      "indices" : [ ],
      "data_streams" : [ ],
      "composable_templates" : [ ]
    }
  }
}

Create

http
PUT _ilm/policy/ts_applog
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_primary_shard_size": "1kb",
            "max_age": "2d"
          }
        }
      },
      "delete": {
        "min_age": "4d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

CRUD index template

http
GET _index_template/
GET _index_template/<name>
DELETE _index_template/<name>

Create index template

http
PUT _index_template/ts_applog
{
  "index_patterns": ["ts_applog-*"],
  "template": {
    "settings": {
      "number_of_shards": 1,
      "index.lifecycle.name": "ts_applog",
      "index.lifecycle.rollover_alias": "ts_applog"
    }
  }
}

Create index template with custom mapped fields

index_template.json

它需要启动一个初始索引,并将其指定为索引模板中指定的滚动别名的写入索引。 此索引的名称必须与模板的索引模式匹配,并以数字结尾。在滚动时,此值会增加以生成新索引的名称。

http
PUT ts_applog-000001
{
  "aliases": {
    "ts_applog": {
      "is_write_index": true
    }
  }
}

GET _cat/aliases?v

Check lifecycle progress GET ts_applog-*/_ilm/explain

http
GET /_cluster/settings
PUT /_cluster/settings
{
  "transient": {
    "indices.lifecycle.poll_interval":"10s"
  }
}

Query old data

http
GET ts_applog/_count
{
  "query": {
    "range": {
      "timestamp": {
        "lt": "now-7d/d"
      }
    }
  }
}

GET ts_applog/_search
{
  "query": {
    "range": {
      "timestamp": {
        "lt": "now-7d/d"
      }
    }
  }
}

Delete old data by manual

POST ts_applog/_delete_by_query
{
  "query": {
    "range": {
      "timestamp": {
        "lt": "now-7d/d"
      }
    }
  }
}

常用接口

查看统计 _data_stream/_stats

查看某个 data stream GET _data_stream/logs-xxx-default

查看某个 data stream 的索引的 ILM 信息 GET .ds-logs-xxx-default-2049.01.01-000001/_ilm/explain

主动触发索引滚动 (roll over) 生成新索引 POST logs-xxx-default/_rollover

常见问题

index.lifecycle.rollover_alias [ts_applog] does not point to index [ts_applog-000001]

索引 ts_applog-000001 的 aliases 值不对,删除 ts_applog-000001 重建。

Solve health status yellow

可能是存在 unassigned shard 导致:

GET /_cat/shards?v=true&h=index,shard,prirep,state,node,unassigned.reason&s=state&pretty

对于非生产环境,可修改全局默认副本为 0:

http
PUT _settings
{
  "index": {
    "number_of_replicas": 0
  }
}

Released under the CC-BY-NC-4.0