当前位置: 首页 > news >正文

Lucene与Elasticsearch如何具体协作?

Lucene 和 Elasticsearch (ES) 的关系可以比喻为 “引擎”与“整车”,或者 “内核”与“操作系统” 的关系。

  • Lucene:是一个 Java 库,负责最核心的索引构建文本分析搜索执行。它不知道什么是“集群”、“节点”、“REST API”或“JSON”。
  • Elasticsearch:是一个分布式系统,基于 Lucene 构建。它负责数据分布集群管理API 暴露容错处理以及业务逻辑封装,然后调用 Lucene 来完成实际的读写操作。

以下是它们在实际运行中具体协作的深层机制:


1. 架构层级关系

层级 组件 职责 依赖关系
应用层 Kibana / Logstash / 客户端 发送 JSON 请求,展示结果 依赖 ES REST API
服务层 Elasticsearch 接收请求、路由、权限控制、聚合结果、集群状态管理 依赖 Lucene 库
内核层 Apache Lucene 创建倒排索引、执行查询、计算评分、管理 Segment 纯 Java 库,无网络能力
存储层 文件系统 (OS) 存储 .cfs, .doc, .tim 等物理文件 被 Lucene 调用

关键点:在 ES 的代码中,你找不到“如何构建倒排索引”的代码,这部分完全委托给了 org.apache.lucene 包。ES 只负责决定“什么时候”、“在哪个节点”、“对哪些数据”调用 Lucene。


2. 写入流程中的协作 (Indexing)

当客户端向 ES 发送一条文档写入请求时,协作过程如下:

第一步:ES 的预处理 (Routing & Parsing)

  1. 协调节点 (Coordinating Node) 接收请求,解析 JSON。
  2. 路由计算:根据 _idrouting 值,计算该文档属于哪个 分片 (Shard)
  3. 转发:将请求转发给持有该主分片的 数据节点 (Data Node)

第二步:ES 调用 Lucene 进行索引 (The Handoff)

在数据节点上,ES 的 IndexShard 类开始工作:

  1. 分析器 (Analyzer):ES 配置好 Analyzer(如 standard, ik_max_word),调用 Lucene 的 Analyzer 接口,将文本字段拆解为 Token Stream (词项流)。
  2. 构建 Document:ES 将处理后的字段组装成 Lucene 的 Document 对象。
    • ES 的 Field 映射到 Lucene 的 Field (如 TextField, KeywordField, DocValuesField)。
    • ES 自动添加隐藏字段(如 _source, _id, _version)到 Lucene Document 中。
  3. 调用 IndexWriter:ES 获取该分片对应的 Lucene IndexWriter 实例,调用 indexWriter.addDocument(doc)
    • 此时,Lucene 接管:它将数据写入内存缓冲 (RAMBuffer),生成临时的 Segment 信息。

第三步:Refresh 与 Commit

  1. Refresh (默认 1s):ES 定时调用 indexWriter.commit() (实际上是 NRT 的 reopen)。
    • Lucene 将内存中的数据刷新为一个新的 Segment,并打开供搜索。
    • ES 更新其内部的 IndexReader 引用,使新数据对查询可见。
  2. Flush (默认 30min 或内存满):ES 调用 indexWriter.commit() 强制落盘。
    • Lucene 将 Segment 文件真正写入磁盘,并生成 segments_N 文件。
    • ES 同时更新 Translog (这是 ES 自己的机制,Lucene 没有),用于故障恢复。

查询是 ES 与 Lucene 协作最复杂的部分,涉及 Scatter-Gather (散播 - 聚集) 模式。

第一步:ES 的散播 (Scatter)

  1. 协调节点 解析查询 DSL (Domain Specific Language)。
  2. 重写查询:ES 将 DSL 转换为 Lucene 的 Query 对象树 (如 BooleanQuery 包含多个 TermQuery)。
  3. 路由:确定需要查询哪些分片(通常是所有相关分片)。
  4. 并发请求:协调节点向各个持有分片的节点发送子查询请求。

