Elasticsearch核心技術與實戰學習筆記 41 | 剖析分佈式查詢及相關性算分

一 序

    本文屬於極客時間Elasticsearch核心技術與實戰學習筆記系列。

二 分佈式搜索的運行機制

  • ES 的搜索,會分兩階段進行
    • 第一階段 - QUERY
    • 第二階段 - Fetch
  • Query - then - Fetch

2.1 Query 階段

    用戶發出搜索請求到 ES 節點。節點收到請求後,會以 Coordinating 節點的身份,在 6 個主副分片中隨機選擇 3 個分片,發送查詢請求
被選中的分片執行查詢,進行排序。然後,每個分片都會返回 From + Size 個排序後的文檔 Id 和排序值給 Coordinating 節點

   

2.2 Fetch 階段

Coordinating Node 會將 Query 階段,從每個分片獲取的排序後的文檔 Id 列表,重新進行排序。選取 From 到 From + Size 個文檔的 Id
以 multi get 請求的方式,到相應的分片獲取詳細的文檔數據。   

2.3 Query Then Fetch 潛在的問題

 性能問題

  • 每個分片上需要查的文檔個數 = from + size
  • 最終協調節點需要處理:number_of_shard * (from + size)
  • 深度分頁

相關性算分

  • 每個分片都基於自己的分片上的數據進行相關度計算。這會導致打分偏離的情況,特別是數據量很少時,如果文檔總數很少的情況下,如果主分片大於 1,主分片越多,相關性算分會越不準。

2.4 解決算分不準的方法

 數據量不大的時候,可以將主分片數設置爲 1
當數據量足夠大時候,只要保證文檔均勻分散在各個分片上,結果一般就不會出現偏差
使用 DFS Query Then Fetch
搜索的 URL 中指定參數 “_search?search_type=dfs_query_then_fetch”
到每個分片把各分片的詞頻和文檔頻率進行蒐集,然後完整的進行一次相關性算分,消耗更加多的 CPU 和內存,執行性能低下,一般不建議使用

 

3. demo:

數據準備:

DELETE message

POST message/_doc?routing=1
{
  "content":"good"
}

POST message/_doc?routing=2
{
  "content":"good morning"
}

POST message/_doc?routing=3
{
  "content":"good morning everyone"
}
POST message/_search
{
  "query": {
    "term": {
      "content": {
        "value": "good"
      }
    }
  }
}

使用es7  默認1 個主分片測試,不存在分佈式查詢算分不準的情況,Good 應該排在第一 

 

改爲20分片:打分是一樣的。

如果使用explain查看,會發現文檔分散到不同的shard上,所以分數一樣。

如果執行 DFS Query Then Fetch ,結果和一個分片上一致

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章