Elasticsearch深度分頁問題以及Scroll查詢的一些總結

背景介紹

我們在 Elasticsearch API的基礎上實現了一個日誌查詢系統,支持最基本的時間範圍選擇以及關鍵詞搜索高亮,並且日誌展示的表格支持異步分頁。

有天用戶反饋,查詢的時候頁面報錯

Result window is too large, from + size must be less than or equal to: [10000] but was [24600]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting.

這是因爲我們的異步分頁查詢邏輯中使用了 from + size,而 Elasticsearch 默認配置爲

“max_result_window”: “10000”

於是, 將這個參數調至 30000, 問題暫時解決。

不過,今天又接到反饋,API報錯

Result window is too large, from + size must be less than or equal to: [30000] but was [44600]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting.

一味調整 max_result_window 不是個辦法,遂計劃詳細瞭解下 window 查詢的邏輯,以及 max_result_window 這個參數存在的意義。

Elasticsearch Search 搜索

我們的查詢DSL大致如下:

{
    "from": m,
    "size": n,
    "sort": [{"l": "asc"}, {"line": "asc"}],
    "query": {}
}

ES的 Search 搜索是分兩個階段進行的,即Query和Fetch階段。

Query 階段

  1. 每個 Shard 通過查詢倒排索引,獲取滿足查詢結果的有序文檔ID優先隊列,隊列長度爲 from + size
  2. 每個 Shard 返回有序文檔列表發送給協調節點,協調節點把所有 Shard 的結果合併產生一個全局排序後的優先隊列,隊列長度爲 from + size

Fetch 階段

  1. 根據 Query 階段返回的結果隊列決定哪些文檔需要被取回,在長度爲 from + size 的隊列中,前from個文檔會被丟棄,只有最後size個文檔需要被取回,而這些文檔可能來自於一個或者多個分片
  2. 協調節點給相關文檔的分片創建一個 Multi Get 請求,一旦所有文檔被取回,協調節點返回結果給客戶端。

max_result_window 參數的意義

在 Query 階段中,協調節點需要在長度爲 number_of_shard * (from + size) 的排序文檔中,找到包含在 size 中的文檔。

這個性能,取決於文檔大小/分片個數以及硬件性能等,當 from 值足夠大時,這個過程會變得沉重,消耗大量的資源,這也是 Elasticsearch 不推薦使用深度分頁以及 max_result_window存在的意義。

Elasticsearch Scroll 搜索

在瞭解深度分頁的過程中,看見推薦使用 Scroll 完成深度分頁,於是同時瞭解了一下 Scroll 查詢

Scrolling is not intended for real time user requests, but rather for processing large amounts of data, e.g. in order to reindex the contents of one index into a new index with a different configuration.

首先,Scroll 並不適合用來做實時搜索,更適用於大規模數據處理,例如 reindex

Scroll 的使用也分爲兩個階段,初始化和遍歷。

初始化時將所有符合搜索條件的搜索結果文檔ID緩存起來, 形成快照,遍歷時直接從快照取數據。

初始化會返回一個 scroll_id,每次遍歷時都帶上這個id,重複遍歷知道返回的數據爲空,刪除快照。

總結:

Search 相比將Query階段的隊列緩存起來,多次查詢時減少 Query階段的操作,以提高性能?(待繼續驗證)

Reference

  1. 使用scroll實現Elasticsearch數據遍歷和深度分頁
  2. Elasticsearch 5.x from size, scroll 和 search after
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章