Elasticsearch搜索過程詳解

前言

說明:本文章使用的ES版本是:6.7.0git

在上一篇文章Elasticsearch如何建立索引?中,介紹了ES寫入文檔的過程。github

接下來咱們具體的看一下ES中,搜索過程是怎樣的算法

在ES中搜索

按照前面幾篇文章的步驟,咱們直接開始debug搜索的過程。上一篇文章中咱們寫入了以下的數據json

{
    "id":6,
    "title": "我是文件標題,可被搜索到66",
    "text":  "文本內容,ES時如何索引一個文檔的66",
    "date":  "2014/01/06"
}'

如今執行以下請求,對ES服務器發起搜索請求:緩存

curl -X GET 'localhost:9200/index_name/type_name/_search?pretty&q=title:66' -H 'Content-Type: application/json'

搜索能夠接收下面的形式的請求:服務器

clipboard.png

客戶端

  1. 根據路由,RestSearchAction接收並開始處理請求
  2. RestSearchAction解析並驗證搜索參數,並將其封裝成SearchRequest,並指定服務端要處理該請求的Action:indices:data/read/search

服務端(master節點)

  1. 根據SearchRequest的index構造相應的ShardsIterator(分片迭代器),shardIterators由localShardsIterator(當前節點分片迭代器(默認一個節點上,一個索引有5個分片))和remoteShardIterators(其餘節點分片迭代器)合併而成,根據搜索條件,構建搜索策略。而後遍歷全部的shard。併發

    • 搜索策略app

      • 最多遍歷分片數量LONG最大值2^63-1
      • 若是隻有一個分片,搜索類型只能是:QUERY_THEN_FETCH
      • 是否查詢緩存
      • 遍歷分片的最大併發數Math.min(256, Math.max(節點數, 1)*節點分片數),節點默認分片數:5
  2. 構造異步請求Action,將請求轉發到各個節點,等待回調
  3. 遍歷全部節點,構造節點查詢參數ShardSearchTransportRequest對象,對每一個節點執行查詢操做 clipboard.png
  4. 執行查詢階段,首先在cache裏面判斷是否有緩存,若是有則執行緩存查詢;若是cache裏面沒有,執行QueryPhase類的execute()方法,他調用lucene的searcher.search對索引進行查詢,查詢成功回調onShardResult方法並返回docIds,查詢失敗回調onShardFailure(計數失敗狀況,並嘗試在副本分片上進行查詢)
  5. 查詢階段會計算文檔的相關性得分用於排序: clipboard.png
  6. Fetch階段:master接收到各個節點返回的docIds後,發起數據Fetch請求,經過docId和其分片ID到對應分片抓取數據,後合併數據返回給客戶端

大體的查詢時序邏輯:
clipboard.pngcurl

搜索總結

  1. Query階段能夠知道,一個搜索會遍歷這個索引下的全部分片,每一個分片都會執行一次搜索,並返回相同數量的文檔ID。好比搜索條件要查詢5條數據,有5個分片,則最終會查詢25條數據,排序後取前面5條數據
  2. 查詢和計算權重得分在Lucene完成,聚合是在ES中實現的
  3. 搜索會遍歷全部的分片,因此分片的數量影響着搜索的性能,而分片的數量也決定了ES能承載的最大數據量。因此在具體的應用中,須要在兩者之間選擇平衡
  4. 計算文檔權重得分,每搜索一次,都會根據搜索條件從新計算一次,對搜索性能影響很大

系列文章

  1. 搜索引擎ElasticSearch源碼編譯和Debug環境搭建
  2. 搜索引擎ElasticSearch的啓動過程
  3. Elasticsearch建立索引流程
  4. Elasticsearch搜索過程詳解
  5. Elasticsearch搜索相關性排序算法詳解
  6. Elasticsearch中的倒排索引
相關文章
相關標籤/搜索