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.

在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)
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策略建好了,我们需要把他应用到索引或索引模板才能生效,一般来说我们肯定是应用到索引模板的,因为单个索引应用ILM策略无意义,除非每次创建索引你都绑定一次ILM,这很麻烦不如使用模板。
https://www.elastic.co/docs/manage-data/lifecycle/index-lifecycle-management/policy-apply
需要特别注意的是:包含rollover动作的ILM策略必须应用于索引模板,不能直接应用于索引,且索引模板必须包含index alias配置, 原因如下:
- rollover会生成符合index_patterns的新索引名,因此对于使用了rollover的ILM策略,必须应用于index template而非index本身
- rollover是基于index alias实现的,当current索引过期后,新索引创建时index alias会自动将别名指向新index,客户端因此只通过别名即可读写
应用ILM到模板的方式很简单,只要新增模板时设置好ILM策略即可(index.lifecycle.name)。
PUT _index_template/my_template
{
"index_patterns": ["test-*"],
"template": {
"settings": {
"number_of_shards": 1, # 生产上如果单个索引数据量超过了1GB,那么就可以开始考虑设置number_of_shards>1啦,确保单个分片数据量在<30GB为宜
"number_of_replicas": 1,
"index.lifecycle.name": "my_policy",
"index.lifecycle.rollover_alias": "test-alias"
}
}
}
在7.10+的新版本中当你向首个符合pattern(必须是数字后缀)的index写入数据时,会自动为其设置alias和"is_write_index": true。
但是在老版本中,你还必须手动创建第一个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
}
}
}
上边讲述的其实是一种理想场景,即客户端只需要关注alias即可,至于alias指向的具体索引则完全交由ES自动管理,所有索引本身则依赖ILM自动进行过期清理。
但实际使用中一种很常见的场景是,客户端自己通过时间滚动策略直接写入yyyy/mm/dd格式的索引,那么事情就简单了,我们只需要应用ILM策略到模板即可,此时有两种设置方式:
- PUT _index_template/my_template绑定ILM时不指定rollover_alias,此时ILM策略中也不能包含rollover关键字
- PUT _index_template/my_template时依然指定rollover_alias,同时ILM策略中也必须包含rollover关键字,但是这个rollover操作因为索引名不符合自动管理的要求,因此总是失败,导致数据无法转阶段。
两种设置方式都不会报错,但只有第一种设置方式才是有效的,说白了就是ILM策略中的rollover action与template中的rollover_alias必须同步,要么都没有要么都有,而且当都有时必须是自动管理的index名称而不能是自定义的index name,否则即便你的template能绑定ilm策略成功,rollover也会失败导致你的数据无法过期(通过<index_name>/_ilm/explain查看ilm策略未生效的原因)。
在7.11+的版本中,你可以通过<索引名>/_settings接口得到此索引遵循的ILM策略,然后通过_ilm/policy/<ilm策略名>查看ILM策略内容以及应用了此策略的所有模板(composable_templates字段),之后可以通过_index_template/<模板名>?pretty查看此模板的具体配置,其中有个composed_of字段需注意,此配置表示当前模板是由多个组件模板构成的,是ES新推出的组件模板,即复用一些提前建好的组件模板构成新模板(组件模板本身不能用于索引绑定),可以通过_component_template/<组件模板名>查看具体配置。
补充
一个关键词较为齐全的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": {}
}
}
}
}
}
最后,推荐使用kibana进行索引、索引模板、ILM策略的管理,目前kibana这方面的UI操作已经很完善了。

浙公网安备 33010602011771号