Elasticsearch ILM生命周期管理

Implementing a Hot-Warm-Cold Architecture with Index Lifecycle Management
https://www.elastic.co/blog/implementing-hot-warm-cold-in-elasticsearch-with-index-lifecycle-management

ILM lifecycle phases:
https://www.elastic.co/docs/manage-data/lifecycle/index-lifecycle-management/index-lifecycle

ILM is a feature that was first introduced in Elasticsearch 6.6 (beta) and made generally available in 6.7. ILM is part of Elasticsearch and is designed to help you manage your indexes.

image

在ES早期版本中,用户一般通过手动或外部的自动化脚本/工具(Curator等)管理index的生命周期,如每日新建索引并通过alias重定向,旧索引自行删除等手段。
在ES 6.7版本中引入了ILM policy进行自动化的index lifetime management,并在7.10+版本中逐步成熟。
本文介绍一下如何并应用ILM policy实现索引数据的自动过期和删除。

1. 设置es node属性

https://www.elastic.co/docs/reference/elasticsearch/configuration-reference/node-settings

# 7.9 之前你可以自定义node的标签,但是在ILM策略中你必须通过allocate主动设置标签识别实现数据冷热分离
# 6.7-7.9版本期间es配置关于node.roles/node role相关配置改动比较频繁,演进比较快速,建议保持使用node.attr.box_type
node.attr.box_type: hot
node.attr.box_type: warm
node.attr.box_type: cold
# 这些值本身没有强制语义,只是打了个标签,ES 内部并不会自动识别,需要在ILM policy中手动设置action
# 7.9 开始推荐 `node.roles`, 取代了之前通过node.attr.box_type自定义的标签,这些是内置角色,系统直接识别,影响内部调度和 API,但是与node.attr.box_type没有本质区别,配置难度也相似
# vi elasticsearch.yml
node.roles: [ master, data_hot ]

关于node.roles设置:

#### 核心角色
- `master` → 参与集群管理(选主、元数据)。
- `data` → 通用数据节点(7.9 后被细分,不推荐单独用)。
- `data_content` → 一般用于存放静态数据集,不参与冷热分离的那些数据
集群至少要有master、data_content、data_hot三种角色(如果用了data角色,那么至少要有master、data两种角色)。
#### 数据子角色(冷热分离相关)
- `data_hot` → 热节点,处理写入和实时查询。
- `data_warm` → 温节点,存储历史索引。
- `data_cold` → 冷节点,存储长期不活跃数据。
- `data_frozen` → 冻结节点,用于搜索快照(S3 等对象存储)。
#### 其他角色
- `ingest` → 数据预处理(ingest pipelines)。
- `ml` → 机器学习节点。
- `remote_cluster_client` → 跨集群查询。
- `transform` → 批处理和持续数据转换。
- `voting_only` → 只参与投票的 master 节点。

如果node.roles未出现在配置文件中,那么节点默认拥有所有角色,如果node.roles被设置为空列表:node.roles: [],那么此节点被认为是Coordinating only node,将其理解为仅接收客户端请求的节点即可,小型集群没有必要设置此类节点。
所有节点默认都具有coordinate功能,即默认都可以接收客户端请求。

2. 设置ILM policy(通过kibana也能设置ILM)

https://www.elastic.co/docs/manage-data/lifecycle/index-lifecycle-management/configure-lifecycle-policy

