Elasticsearch 冷热集群架构(Hot-Warm/Hot-Cold)实战指南_es冷热备份自动迁移
1. 概览与设计目标
在大规模日志、监控或业务指标系统中,数据量持续增长,同时访问频率存在明显冷热差异。Elasticsearch 的 冷热分层(Hot-Warm/Hot-Cold)架构正是为了解决以下问题:
-
成本控制
热数据需要高性能 SSD 存储与更多内存,而冷数据访问少,可使用低成本 HDD 或对象存储。 -
数据生命周期管理
通过 ILM(Index Lifecycle Management)策略,自动将索引从热节点迁移到温或冷节点,最终可归档或删除。 -
运维与故障隔离
节点角色分离便于扩容、升级和故障处理,避免单点压力波及整个集群。
适用场景:
-
日志分析系统(ELK/EFK)
-
监控指标存储(Prometheus -> Elasticsearch)
-
业务指标数据(金融、IoT、广告点击数据)
-
时序数据与历史数据归档场景
成本与性能权衡:
通过合理划分,既保证查询性能,又控制存储成本,实现数据生命周期的自动管理。
2. 核心概念与原理
Elasticsearch 冷热分层架构的设计核心在于 节点角色划分、索引生命周期管理、分片策略以及查询路径优化。理解这些核心概念是成功落地 Hot-Warm/Hot-Cold 架构的前提。
2.1 节点类型定义
在冷热架构中,节点可根据角色和硬件规格划分为 Hot、Warm 和 Cold:
data_hot
),写入密集型,高搜索频率data_warm
),索引只读、偶尔查询data_cold
),归档数据说明:Elasticsearch 7.x 和 8.x 的节点角色定义类似,但 8.x 引入了
data_frozen
节点,专门用于极冷数据,通过 Elastic Search Frozen Tier API 直接访问对象存储。
示例节点配置 (elasticsearch.yml
):
# Hot节点配置node.roles: [ \"data_hot\", \"ingest\", \"ml\" ]node.attr.box_type: hot# Warm节点配置node.roles: [ \"data_warm\" ]node.attr.box_type: warm# Cold节点配置node.roles: [ \"data_cold\" ]node.attr.box_type: cold
2.2 索引生命周期(ILM)
ILM(Index Lifecycle Management)用于自动管理索引从创建到删除的全生命周期。
典型 ILM 生命周期阶段:
ILM 示例 JSON(Hot → Warm → Cold → Delete):
{ \"policy\": { \"phases\": { \"hot\": { \"actions\": { \"rollover\": { \"max_size\": \"50gb\", \"max_age\": \"7d\" }, \"set_priority\": { \"priority\": 100 } } }, \"warm\": { \"min_age\": \"7d\", \"actions\": { \"allocate\": { \"require\": { \"box_type\": \"warm\" } }, \"forcemerge\": { \"max_num_segments\": 1 }, \"shrink\": { \"number_of_shards\": 1 }, \"set_priority\": { \"priority\": 50 } } }, \"cold\": { \"min_age\": \"30d\", \"actions\": { \"allocate\": { \"require\": { \"box_type\": \"cold\" } }, \"freeze\": {}, \"set_priority\": { \"priority\": 0 } } }, \"delete\": { \"min_age\": \"90d\", \"actions\": { \"delete\": {} } } } }}
安全提示:
delete
阶段执行前务必确认已备份索引(Snapshot),避免误删生产数据。
2.3 分片与副本策略
冷热架构中分片策略影响性能与存储:
-
Hot 节点
-
分片较小(10-50GB),副本高(1-2),保证写入和搜索性能。
-
-
Warm 节点
-
分片可适当大(50-100GB),副本可降低,减少资源消耗。
-
-
Cold 节点
-
分片尽量大(100-200GB),副本可最少或仅1,冻结索引减少内存占用。
-
Shard Allocation 示例(强制 Hot → Warm):
PUT _cluster/settings{ \"transient\": { \"cluster.routing.allocation.include.box_type\": \"hot\" }}
通过
node.attr.box_type
与allocation filtering
可灵活控制索引迁移。
2.4 查询路径与优化
在冷热架构中,查询请求通常遵循以下路径:
-
热数据优先:ES 自动路由查询到 Hot 节点,保证响应速度。
-
历史查询:可通过索引别名(
current_logs
、archived_logs
)控制访问范围,减少跨冷热节点搜索压力。 -
冷数据查询:可使用
frozen
查询模式,按需加载磁盘或对象存储数据,牺牲部分性能换取成本优化。
索引别名示例:
POST _aliases{ \"actions\": [ { \"add\": { \"index\": \"logs-2025.08.*\", \"alias\": \"current_logs\" } }, { \"add\": { \"index\": \"logs-2025.06.*\", \"alias\": \"archived_logs\" } } ]}
查询时只访问对应别名,减少冷热节点交叉查询开销。
2.5 数据迁移与段合并原理
-
Hot → Warm/Cool迁移通过 ILM
allocate
动作控制。 -
强制合并段 (
forcemerge
) 减少段数量,降低搜索时的 I/O 压力。 -
冻结索引 (
freeze
) 会关闭索引缓存,仅在查询时按需加载数据块,节省内存。
Hot → Warm 强制迁移示例:
POST /logs-2025.07/_ilm/move{ \"current_step\": { \"phase\": \"hot\", \"action\": \"rollover\", \"name\": \"check-rollover-ready\" }}
注意:ILM API 支持手动推进阶段,便于测试和故障恢复。
3. 架构设计与节点规格
在理解了冷热架构的核心原理后,本章节重点讨论 如何根据业务场景设计集群架构、节点规格、网络拓扑,以及索引分层策略,确保性能、成本与可维护性达到平衡。
3.1 节点角色划分与硬件规格
冷热架构通常将节点划分为 Hot、Warm、Cold,部分场景还可增加 Master、协调节点(Coordinating Node)以提升集群稳定性。
说明:
Hot 节点 CPU 与内存占比高,保证索引和搜索吞吐。
Warm 节点可减少副本,提高存储效率。
Cold 节点可使用大容量 HDD 或 Elastic Cloud Frozen Tier,降低成本。
Master 节点与数据节点分离,提升集群稳定性。
3.2 集群拓扑设计
一个标准的冷热集群拓扑示意:
+------------------+ | Master | | 3-5 节点冗余 | +------------------+ | ---------------------------------------- | | | +--------+ +--------+ +--------+ | Hot 1 | | Hot 2 | | Hot 3 | +--------+ +--------+ +--------+ | | | ------------- ------------- ------------- | Warm 1 | | Warm 2 | | Warm 3 | ------------- ------------- ------------- | | | ------------- ------------- ------------- | Cold 1 | | Cold 2 | | Cold 3 | ------------- ------------- -------------
设计思路:
Master 节点独立,避免被数据压力影响。
Hot 节点用于写入和高频查询。
Warm 节点按时间序列划分索引,负责历史分析。
Cold 节点用于归档和低频查询。
可配置协调节点提升复杂查询性能,尤其是跨冷热节点聚合。
3.3 索引分层与别名策略
为了支持高效查询与 ILM 自动迁移,通常采用 索引按时间分层 + 别名管理。
索引策略示例:
索引别名操作示例(Kibana Dev Tools):
POST _aliases{ \"actions\": [ { \"add\": { \"index\": \"logs-2025.08.27\", \"alias\": \"current_logs\" } }, { \"add\": { \"index\": \"logs-2025.07.*\", \"alias\": \"archived_logs\" } }, { \"add\": { \"index\": \"logs-2025.01.*\", \"alias\": \"cold_logs\" } } ]}
通过别名,应用程序无需感知索引迁移,实现查询透明化。
3.4 Shard Allocation 与数据迁移策略
-
Shard Allocation 策略
-
Hot 节点:小分片、高副本
-
Warm 节点:中分片、适度副本
-
Cold 节点:大分片、低副本
-
示例:按节点属性分配分片:
PUT _cluster/settings{ \"persistent\": { \"cluster.routing.allocation.awareness.attributes\": \"box_type\", \"cluster.routing.allocation.enable\": \"all\" }}
ILM allocate 示例:
\"allocate\": { \"require\": { \"box_type\": \"warm\" }}
-
时间序列数据迁移
-
Hot 节点索引达到 Rollover 条件(如 50GB 或 7天) → 自动迁移到 Warm
-
Warm 阶段再经过 30天 → 迁移到 Cold
-
使用 ILM 自动完成,避免人工干预。
-
3.5 网络与高可用设计
-
Hot 节点与 Warm/Cold 节点之间最好在同一机房或低延迟网络环境,减少分片迁移时间。
-
Master 节点建议使用奇数个(3或5)形成选主仲裁。
-
数据节点建议每个节点 rack-aware 分布,避免单点机架故障影响整个索引。
Allocation Awareness 示例:
PUT _cluster/settings{ \"persistent\": { \"cluster.routing.allocation.awareness.attributes\": \"rack_id\" }}
Rack-aware 配置可确保同一分片副本不在同一机架,提升容错能力。
3.6 实践建议
-
热点索引每日 Rollover,避免分片过大影响搜索性能。
-
Warm 节点可以减少副本,降低存储成本,同时执行
forcemerge
合并段,提高查询效率。 -
Cold 节点分片大,建议开启
frozen
功能访问对象存储,节省内存和磁盘。 -
确保 Master 节点与协调节点独立,防止集群元数据阻塞写入或查询。
4. 部署与配置实战
本章节将围绕 冷热集群的部署与配置,提供可直接复制的示例,包括节点配置、ILM 策略、索引模板、Shard Allocation、Snapshot 快照策略以及测试验证方法,帮助工程师快速落地冷热分层架构。
4.1 节点配置 (elasticsearch.yml
)
Hot 节点配置示例
cluster.name: es-hot-warmnode.name: hot-1node.roles: [ \"data_hot\", \"ingest\" ]node.attr.box_type: hotpath.data: /data/elasticsearchpath.logs: /var/log/elasticsearchnetwork.host: 0.0.0.0http.port: 9200# Heap 内存,建议 50% 内存不超过 32GB# jvm.options 示例# -Xms64g# -Xmx64gdiscovery.seed_hosts: [\"master1\", \"master2\", \"master3\"]cluster.initial_master_nodes: [\"master1\", \"master2\", \"master3\"]
Warm 节点配置示例
node.name: warm-1node.roles: [ \"data_warm\" ]node.attr.box_type: warmpath.data: /data/elasticsearchpath.logs: /var/log/elasticsearchnetwork.host: 0.0.0.0http.port: 9200
Cold 节点配置示例
node.name: cold-1node.roles: [ \"data_cold\" ]node.attr.box_type: coldpath.data: /data/elasticsearchpath.logs: /var/log/elasticsearchnetwork.host: 0.0.0.0http.port: 9200
4.2 ILM 策略部署
完整 JSON 示例(Hot → Warm → Cold → Delete)
PUT _ilm/policy/logs_hot_warm_cold_policy{ \"policy\": { \"phases\": { \"hot\": { \"min_age\": \"0ms\", \"actions\": { \"rollover\": { \"max_size\": \"50gb\", \"max_age\": \"7d\" }, \"set_priority\": { \"priority\": 100 } } }, \"warm\": { \"min_age\": \"7d\", \"actions\": { \"allocate\": { \"require\": { \"box_type\": \"warm\" } }, \"forcemerge\": { \"max_num_segments\": 1 }, \"shrink\": { \"number_of_shards\": 1 }, \"set_priority\": { \"priority\": 50 } } }, \"cold\": { \"min_age\": \"30d\", \"actions\": { \"allocate\": { \"require\": { \"box_type\": \"cold\" } }, \"freeze\": {}, \"set_priority\": { \"priority\": 0 } } }, \"delete\": { \"min_age\": \"90d\", \"actions\": { \"delete\": {} } } } }}
⚠️ 安全提示:执行 Delete 前必须确保已完成 Snapshot 备份。
4.3 索引模板配置
PUT _template/logs_template{ \"index_patterns\": [\"logs-*\"], \"template\": { \"settings\": { \"number_of_shards\": 5, \"number_of_replicas\": 1, \"index.lifecycle.name\": \"logs_hot_warm_cold_policy\", \"index.lifecycle.rollover_alias\": \"current_logs\" }, \"mappings\": { \"properties\": { \"timestamp\": { \"type\": \"date\" }, \"message\": { \"type\": \"text\" }, \"level\": { \"type\": \"keyword\" } } }, \"aliases\": { \"current_logs\": {} } }}
使用
rollover_alias
配合 ILM,实现 Hot 索引自动 Rollover。
4.4 Shard Allocation 配置
PUT _cluster/settings{ \"persistent\": { \"cluster.routing.allocation.awareness.attributes\": \"box_type\", \"cluster.routing.allocation.enable\": \"all\" }}
-
Hot → Warm/Cool 自动迁移通过 ILM 的
allocate
动作控制。 -
可通过手动 API 验证分片迁移状态:
GET _cat/shards?v&h=index,shard,prirep,state,node
4.5 冷热分层验证方法
-
创建 Hot 索引并写入数据
-
检查分片是否在 Hot 节点:
GET _cat/shards?v&h=index,shard,prirep,state,node
-
人工推进 ILM 到 Warm
-
查看分片迁移到 Warm 节点
-
再推进 Cold,验证
freeze
和低优先级状态
通过这种方式,可在测试环境确认 ILM 策略和节点分层配置是否按预期生效。