Elasticsearch介绍

Elasticsearch(ES)的工作原理可以高度概括为**"分布式、倒排索引、近实时搜索"**。

1. 核心基石:倒排索引(Inverted Index)

这是ES搜索飞快的根本原因。不同于传统数据库(正排索引:ID -> 内容),倒排索引是 内容 -> ID

  • 例子:你有三篇文档。

    • 文档1:"苹果好吃"

    • 文档2:"香蕉好吃"

    • 文档3:"苹果营养"

  • 倒排索引构建

    • 苹果 -> 文档1, 文档3

    • 好吃 -> 文档1, 文档2

    • 营养 -> 文档3

  • 查询时 :当你搜索"苹果",ES直接命中索引,瞬间返回文档1和3,不需要扫描所有数据


2. 数据写入流程(Index / Write)

ES写入并不是直接写磁盘,而是走 Memory Buffer -> Filesystem Cache -> Segment -> Commit 的路线,这是它**近实时(Near Real-Time)**的关键。

  1. 写入内存缓冲区(Buffer) :数据到达时,先写入Transaction Log(防止宕机丢数据),同时将原始JSON文档放入内存Buffer中,此时数据不可被搜索

  2. Refresh(刷新) :默认每隔 1秒 ,ES会执行Refresh操作,将Buffer中的数据冲刷到操作系统的文件缓存(Filesystem Cache)中,并生成一个新的分段(Segment)

    • 关键点 :此时数据已经可以搜索 ,但尚未落盘(Fsync)。这就是ES被称为"近实时"(延迟1秒)的原因。
  3. Flush(冲刷):当Translog太大或每隔30分钟,ES会执行Flush。将所有内存中的Segment刷入磁盘,并清空Translog。此时数据才算真正持久化。


3. 数据读取流程(Search / Read)

ES的读取分为Query Phase(查询阶段)Fetch Phase(取回阶段) ,且利用**分片(Shard)**并行工作。

假设你有3个节点,索引被分为2个主分片(Primary)和2个副本分片(Replica)。

  • Query Phase :协调节点(Coordinating Node)收到搜索请求,会将请求广播给所有分片(主或副本)。每个分片在本地利用倒排索引找到匹配的文档ID,但只返回文档ID和评分给协调节点。协调节点对全局所有ID进行合并排序。

  • Fetch Phase :协调节点根据排好序的ID列表,再次请求各个分片,获取文档的完整原始_source数据,返回给客户端。


4. 核心底层数据结构

为了让倒排索引更快,ES使用了以下核心编码技术:

  • FST(Finite State Transducer,有限状态转换器):用于存储词典(Term Dictionary),内存占用极小,查询速度极快(O(1)级别)。

  • 跳跃表(Skip List):用于在多个Posting List(文档ID列表)之间快速求交集(AND)或并集(OR)。

  • BKD Tree :用于数值类型地理位置的范围查询(Range Query),而非倒排索引。


5. 分布式架构原理(去中心化)

  • Master Node(主节点):只负责管理集群状态(创建索引、分配分片),不参与数据读写,防止脑裂。

  • 数据节点(Data Node):负责存储数据和执行实际的搜索计算。

  • 路由算法 :当你写入一条数据时,ES通过公式 shard_num = hash(_routing) % number_of_primary_shards 决定该数据去哪个分片,保证同一文档永远在固定分片,方便查询时定位。


6. 你必须要知道的"坑"(面试重点)

  • 删除不是真删除 :ES的删除只是给文档打上deleted标记,在Segment Merge时才会物理清除,所以频繁删除会导致性能下降。

  • Segment是不可变的 :一旦写磁盘就永不改变。ES通过后台Merge进程将多个小Segment合并成大Segment,释放被标记删除的空间,这也是写性能高的原因(没有锁竞争)。


一句话总结

Elasticsearch 通过"倒排索引"实现快速匹配,通过"内存Buffer + 每秒Refresh"实现近实时搜索,通过"分片 + 副本"实现高可用和水平扩展,通过"Segment合并"实现后台异步持久化。