Elasticsearch核心技術(五):搜尋API和搜尋執行機制

James_Shangguan發表於2021-12-28

本文將從資料儲存和搜尋的角度簡單分析Elasticsearch的搜尋執行機制,主要涉及搜尋API、搜尋機制、存在問題和解決方案。

4.1 Search API

Search API允許使用者執行一個搜尋查詢並返回匹配查詢的搜尋命中結果。

Elasticsearch查詢主要有兩種方式:URI SearchRequest Body Search

  • URI Search:通過URI引數實現搜尋,特點是操作簡便,僅包含部分查詢語法,常用引數如下:
    q:指定查詢語句,使用Query String Syntax
    df:預設欄位,不指定時,會對所有欄位進行查詢
    sort:排序
    profile:用於檢視查詢是如何被執行的

  • Request Body Search:完備的查詢語法Query DSL,所以還是建議使用Request Body Search。

4.2 深入瞭解Search執行機制

建議先參考上篇Elasticsearch核心技術(四):分散式儲存架構與索引原理分析,其中主要介紹了ES的分散式儲存架構和原理。

4.2.1 Query-then-Fetch執行機制

Elasticsearch的分散式搜尋的執行機制稱為Query-then-Fetch。具體分為Query和Fetch兩個階段:

Query階段

使用者發出搜尋請求到達ES節點。節點收到請求後,會以協調節點(Coordinating Node)的身份,在6個主副分片中隨機選擇3個分片,傳送查詢請求。

被選中的節點,進行排序(根據score值進行排序)。然後每個分片都返回 From+size 個排序後的文件id和排序值給協調節點。 注意這裡返回的是文件id。

Fetch階段

Coordinating節點將Query階段從每個分片獲取的排序的文件id列表重新進行排序,選取 From 到 From+size 個文件的id。

multi get請求的方式,到相應的分片獲取詳細的文件資料。

4.2.2 為什麼需要兩階段才能完成搜尋

因為Elasticsearch在查詢的時候不知道文件位於哪個分片,因此索引的所有分片都要參與搜尋,然後協調節點將結果合併,在根據文件ID獲取文件內容。例如現在有5個分片,需要查詢匹配度Top10的資料,那麼每個分片都要查詢出當前分片的Top10的資料,協調節點將5×10個結果再次進行排序,返回Top10的結果給客戶端。

4.2.3 Query-then-Fetch存在問題和解決方案

Query-then-Fetch存在問題分為兩方面,一個是效能問題,一個是相關性算分問題。

  • 效能問題

效能問題主要表現為深度分頁的問題。Elasticsearch資料是分片儲存的,資料分佈在多臺機器上。有這樣一個場景,如何獲取前1000個文件?當獲取從990-1000的文件時候,會在每個分片上面都先獲取1000個文件,然後再由協調節點聚合所有分片的結果在排序選取前1000個文件。

這個過程有什麼問題嗎?當然是有的,頁數越深,處理文件越多,佔用記憶體越多,耗時越長。所以要儘量避免深度分頁。當然,ES官方也注意了這個問題,所以通過index.max_result_window限定最多到10000條資料。當然我們也可以根據業務需要修改這個引數,這也解釋了:為什麼Google搜尋結果只有相關度最高的17頁結果,百度只有76頁的結果,原因之一是受限於Elasticsearch深度分頁的效能問題。

  • 相關性算分問題
    另外一個問題是相關性算分不準確問題。每個分片都基於自己分片上面的資料進行相關度計算。這會導致打分偏離的情況,特別是資料量很少的時候。相關性算分在分片之間是相互獨立。當文件總數很少的情況下,如果主分片大於1,如果主分片數越多,相關性算分會越不準。

  • 如何解決算分不準的問題?

  1. 當資料量不大的時候,將主分片數設定為1;當資料量足夠大的時候,只要保證文件均勻分佈在各個分片上面,結果一般不會出現偏差
  2. 使用DFS Query Then Fetch
    在搜尋的URL中指定引數 _search?search_type=dfs_query_then_fetch ;這樣就可以保證每個分片把各個分片的詞頻和文件頻率進行蒐集,然後進行一次相關性算分。但是這樣會耗費更多的CPU和記憶體資源,執行效能較低。
  • 如何避免深度分頁的問題?

使用Search_After
ES提供實時的下一頁文件獲取功能,這個功能只能下一頁,不能上一頁;
不能指定頁數,不能使用from引數;

  • 三種分頁方式對比:
型別 場景
From/Size 需要實時獲取頂部的部分文件,且需要自由翻頁
Scroll 需要全部文件,如匯出所有資料的功能
Search_After 需要全部文件,不需要自由翻頁

4.3 總結

經濟基礎決定上層建築,ES的分片儲存決定了搜尋機制。其實儲存和搜尋不能分割開來看,只儲存不可搜尋,這個儲存是沒有意義的;只搜尋沒有儲存(資料來源)是空中樓閣。

相關文章