第二步:分片节点的本地执行 (Lucene in Action)

在持有分片的节点上:

  1. 获取 Reader:ES 获取该分片最新的 IndexReader (Lucene 对象)。
  2. 调用 Searcher:ES 创建 IndexSearcher (Lucene 核心类),调用 searcher.search(query, topN)
  3. Lucene 执行
    • 遍历倒排索引:Lucene 利用 FST 找到 Term,读取 Posting List。
    • 评分:Lucene 使用 BM25 算法计算每个文档的得分。
    • 收集器 (Collector):Lucene 在本地维护一个优先队列,只保留该分片内得分最高的 Top-N 文档。
    • 返回结果:Lucene 返回 TopDocs 对象(包含 DocID 和 Score,注意:此时还没有原始数据)。

第三步:ES 的聚集 (Gather)

  1. 协调节点 收集所有分片返回的 TopDocs
  2. 全局排序:ES 在内存中对所有分片的结果进行合并、排序,计算出全局的 Top-N。
  3. Fetch 阶段
    • ES 根据全局 Top-N 的 DocID,再次向对应分片请求原始数据 (_source)。
    • 分片节点调用 Lucene 的 DocumentStoredFieldVisitor_source 字段(存储在 Lucene 的 StoredFields 中)读取原始 JSON。
  4. 最终响应:ES 将结果组装成 JSON 返回给客户端。

关键协作点:Lucene 只负责“找到 DocID 并打分”,ES 负责“跨分片排序”和“取回原始数据”。


4. 高级功能的协作细节

A. 聚合 (Aggregations)

  • ES 的角色:解析聚合 DSL,构建聚合树,处理跨分片的 Bucket 合并。
  • Lucene 的角色:提供 Doc Values
    • 当 ES 需要按某个字段分组或求平均时,它不会去扫描倒排索引或 _source
    • ES 直接调用 Lucene 的 SortedNumericDocValuesBytesDocValues 接口。
    • Lucene 以列式存储的方式快速迭代该字段在所有文档中的值,极大提升速度。

B. 分片合并 (Segment Merge)

  • ES 的角色:通过 MergeScheduler 决定何时触发合并(基于 TieredMergePolicy),并在后台线程池中运行。
  • Lucene 的角色:执行实际的 I/O 操作。
    • 读取多个小 Segment 的文档。
    • 剔除已标记删除的文档。
    • 重新压缩写入一个新的大 Segment。
    • ES 负责在合并完成后更新引用,并删除旧的物理文件。

C. 向量搜索 (KNN)

  • ES 的角色:管理向量字段映射 (dense_vector),处理 HNSW 图的构建参数。
  • Lucene 的角色:(Lucene 9+) 提供 HnswGraphSearcher
    • Lucene 在内存中维护 HNSW 图结构。
    • 执行近似最近邻搜索,返回向量距离最近的 DocID。

5. 为什么 ES 不直接用 Lucene 而要封装一层?

如果直接使用 Lucene,你只能得到单机、单文件、无网络能力的库。ES 的封装解决了以下 Lucene 不做 的事情:

  1. 分布式:Lucene 不懂网络。ES 实现了分片路由、副本同步、节点发现。
  2. 高可用:Lucene 文件坏了就是坏了。ES 实现了副本故障转移、数据重平衡。
  3. 易用性:Lucene 是复杂的 Java API。ES 提供了 RESTful JSON API 和强大的 DSL。
  4. 生命周期管理:Lucene 不会自动删除旧数据。ES 提供了 ILM。
  5. 安全性:Lucene 没有用户权限概念。ES 提供了 RBAC、SSL/TLS。
  6. 监控与管理:ES 提供了 _cat, _stats, _cluster/health 等监控接口,这些都是包裹在 Lucene 统计信息之外的元数据。

总结图示

