Elasticsearch核心技術(五):搜索API和搜索運行機制
- 2021 年 12 月 28 日
- 筆記
- Elasticsearch核心技術
本文將從數據存儲和搜索的角度簡單分析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的分片存儲決定了搜索機制。其實存儲和搜索不能分割開來看,只存儲不可搜索,這個存儲是沒有意義的;只搜索沒有存儲(數據源)是空中樓閣。