Skip to content

Elasticsearch 核心原理

理解 Elasticsearch 时,可以围绕倒排索引、分片副本、写入流程、查询流程、refresh、segment merge、深分页和 term/match 区别展开。


1. ES 是什么

Elasticsearch 是基于 Lucene 的分布式搜索和分析引擎。

适合:

  • 全文检索。
  • 日志检索。
  • 聚合分析。
  • 多条件复杂查询。

不适合:

  • 强事务系统。
  • 高频更新的核心账务数据。
  • 替代关系型数据库做强一致存储。

2. 倒排索引

关系型数据库常用正向索引:

text
文档 -> 包含哪些词

搜索引擎核心是倒排索引:

text
词 -> 出现在哪些文档

例如:

text
doc1: Java 并发 编程
doc2: Java 虚拟机
doc3: Redis 缓存

倒排索引:

text
Java -> doc1, doc2
并发 -> doc1
Redis -> doc3

这样搜索某个词时,可以快速定位文档列表。


3. 分词

全文检索字段会经过分词器处理。

分词器通常包含:

text
character filter -> tokenizer -> token filter

中文搜索通常需要 IK、jieba 等中文分词方案。


4. index、shard、replica

概念含义
index类似逻辑表
document一条文档
field文档字段
shard主分片,承载部分数据
replica副本分片,提供高可用和读扩展

一个 index 可以拆成多个 primary shard,每个 primary shard 可以有多个 replica。


5. 写入流程

简化流程:

text
客户端写入文档
  -> 协调节点根据路由找到 primary shard
  -> primary shard 写入内存 buffer 和 translog
  -> 转发给 replica shard
  -> replica 写入成功
  -> 返回客户端

写入后不是立刻能被搜索到,要等 refresh。


6. refresh、flush、merge

6.1 refresh

refresh 会把内存 buffer 中的数据生成新的 segment,并让它对搜索可见。

ES 近实时搜索的原因就是 refresh 不是每次写入都执行,而是周期性执行。

6.2 flush

flush 会把内存中的数据更彻底地持久化,并生成 commit point,同时清理 translog。

6.3 merge

Lucene segment 是不可变的。频繁 refresh 会产生很多小 segment。

merge 会把多个小 segment 合并成大 segment,并清理已删除文档。

代价:

  • 消耗 CPU。
  • 消耗磁盘 IO。
  • 可能影响写入和查询性能。

7. 查询流程

ES 查询通常分两个阶段:

text
query phase
fetch phase

7.1 query phase

协调节点把查询请求转发给相关 shard。每个 shard 本地查询并返回 top N 文档 ID 和排序信息。

7.2 fetch phase

协调节点合并排序结果后,再去对应 shard 拉取完整文档内容。


8. term 和 match

查询特点场景
term不分词,精确匹配倒排词项keyword、状态码、枚举值
match会对查询内容分词text 全文检索

如果对 text 字段用 term 查询,容易查不到,因为索引时已经分词。

如果对 keyword 字段用 match,通常也能查,但语义上不如 term 精确。


9. 深分页问题

普通分页:

json
{
  "from": 10000,
  "size": 10
}

深分页代价很高,因为每个 shard 都要取大量候选结果,协调节点再合并排序。

解决方式:

  • 限制最大分页深度。
  • 使用 search_after
  • 使用 point in time(PIT)保证翻页期间视图稳定。
  • 业务上避免跳到特别深的页。

10. 为什么 ES 是近实时

写入文档后,数据先进入内存 buffer 和 translog。只有 refresh 后,新 segment 被打开,数据才对搜索可见。

因此 ES 不是严格实时,而是近实时。


11. 理解检查

ES 为什么查询快?

核心是倒排索引,可以从词快速定位文档集合,而不是逐行扫描。

refresh 和 flush 区别?

refresh 让数据对搜索可见;flush 更偏持久化和 translog 清理。

为什么深分页慢?

因为每个 shard 都要构造大量排序结果,协调节点再合并,内存和 CPU 成本高。

为什么写入太频繁会影响查询?

频繁写入和 refresh 会产生大量 segment,merge 又会消耗 IO 和 CPU。


12. 总结

ES 的核心链路是:倒排索引用于快速检索,分片副本用于分布式扩展和高可用,refresh 带来近实时搜索,segment merge 影响写入和查询性能。理解时要避免把 ES 当成普通数据库。

Released under the MIT License.