Elasticsearch之基本原理
Elasticsearch (ES) 核心原理图示说明其分布式架构、索引机制、搜索过程及高可用设计。
一、Elasticsearch 核心定位
分布式、近实时的搜索与分析引擎,核心能力:
- 🔍 全文搜索:高效检索非结构化文本(如日志、文档)。
- 📊 数据分析:聚合(Aggregation)实现复杂数据分析(如统计、分组、直方图)。
- ⚡ 近实时 (NRT):数据写入后 1s 内 可被搜索。
- 📦 分布式存储与计算:自动分片(Sharding)、副本(Replica),支持水平扩展。
二、核心架构图解
1. 集群(Cluster)与节点(Node)
+---------------------+
| Elasticsearch |
| Cluster |
+----------+----------+
|
+---------------------------+---------------------------+
| | |
+--------+-------+ +---------+---------+ +-------+--------+
| Node 1 | | Node 2 (Master) | | Node 3 |
| +------------+ | | +---------------+ | | +------------+ |
| | Shard P0 | | | | Shard P1 (R) | | | | Shard R0 | |
| | (Primary) | | | | (Primary) | | | | (Replica) | |
| +------------+ | | +---------------+ | | +------------+ |
| | | +---------------+ | | +------------+ |
| +------------+ | | | Shard R1 | | | | Shard P1 | |
| | Shard R1 | | | | (Replica) | | | | (Replica) | |
| | (Replica) | | | +---------------+ | | +------------+ |
| +------------+ | | | | |
+----------------+ +-------------------+ +----------------+
- 集群 (Cluster):多个节点(Node)的集合。
节点 (Node):
- Master Node:管理集群状态(分片分配、节点加入/离开)。图中
Node 2
。 - Data Node:存储分片数据(如
Node 1
,Node 3
)。 - 协调节点 (Coordinating Node):接收客户端请求,转发到相关节点(默认所有节点均可担任)。
- Master Node:管理集群状态(分片分配、节点加入/离开)。图中
分片 (Shard):
- 主分片 (Primary Shard):数据写入的目标分片(如
P0
,P1
)。 - 副本分片 (Replica Shard):主分片的拷贝,提供高可用与读负载均衡(如
R0
,R1
)。
- 主分片 (Primary Shard):数据写入的目标分片(如
💡 分片路由公式:shard_num = hash(_routing) % num_primary_shards
默认_routing = document_id
三、倒排索引(Inverted Index)原理
倒排索引结构
文档集合:
Doc1: "The quick brown fox"
Doc2: "The quick dog"
Doc3: "The brown dog"
倒排列表(Postings List):
Term │ Postings List (DocID, Position)
──────────┼───────────────────────────────
"the" │ [(1,0), (2,0), (3,0)]
"quick" │ [(1,1), (2,1)]
"brown" │ [(1,2), (3,1)]
"fox" │ [(1,3)]
"dog" │ [(2,2), (3,2)]
- 核心思想:从词项(Term) 映射到包含该词的文档列表。
组成:
- Term Dictionary:排序的词项列表(常存于内存)。
- Postings List:包含词项的文档ID列表及位置信息(存于磁盘)。
压缩优化:
- FOR (Frame Of Reference):对文档ID差值(Delta)编码压缩。
- Roaring Bitmaps:高效存储文档ID集合。
四、数据写入与近实时(NRT)搜索流程
写入流程时序图
Client │ Coordinating Node │ Primary Shard │ Replica Shards
─────────────┼──────────────────────────────┼────────────────────────┼─────────────────────
1. Index Req │ │ │
───────────> │ 2. Route to Primary (P0) │ │
│ ───────────────────────────> │ │
│ │ 3. Write to Translog │
│ │ (Crash-Safe) │
│ │ 4. Add to In-Mem Buffer│
│ │ │
│ 5. Ack (200) <──────────────┼ │
6. Ack <─────┤ │ │
│ │ 7. Refresh (1s) │
│ │ ┌───────────────────┐│
│ │ │ In-Mem Buffer ───┼┼──> Segment (Cache)
│ │ └───────────────────┘│
│ │ 8. Replicate to Replicas (Async)
│ │ ────────────────────────>
│ │ │
│ │ 9. Flush (30m / 512MB)│
│ │ ┌───────────────────┐│
│ │ │ Translog + Cache ─┼┼──> New Segment (Disk)
│ │ └───────────────────┘│
关键步骤:
- Translog 写入:数据先写事务日志(类似 DB Redo Log),确保崩溃恢复。
- 内存缓存 (In-Mem Buffer):文档暂存内存。
Refresh(默认 1s):
- 将内存缓存转为 不可变的 Lucene Segment(在文件系统缓存)。
- 此时文档可被搜索(NRT 的核心)。
Flush:
- 将文件系统缓存中的 Segment 写入磁盘(
.fdt
,.fdx
等文件)。 - 清空 Translog(生成新 Translog)。
- 将文件系统缓存中的 Segment 写入磁盘(
- 副本同步:异步复制数据到 Replica Shards。
五、分布式搜索执行流程
搜索流程图
Client │ Coordinating Node │ Data Node (Shard P0) │ Data Node (Shard P1)
─────────────┼─────────────────────┼──────────────────────────┼─────────────────────────
1. Search Req│ │ │
───────────> │ 2. Query Parsing │ │
│ 3. Route to all │ │
│ relevant shards │ │
│ ────────────────────> │
│ │ 4. Execute Query (Lucene)│
│ │ - Term Lookup │
│ │ - Scoring (BM25/TF-IDF)│
│ │ 5. Return Top Docs │
│ <──────────────────── │
│ │ ────────────────────────>
│ │ │ 4. Execute Query (Lucene)
│ │ │ 5. Return Top Docs
│ <───────────────────────────────────────────────
│ 6. Merge Results │ │
│ (Sort/Aggs) │ │
7. Result <──┤ │ │
关键阶段:
Query Phase:
- 协调节点将查询广播到相关分片(主或副本)。
- 每个分片在本地执行搜索,返回 文档ID + 排序值(如
_score
)。
Fetch Phase:
- 协调节点合并所有分片结果(排序、分页)。
- 根据文档ID从对应分片拉取完整数据(
_source
字段)。
聚合 (Aggregation):
- 在 Query Phase 中,各分片先计算本地聚合结果。
- 协调节点汇总所有分片结果生成全局聚合。
六、高可用与容灾设计
分片分配与故障恢复
正常状态: Node1故障后:
+------+ +------+ +------+ +------+ +------+ +------+
| P0 | | R0 | | P1 | | | | R0↑ | | P1 |
| (N1) | | (N2) | | (N3) | | (X) | | (N2) | | (N3) |
+------+ +------+ +------+ +------+ +------+ +------+
| R1 | | P1 | | R0 | | | | P1↑ | | R0 |
| (N2) | | (N1) | | (N1) | | (X) | | (N3) | | (N2) |
+------+ +------+ +------+ +------+ +------+ +------+
副本的价值:
当
Node1
宕机时:- 副本分片
R0
(在Node2
)提升为新的主分片P0
。 - 副本分片
R1
因节点丢失变为未分配状态。 - 集群自动在新节点(如
Node4
)重建缺失副本。
- 副本分片
分片分配策略:
- 主分片与副本不在同一节点(通过
index.routing.allocation
控制)。 - 支持机架感知(
awareness
)避免单机房故障。
- 主分片与副本不在同一节点(通过
七、性能调优核心策略
1. 分片设计优化
+---------------------+ +---------------------+
| Hot Data Tier | | Warm Data Tier |
| (SSD, High CPU) | | (HDD, Low CPU) |
| | | |
| Index: logs-2023-10| | Index: logs-2023-09|
| Shards: 10 | | Shards: 5 (Reduced)|
| Replicas: 1 | | Replicas: 0 |
+----------+----------+ +----------+----------+
│ │
│ ILM Policy │
│ (Index Lifecycle Management) │
└──────────────────────────────>│
分片数规划:
- 单个分片大小建议 20GB–50GB(最大不超过 100GB)。
- 避免“过度分片”(每个分片消耗内存/CPU)。
冷热分层 (Hot-Warm Architecture):
- Hot 层:新写入索引,部署在 SSD + 高配 CPU 节点。
- Warm 层:只读历史索引,部署在 HDD + 低配 CPU 节点。
- 通过 ILM (Index Lifecycle Management) 自动迁移索引。
2. 查询优化技巧
- 避免深度分页:用
search_after
替代from/size
。 - 使用 Filter Context:对不参与评分的条件(如
status=active
)用filter
,利用缓存。 聚合优化:
- 小基数聚合用
terms
+size
。 - 大基数用
composite
聚合分批查询。
- 小基数聚合用
八、典型应用场景
场景 | ES 特性应用 | 案例 |
---|---|---|
日志分析 (ELK) | 高吞吐写入 + 聚合分析 | Nginx 日志错误率统计 |
全文搜索引擎 | 倒排索引 + BM25 相关性排序 | 电商商品搜索 |
指标监控 | Metricbeat + Kibana 可视化 | Kubernetes 集群监控 |
安全分析 (SIEM) | 实时检测规则 + 关联分析 | 用户异常登录行为识别 |
总结:Elasticsearch 核心优势
- 分布式可扩展性:自动分片与副本,线性扩展至 PB 级。
- 搜索性能:倒排索引 + 列存(Doc Values) + 近实时刷新。
- 生态完备:Kibana(可视化)、Logstash/Beats(数据采集)、APM(应用监控)。
- 云原生支持:ECK (Elastic Cloud on Kubernetes) 简化运维。
掌握 ES 的关键是理解 分片路由机制、倒排索引原理、NRT 实现 和 集群故障恢复逻辑。结合图示理解其分布式设计,能更高效地部署与调优。