Elasticsearch 系统架构深度解析:从内核到实战(超详细图文教程)
作者:IT之一小佬
发布日期:2025年10月20日
阅读时间:25分钟
适合人群:后端开发、SRE、搜索工程师、架构师
🌟 引言:Elasticsearch 为何能扛住亿级数据?
你是否好奇:
- 为什么 Elasticsearch 能在毫秒级返回亿级文档的搜索结果?
- 它如何实现高可用和水平扩展?
- 数据是如何在集群中流动的?
这一切都源于其精妙的分布式系统架构。
本教程将带你深入 Elasticsearch 的内部架构,从网络层到存储引擎,从协调节点到分片分配,结合图解与真实场景,彻底揭开它的神秘面纱。
✅ 目标:读完本文,你将掌握 Elasticsearch 的核心架构原理,具备设计高性能、高可用集群的能力。
一、Elasticsearch 架构全景图
┌─────────────────────────────────────┐
│ Client Applications │
│ (Kibana, Logstash, Apps, Postman) │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Coordinating Node(s) │
│ (接收请求、路由、合并结果) │
└─────────────────────────────────────┘
╱ │ ╲
╱ │ ╲
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Master Node │ │ Data Node │ │ Ingest Node │
│ (管理集群状态) │ │(存储+搜索+聚合) │ │ (预处理数据) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
╱ │ │ ╲
╱ │ │ ╲
▼ ▼ ▼ ▼
┌───────────────────────────────────┐
│ Lucene Index │
│ (倒排索引 + 正向索引 + 存储) │
└───────────────────────────────────┘
二、架构核心层详解
1. 客户端层(Client Layer)
角色
- 发起请求的应用程序
- 包括:Kibana、Logstash、Beats、自定义应用、Postman
通信协议
- HTTP/REST API:最常用,JSON 格式
- Transport Client(已废弃)
- Java High-Level REST Client / Java API Client
- Elasticsearch SDKs(Python、Go、.NET 等)
✅ 建议:优先使用官方 SDK 或直接调用 REST API。
2. 协调节点(Coordinating Node)
📌 定义
任何节点都可以作为协调节点。它负责:
- 接收客户端请求
- 将请求路由到正确的分片
- 合并来自多个分片的结果
- 返回最终响应
🔍 工作流程(以搜索为例)
1. 客户端 → 协调节点(Node A)
2. Node A → 查询路由表 → 确定 P0, P1, R0, R1 参与查询
3. Node A 并行发送请求到:
- Node B (P0)
- Node C (P1)
- Node D (R0)
- Node E (R1)
4. 收集所有响应 → 合并排序 → 返回客户端
⚠️ 性能陷阱
- 如果协调节点负载过高(如频繁复杂查询),可能成为瓶颈
- 解决方案:部署专用协调节点,或确保 Data 节点有足够资源
3. 主节点(Master-eligible Node)
📌 定义
有资格参与主节点选举的节点。集群必须有且仅有一个主节点(Master Node)。
🔑 核心职责
| 职责 | 说明 |
|---|---|
| 集群状态管理 | 维护索引创建/删除、分片分配等元数据 |
| 节点发现与加入 | 处理新节点加入请求 |
| 故障检测 | 检测节点宕机并触发恢复 |
| 分片再平衡 | 在节点增减时重新分配分片 |
✅ 高可用配置
# elasticsearch.yml
node.roles: [ master ]
discovery.seed_hosts: ["master1", "master2", "master3"]
cluster.initial_master_nodes: ["master1", "master2", "master3"]
💡 最佳实践:
- 使用 奇数个(3 或 5)专用主节点
- 避免主节点同时承担数据角色(防止资源争抢)
4. 数据节点(Data Node)
📌 定义
存储分片数据,执行数据相关操作(索引、搜索、聚合)的节点。
🔑 核心职责
| 职责 | 说明 |
|---|---|
| 存储分片 | 主分片和副本分片都存储在数据节点 |
| 执行查询 | 在本地分片上执行搜索和聚合 |
| 索引文档 | 接收写入请求,更新 Lucene 索引 |
| 段合并 | 后台优化 Lucene 段(Segments) |
✅ 配置示例
node.roles: [ data ]
node.attr.box_type: hot # 可用于冷热架构
💡 性能建议:
- 使用 SSD 磁盘
- 内存 ≥ 32GB,堆内存 ≤ 31GB(避免 JVM 大页问题)
- CPU 核心数影响并行处理能力
5. Ingest 节点(预处理节点)
📌 定义
在索引前对文档进行预处理的节点。
🔍 典型处理操作
| 处理类型 | 示例 |
|---|---|
| 解析 | 解析 CSV、JSON、日志格式 |
| 转换 | 重命名字段、类型转换 |
| 丰富 | 添加地理信息(通过 IP)、用户画像 |
| 删除 | 移除敏感字段 |
✅ Pipeline 示例
PUT _ingest/pipeline/user_log_pipeline
{
"description": "Parse user logs",
"processors": [
{
"grok": {
"field": "message",
"patterns": ["%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:msg}"]
}
},
{
"date": {
"field": "timestamp",
"target_field": "@timestamp"
}
},
{
"remove": { "field": "timestamp" }
}
]
}
使用:
PUT /logs/_doc/1?pipeline=user_log_pipeline
{ "message": "2025-10-20T10:00:00Z INFO User login successful" }
✅ 部署建议:对于大量日志处理,建议设置专用 Ingest 节点。
三、数据存储层:Lucene 引擎
Elasticsearch 是构建在 Lucene 之上的分布式封装。理解 Lucene 是理解 ES 存储的关键。
1. 倒排索引(Inverted Index)
📌 核心思想
- 传统:文档 → 词列表
- 倒排:词 → 文档列表
🔍 示例
原始文档:
Doc1: "Elasticsearch is fast"
Doc2: "Fast search with Elasticsearch"
倒排索引:
elasticsearch → [Doc1, Doc2]
fast → [Doc1, Doc2]
search → [Doc2]
with → [Doc2]
is → [Doc1]
✅ 优势:搜索“fast”时,直接定位到 Doc1 和 Doc2,无需扫描所有文档。
2. 正向索引(Stored Fields)
- 存储文档的原始 JSON 字段(
_source) - 用于返回搜索结果中的
_source字段 - 可禁用以节省空间(但无法高亮、重新索引)
3. 段(Segment)与刷新(Refresh)
📌 Lucene 段机制
- 数据先写入内存缓冲区
- 每 1秒(默认)执行一次
refresh:- 内存数据 → 新段(Segment)
- 段变为可搜索
- 这就是 Elasticsearch 的近实时(NRT) 特性
🔍 刷新流程
Memory Buffer → (refresh) → OS Cache (Segment) → (flush) → Disk
⚠️
refresh_interval可调整,但频繁刷新影响性能。
4. 提交(Flush)与事务日志(Translog)
| 操作 | 目的 | 频率 |
|---|---|---|
| Refresh | 使文档可搜索 | 默认 1s |
| Flush | 将段持久化到磁盘 | 默认 30m 或 translog 太大 |
| Translog | 记录所有写操作,用于故障恢复 | 实时追加 |
✅ 持久化保障:写操作先写 Translog,再写内存。即使宕机,重启后从 Translog 恢复。
四、分片与复制机制
1. 分片(Shard)分配策略
- 主分片在创建索引时确定,不可更改
- 副本分片可动态调整
- 分配原则:
- 同一分片的主副本不放在同一节点
- 尽量均衡分布
2. 写操作流程
Client → Coordinating Node → Primary Shard → Replica Shard(s) → Ack
- 默认
wait_for_active_shards=all,等待所有活跃分片确认 - 可设置
consistency=one/quorum/all
3. 读操作流程
Client → Coordinating Node → 随机选择主分片或副本分片 → 返回结果
- 副本提升读吞吐量和容错能力
五、集群状态与发现机制
1. 集群状态(Cluster State)
- 包含:索引元数据、分片位置、节点信息
- 由主节点管理,通过 Gossip 协议广播给所有节点
- 存储在内存中,快速访问
2. 节点发现(Discovery)
- Zen Discovery(旧版)
- Coordinator-based discovery(7.0+)
- 使用
discovery.seed_hosts配置种子节点 - 新节点启动时连接种子节点,加入集群
六、典型生产架构模式
1. 通用型架构(中小规模)
┌─────────────────┐
│ Client │
└────────┬────────┘
▼
┌─────────────────┐
│ Coordinating │
│ Nodes (2-3) │
└────────┬────────┘
▼
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Master │ │ Data │ │ Ingest │
│ Nodes (3) │ │ Nodes (N) │ │ Nodes (2) │
└───────────┘ └───────────┘ └───────────┘
2. 冷热架构(大规模日志)
Hot Tier (SSD): Ingest + Hot Data Nodes → 快速写入和近期查询
Warm Tier (HDD): Warm Data Nodes → 旧数据,低频查询
Cold Tier: Cold Data Nodes → 归档数据
Frozen Tier: Searchable Snapshots → 极低成本归档
使用 Index Lifecycle Management (ILM) 自动迁移。
七、架构最佳实践
| 实践 | 说明 |
|---|---|
| 分离角色 | Master、Data、Ingest 节点分离 |
| 合理分片 | 单分片 ≤ 50GB,单节点 ≤ 1000 分片 |
| 监控 Translog | 避免 translog too large 错误 |
| 备份快照 | 定期 Snapshot 到 S3/HDFS |
| JVM 调优 | 堆内存 ≤ 31GB,UseG1GC |
| 安全加固 | 开启 TLS、RBAC、审计日志 |
八、常见架构问题排查
❌ 问题:集群状态为 red 或 yellow
排查步骤:
GET /_cluster/health→ 查看unassigned_shardsGET /_cat/shards?v→ 找出未分配分片GET /_cluster/allocation/explain→ 诊断原因(磁盘满?节点离线?)
❌ 问题:搜索延迟高
排查方向:
- 协调节点 CPU 高?→ 增加协调节点
- 数据节点 IO 高?→ 升级磁盘或增加节点
- 分片过多?→ 减少分片数或使用
search shards聚合
九、总结:Elasticsearch 架构核心要点
| 层级 | 组件 | 关键作用 |
|---|---|---|
| 接入层 | Client / Coordinating | 请求入口与结果聚合 |
| 控制层 | Master Node | 集群大脑,管理元数据 |
| 数据层 | Data Node + Lucene | 存储与检索核心 |
| 预处理层 | Ingest Node | 数据清洗与转换 |
| 存储引擎 | Lucene Segments | 倒排索引实现近实时搜索 |
🔚 结语
现在,你已经掌握了 Elasticsearch 的完整系统架构:
- 理解了 协调、主、数据、Ingest 节点的分工协作
- 明白了 Lucene 倒排索引如何实现毫秒搜索
- 学会了 分片与副本的分布式机制
- 掌握了 生产级架构设计的最佳实践
这些知识让你不仅能“使用”Elasticsearch,更能“驾驭”它,应对复杂的搜索与分析场景。
💬 评论区互动:你的生产环境采用了哪种架构?遇到了哪些挑战?欢迎分享你的经验!
Elasticsearch架构深度解析
891

被折叠的 条评论
为什么被折叠?



