本文將從資料儲存和搜尋的角度簡單分析Elasticsearch的搜尋執行機制,主要涉及搜尋API、搜尋機制、存在問題和解決方案。
4.1 Search API
Search API允許使用者執行一個搜尋查詢並返回匹配查詢的搜尋命中結果。
Elasticsearch查詢主要有兩種方式:URI Search
和Request 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;當資料量足夠大的時候,只要保證文件均勻分佈在各個分片上面,結果一般不會出現偏差
- 使用
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的分片儲存決定了搜尋機制。其實儲存和搜尋不能分割開來看,只儲存不可搜尋,這個儲存是沒有意義的;只搜尋沒有儲存(資料來源)是空中樓閣。