PUT /_ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": { "max_age": "7d", "max_size": "50gb" }  # 注意不同版本支持的rollover options有演进,参考本文第二个链接中的Hot phase部分rollover链接中的Options即可
        }
      },
      "warm": {
        "actions": {
          "allocate": { "include": { "box_type": "warm" } },  # 7.10+改为"allocate": {"require":{"data":"warm"}}即可,下述同理
          "forcemerge": { "max_num_segments": 1 }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "allocate": { "include": { "box_type": "cold" } },
          "searchable_snapshot": { "snapshot_repository": "my_repo" }
        }
      },
      "delete": {
        "min_age": "90d",
        "actions": { "delete": {} }
      }
    }
  }
}
# rollover的含义为:当index创建超过30天或者达到50GB后,写入切换到一个新的索引
# warm未设置min_age/max_age,那么hot数据rollover后立即进入warm状态
# cold设置了min_age=30d,那么第37天开始warm数据变为cold,同理第127天后数据删除
# 在7.10+之前我们可以为cold标签设置searchable_snapshot实现冷数据的低成本搜索,7.10+之后可以直接定义data_frozen角色
# 挂载一个本地盘用于searchable_snapshot,也就是说cold节点本身的data目录只存很少的热点数据,没有的从my_repo拉取,因此cold节点本地磁盘可以很小,大部分数据依赖挂载的nfs等远程存储即可
PUT _snapshot/my_frozen_repo
{
  "type": "fs",
  "settings": {
    "location": "/mnt/my_frozen_repo", 
    "compress": true
  }
}
# 生产上没必要设置很多phase(层),根据需求来即可,一般只需要hot/warm/cold三层,给cold设置searchable_snapshot即可
# 不同的phase支持的action列表不一样,例如searchable_snapshot只支持在cold/frozen层设置,rollover只支持在hot层设置,具体差异参考本文第二个链接中的Phase actions部分即可

3. 应用ILM策略

ILM策略建好了,我们需要把他应用到索引或索引模板才能生效。
https://www.elastic.co/docs/manage-data/lifecycle/index-lifecycle-management/policy-apply

需要特别注意的是:包含rollover动作的ILM策略必须应用于索引模板,不能直接应用于索引,且索引模板必须包含index alias配置, 原因如下:

  1. rollover会生成新的索引名,因此对于使用了rollover的ILM策略,必须应用于index template而非index
  2. rollover是基于index alias实现的,当current索引过期后,新索引创建时index alias会自动将别名指向新index,客户端认知的只有别名

在7.10+版本后应用ILM的方式已变得简单,只要新增一个模板即可,当你向首个符合pattern(必须是数字后缀)的index写入数据时,会自动为其设置alias和"is_write_index": true:

PUT _index_template/my_template
{
  "index_patterns": ["test-*"],
  "template": {
    "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 1,
      "index.lifecycle.name": "my_policy",
      "index.lifecycle.rollover_alias": "test-alias"
    }
  }
}

而在老版本中,你必须手动创建第一个index,指定其alias和ILM策略,以后ILM才会自动递增创建新索引并重定向别名至新索引:

PUT test-000001
{
  "settings": {
    "index.lifecycle.name": "my_policy",
    "index.lifecycle.rollover_alias": "test-alias"
  },
  "aliases": {
    "test-alias": {
      "is_write_index": true
    }
  }
}

补充

一个关键词较为齐全的ILM policy:

PUT _ilm/policy/hot-warm-cold-delete-60days {
    "policy": {
        "phases": {
            "hot": {
                "actions": {
                    "rollover": {
                        "max_size": "50gb",  # 注意不同版本支持的rollover options有演进,参考本文第二个链接中的Hot phase部分rollover链接中的Options即可
                        "max_age": "30d"
                    },
                    "set_priority": {
                        "priority": 50  # priority越大的policy,ILM处理的优先级越高
                    }
                }
            },
            "warm": {
                "min_age": "7d",
                "actions": {
                    "forcemerge": {
                        "max_num_segments": 1   # 合并底层段,可以不设置或设置的高一些,根据实际负载抉择
                    },
                    "shrink": {
                        "number_of_shards": 1   # 一般不建议设置,因为会将数据集中到某个节点;其设计目的是考虑到warm阶段的数据几乎无写入需求,读取需求也相对较低,所以分片没有太大意义,但是会造成数据集中,需权衡
                    },
                    "allocate": {
                        "require": {
                            "data": "warm"
                        }
                    },
                    "set_priority": {
                        "priority": 25
                    }
                }
            },
            "cold": {
                "min_age": "30d",
                "actions": {
                    "set_priority": {
                        "priority": 0
                    },
                    "freeze": {},
                    "allocate": {
                        "require": {
                            "data": "cold"
                        }
                    }
                }
            },
            "delete": {
                "min_age": "60d",
                "actions": {
                    "delete": {}
                }
            }
        }
    }
}
posted @ 2025-09-10 12:06  realcp1018  阅读(21)  评论(0)    收藏  举报