[Client] | (JSON Request)v
[Elasticsearch Coordinating Node]|-- 1. 解析 DSL -> 转为 Lucene Query 对象|-- 2. 路由 -> 确定目标 Shards|-- 3. 散播请求 -> [Data Node A], [Data Node B]...[Data Node (Per Shard)]|-- 4. 获取 Lucene IndexReader|-- 5. 调用 Lucene IndexSearcher.search(Query)|      |-- [Lucene Kernel]|           |-- 查 FST -> 找 Term|           |-- 读 Posting List -> 得 DocIDs|           |-- 算 BM25 Score|           |-- 读 Doc Values (聚合用)|           `-- 返回 TopDocs (DocID + Score)||-- 6. 返回局部结果给 Coordinating Node[Elasticsearch Coordinating Node]|-- 7. 合并所有局部结果 (Global Sort)|-- 8. Fetch Phase: 请求原始 _source (再次调用 Lucene 读取 StoredFields)|-- 9. 组装 JSON 响应|v
[Client]

一句话总结Elasticsearch 是指挥官和后勤部长,负责调度、分发和整合;Lucene 是前线特种兵,负责在微观层面以极致的效率完成具体的“查找”和“计算”任务。

http://www.jsqmd.com/news/444369/

相关文章:

  • 文明6mod制作(2) - 详解
  • 详细介绍:深入剖析云原生Service Mesh数据平面Envoy核心架构:基于xDS协议与WebAssembly实现动态流量管理与安全策略的微服务治理实战指南
  • 天虹提货券回收技巧,解锁闲置资源新价值 - 京顺回收
  • 孢子 SPORE Collection v.3.1.0.22_(10834)
  • kotlin基础(2)
  • Java变量常量
  • ESP32开发环境搭建(全流程)
  • 2026最新整理:十大设计师素材网站推荐,满足美工及运营设计全场景需求 - 品牌2026
  • Lucene 核心原理
  • 告别侵权风险!2026年十大免费高清图片素材网站推荐,设计师、美工必看合集 - 品牌2026
  • 2026年视频素材数据集及AI训练素材供应商推荐:卓特视觉专业数据集供应商深度评测 - 品牌2026
  • 2026年热门行业图片素材网站推荐:网络通信、物流、印刷、跨境电商、快消品、旅游及服装印花图案设计 - 品牌2026
  • 2026年度十大高清壁纸图片及视频素材网站推荐:精选可商用正版资源 - 品牌2026
  • 2026年度十大免费高清图片素材网站推荐:可下载正版版权库盘点,告别侵权焦虑 - 品牌2026
  • 2026年AI训练数据集、图片及视频素材供应商精选评测卓特视觉全方位解析 - 品牌2026
  • 【原创控件】PopupMenu和MainMenu自绘单元
  • 2026免费图片素材下载网站推荐:十大高清图库宝藏大全,涵盖版权图片与商用图库 - 品牌2026
  • 2026更新!十大免费高清图片素材网站推荐:设计师美工必知的版权网站大全 - 品牌2026
  • 深入解析:计算机视觉——Opencv(模板匹配)
  • 无线VR串流革命:ALVR技能深度解析与实践指南
  • Elasticsearch 索引生命周期管理ILM
  • OpenClaw 装机 1000 元?深度拆解代装产业链:谁在赚钱,谁在裸奔
  • UE5.7.3 AudioCapture
  • Elasticsearch:如何根据场景合理调整分片数量?
  • 装完 OpenClaw 之后,我把它变成了办公助手——一个月真实体验
  • 【工具推荐】WinRAR官网下载:2026最新WinRAR免费版安装图解教程 - xiema
  • 基于YOLO+DeepSeek+智能垃圾分类系统 Pytorch+SpringBoot+Flask+Vue 毕业设计的不同选题方向
  • 如何根据场景合理调整分片数量?
  • 如何在国内合规、稳定地使用GPT/Claude/Gemini API?中转服务全解析 - 实践
  • 三星Galaxy Book 6 Pro,平价高性能之选?