找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1890

积分

0

好友

270

主题
发表于 2025-12-31 08:05:38 | 查看: 20| 回复: 0

Elasticsearch的搜索过程可以清晰地划分为“查询阶段”和“取回阶段”两个核心步骤,整个过程由协调节点来统筹管理。

图:Elasticsearch搜索过程(查询与取回两阶段)流程图

第一阶段:查询阶段

这个阶段的目标是快速定位到满足条件的文档ID和排序分值(_score),但并不获取完整的文档内容。这一设计极大地优化了初期处理效率。

  • 客户端请求:客户端将搜索请求发送到协调节点。
  • 查询广播:协调节点将搜索请求并行转发给索引中所有相关的分片。这里的“相关分片”包括主分片及其副本分片,具体选择由路由和负载均衡策略决定。
  • 分片本地查询
    • 每个分片在本地独立执行查询。
    • 这个过程包括解析查询语句、使用倒排索引查找匹配文档、计算相关度评分以及应用过滤器。
    • 每个分片会从自己的结果中,仅选出排名最高的前 N 个文档(N = from + size),将它们的文档ID和评分构建成一个优先级队列,然后返回给协调节点。
  • 关键点:此时返回的只有元数据,没有完整的 _source 字段,这显著减少了网络传输的数据量。

第二阶段:取回阶段

在查询阶段确定了“哪些文档”后,此阶段的目标就是获取这些文档的完整内容。

  • 结果合并与排序:协调节点收到所有分片返回的列表后,会进行全局合并与排序,筛选出最终的全局前 N 名文档。
  • 发起取回请求:协调节点根据全局排序结果,向这些文档实际所在的分片(而非所有分片)发起多文档获取请求。
  • 返回完整文档:相关分片根据文档ID从本地检索出完整的文档数据并返回。
  • 组装并响应:协调节点收集所有返回的完整文档,组装成最终的搜索结果列表返回给客户端。这种将查找与获取分离的分布式系统设计,是保证其高性能的关键之一。

重要特性与优化点

理解以下特性,能在技术讨论或面试中展现出更深入的洞察。

近实时搜索
文档被索引后,需要经过一个刷新操作(默认1秒一次)才会创建一个新的可搜索段,之后才能被搜索到。这就是“近实时”的含义,也意味着新写入的数据约有1秒的延迟才能被搜到。

深分页问题
当进行深度分页时,每个分片需要在本地准备大量结果,协调节点则需要合并海量数据,消耗巨大。解决方案包括:

  • 业务上避免,或使用滚动搜索(适合数据导出)。
  • 使用 Search After 参数进行游标查询(适合实时深分页)。
  • 通过 index.max_result_window 参数限制最大分页深度(默认10000)。

自适应副本选择
在较新版本中,协调节点会根据副本节点的响应时间和负载等情况,智能选择更快的副本分片来执行查询,从而优化查询延迟,而非简单轮询。

DFS Query Then Fetch
在评分精度要求极高的场景下,可以先执行一个预查询来获取全局的词频信息,以确保评分的绝对准确。但这会带来较大的性能开销,通常只在特定需求下使用。

面试回答精简要点

你可以这样概括:“Elasticsearch的搜索主要分为查询和取回两个阶段。查询阶段协调节点将请求广播到各分片,分片本地执行后仅返回文档ID和评分;取回阶段协调节点合并结果,再向目标分片获取完整文档内容。这种两阶段设计减少了不必要的数据传输,提升了效率,但同时也带来了近实时性和深分页的挑战。”




上一篇:Go语言能否成为未来主流?从三大技术趋势深度分析
下一篇:Oracle RAS 实战指南:解决连接池下的数据库用户身份与权限管控难题 (12c+)
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-9 17:47 , Processed in 0.184738 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表