Elasticsearch 冷热分层架构实战指南

在大规模日志与指标场景下,Elasticsearch 集群的存储成本与查询性能往往成为运维的主要挑战。冷热分层架构(Hot-Warm-Cold Architecture)通过将不同生命周期的数据分配到不同规格的节点上,可在保证查询性能的同时显著降低硬件成本。本文从架构设计出发,介绍 Elasticsearch 官方 ILM(Index Lifecycle Management)的配置方法与实际运维经验。

一、冷热分层架构设计原理

Elasticsearch 节点按角色可分为三类:

热节点(Hot):配置高性能 SSD,承载最新写入的索引,接收全部写入流量和部分实时查询。数据在此层停留时间最短,通常为 1~3 天。

暖节点(Warm):使用普通 SSD 或大容量 HDD,仅承载只读索引,承接历史数据分析查询。数据在此层停留时间适中,通常为 4~14 天。

冷节点(Cold):使用大容量 SATA 磁盘或对象存储,承载极少访问的历史归档索引,以降低存储成本为主要目标。数据在此层可保留数月甚至数年。

合理的分层策略可使存储成本降低 50%~70%,同时查询延迟保持在可接受范围内。

二、节点角色配置

elasticsearch.yml 中通过节点属性定义角色:

1
2
3
4
5
6
7
8
# 热节点
node.attr.box_type: hot

# 暖节点
node.attr.box_type: warm

# 冷节点
node.attr.box_type: cold

分片分配时通过 index.routing.allocation.include.box_type 控制索引分布:

1
2
3
4
5
6
7
8
9
10
11
# 将新索引分配到热节点
PUT /my-index/_settings
{
"index.routing.allocation.include.box_type": "hot"
}

# 将索引迁移到暖节点
PUT /my-index/_settings
{
"index.routing.allocation.include.box_type": "warm"
}

三、ILM 策略配置

ILM 是 Elasticsearch 原生提供的索引生命周期管理工具,通过 Policy 定义各阶段动作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "1d",
"max_docs": 10000000
},
"set_priority": { "priority": 100 }
}
},
"warm": {
"min_age": "1d",
"actions": {
"set_priority": { "priority": 50 },
"shrink": { "number_of_shards": 1 },
"forcemerge": { "max_num_segments": 1 },
"allocate": {
"require": { "box_type": "warm" },
"number_of_replicas": 1
}
}
},
"cold": {
"min_age": "7d",
"actions": {
"set_priority": { "priority": 0 },
"allocate": { "require": { "box_type": "cold" } },
"freeze": {}
}
},
"delete": {
"min_age": "90d",
"actions": { "delete": {} }
}
}
}
}

各阶段关键动作说明:

Rollover(热节点翻滚):当索引达到任一条件(大小、年龄、文档数)时,自动创建新索引并将旧索引转入下一阶段。结合别名(Alias)可实现写入零停机切换。

Shrink(收缩):将主分片数收缩至 1,减少资源占用。仅在索引不再写入时执行。

Force Merge(强制合并):将分段合并为单一分段,减少查询时的文件句柄开销和 IO 开销。

Allocate(分配):修改分片分配规则,将索引迁移至指定角色节点,并调整副本数。

Freeze(冻结):将索引设为只读并释放大部分内存映射,适合冷数据长期保留。

四、索引模板配置

将 ILM 策略绑定到索引模板,新索引自动应用生命周期管理:

1
2
3
4
5
6
7
8
9
10
11
12
PUT _index_template/logs-template
{
"index_patterns": ["logs-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "logs-policy",
"index.lifecycle.rollover_alias": "logs-write"
}
}
}

使用时通过别名写入:

1
2
3
4
5
6
7
PUT logs-000001/_alias
{
"alias": { "logs-write": { "is_write_index": true } }
}

POST logs-write/_doc
{ "message": "log entry" }

五、运维监控与故障排查

分片分配不均衡

执行 _cat/allocation?v 查看各节点分片数量,如发现倾斜,检查 watermark 设置是否触发导致无法分配:

1
GET _cluster/allocation/explain

ILM 状态异常

查看索引生命周期状态:

1
2
GET _ilm/status
GET /logs-000001/_ilm/explain?human

常见异常原因:ILM 锁冲突(同一索引被多个 Policy 引用)、Rollover Alias 未正确配置、Freeze 前副本数不为零。

冷节点恢复慢

冷节点重启后索引恢复耗时较长,可通过 index.store.type: mmapfs 调整内存映射,并监控恢复进度:

1
GET _cat/recovery?v&h=index,stage,time,files_percent

六、总结

冷热分层架构是 Elasticsearch 大规模运维的必备手段,核心在于:

  1. 节点角色清晰划分,热节点用 SSD 保证写入性能,冷节点用大盘降低存储成本;
  2. ILM Policy 设计要考虑翻滚条件、迁移时机、合并策略的组合,避免单一条件触发导致资源突增;
  3. 生产环境中建议先用 Dev 环境验证 Policy 效果,再逐步灰度到所有索引;
  4. 监控 ILM 执行状态和分片分配情况,及时处理卡住的索引。

通过合理配置冷热分层,可在保障查询性能的前提下大幅压缩存储成本,是日志与时序数据分析场景的标准解决方案。