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策略建好了,我们需要把他应用到索引或索引模板才能生效。
https://www.elastic.co/docs/manage-data/lifecycle/index-lifecycle-management/policy-apply
需要特别注意的是:包含rollover动作的ILM策略必须应用于索引模板,不能直接应用于索引,且索引模板必须包含index alias配置, 原因如下:
- rollover会生成新的索引名,因此对于使用了rollover的ILM策略,必须应用于index template而非index
- 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": {}
}
}
}
}
}