作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。
中间件,我给它的定义就是为了实现某系业务功能依赖的软件,包括如下部分:
Web服务器
代理服务器
ZooKeeper
Kafka
RabbitMQ
Hadoop HDFS
Elasticsearch ES (本章节)
前面我们用了2个小节ES利用到2个技术:倒排索引和分词,但是我们开发软件是不是要直接基于这2个技术直接来实现细节么,当然是不用的,今天我们就来介绍一个框架或者库:Lucene。
可以将 Elasticsearch 理解为一个强大的分布式搜索和分析系统,它构建在 Apache Lucene 这个高性能、全功能的全文检索引擎库之上。Lucene 是一个高性能的全文检索引擎库(Library),其核心能力正是建立在倒排索引和分词技术之上。
核心角色:搜索引擎库
-
Lucene 不是一个像 ES 那样开箱即用的完整搜索引擎应用程序(带服务器、集群、REST API 等)。
-
它是一个用 Java 编写的库(Library),提供了一套强大的 API,允许开发者将这些功能嵌入到自己的应用程序中,构建定制化的搜索功能。
-
ES 利用 Lucene 库来处理单个分片(Shard)级别的所有底层索引和搜索操作。每个 ES 分片本质上就是一个独立的 Lucene 索引。
Lucene 的核心数据结构:索引
-
当你在 ES 中索引一个文档时,ES 最终会调用 Lucene 的 API 将该文档写入一个 Lucene 索引中(对应 ES 的一个分片)。
-
一个 Lucene 索引 是存储在文件系统上的一组文件,包含了一个文档集合的所有可搜索数据。
倒排索引 (Inverted Index): 这是 Lucene 的基石,也是 ES 高效全文搜索的根源。它存储了词项(Term)到包含该词项的文档列表(Postings List)的映射。Postings List 通常还包含词频、位置信息(用于短语查询)等元数据。
-
词项字典 (Term Dictionary): 包含索引中所有唯一词项的排序列表。这通常使用高效的数据结构(如 FST - Finite State Transducer)实现,以支持快速查找。
-
文档值 (Doc Values): 这是 Lucene 为加速聚合、排序和脚本访问而构建的列式存储结构。它将每个字段的所有值按文档 ID 顺序存储在一起(想象成数据库表的一列)。这与倒排索引的“行式”(按词项组织)形成互补。ES 的聚合性能严重依赖 Doc Values。
-
存储字段 (Stored Fields): 原始文档内容本身,按文档存储。当你需要检索整个文档或特定存储字段(如标题、摘要)时使用。注意:默认情况下,ES 的
_source字段就是整个原始 JSON 文档的存储字段。 -
点数据 (Points): 专门用于高效存储和查询数值类型(整数、浮点数)和地理点(经纬度)数据。支持快速的范围查询(如
price:[10 TO 100])、距离查询等。 -
段 (Segments): Lucene 索引在物理上是由一个或多个不可变的段组成的。每次提交(Commit)或刷新(Refresh)操作都可能创建一个新段。搜索需要查询所有段。后台有一个合并(Merge)过程将小段合并成大段,优化性能和减少文件句柄占用。ES 的
refresh_interval控制新数据对搜索可见的速度,本质上就是控制新段创建的频率。
Lucene 的处理流程(与 ES 协作)写入(索引文档)
-
ES 接收文档(通常是 JSON)。
-
ES 根据 Mapping 定义进行分词(使用指定的分析器 Analyzer,包含Tokenizer和TokenFilter)。分词器是 Lucene 的核心组件之一!
-
处理后的词项(Tokens)被传递给 Lucene。
-
Lucene 将文档添加到内存缓冲区,构建倒排索引结构(词项->文档映射)、Doc Values、存储字段等。
-
当满足条件(如 refresh 间隔、缓冲区满)时,Lucene 将内存中的数据刷新(Refresh) 到一个新的、可搜索的段(Segment)中(写入文件系统缓存,稍后由 OS 刷盘)。此时新数据对搜索可见。
-
定期或满足条件时,Lucene 执行提交(Commit),确保所有数据安全持久化到磁盘(调用
fsync)。 -
后台的段合并(Merge) 过程持续运行,将小的、可能被删除文档标记的段合并成更大的、更优的段。
Lucene 的处理流程(与 ES 协作)查询(索引文档)
-
ES 接收查询请求(如 Match Query, Term Query, Range Query)。
-
ES 将查询解析并转换成适合底层 Lucene 索引结构的查询类型。
-
ES 确定需要查询哪些分片(Shard),并将请求路由到持有这些分片的节点。
-
在每个分片上(即每个独立的 Lucene 索引上):
Lucene执行逻辑
-
ES 协调节点收集来自各个分片的结果,进行合并、排序(根据得分或其他字段)、分页等操作。
-
ES 如果需要获取文档内容(如 _source 或特定存储字段),会再向相关分片请求存储字段。
-
ES 将最终结果组装返回给客户端
简单来说:Elasticsearch 让你能够轻松地管理和查询分布在多台机器上的海量数据,而 Lucene 则确保在每一台机器上、每一个数据分片内部,数据的存储和检索都达到了极致的高效和强大。 理解 ES 的分词和倒排索引是基础,而理解 Lucene 则是深入理解 ES 内部运作机制的关键一步。
运维小路
一个不会开发的运维!一个要学开发的运维!一个学不会开发的运维!欢迎大家骚扰的运维!
关注微信公众号《运维小路》获取更多内容。