[Mark]解決ElasticSearch深度分頁機制中Result window is too large問題

Mr-Wanter發表於2018-05-24

問題描述

今天在使用ElacticSearch做分頁查詢的時候,遇到一個奇怪的問題,分頁獲取前9999條資料的時候都是正常的,但每次獲取第10000條資料的時候就無法獲取到結果。檢查自己程式碼中的分頁邏輯也未發現什麼問題,於是進行單步除錯,當單步獲取第10000條資料的時候捕捉到了下面的異常:

Failed to execute phase [query_fetch], all shards failed; shardFailures {[1w_m0BF0Sbir4I0hRWAmDA][fuxi_user_feature-2018.01.09][0]: RemoteTransportException[[10.1.113.169][10.1.113.169:9300][indices:data/read/search[phase/query+fetch]]]; nested: QueryPhaseExecutionException[Result window is too large, from + size must be less than or equal to: [10000] but was [10100]. 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 parameter.]; }

解決方案

最後通過查閱瞭解到出現這個問題是由於ElasticSearch的預設 深度翻頁 機制的限制造成的。ES預設的分頁機制一個不足的地方是,比如有5010條資料,當你僅想取第5000到5010條資料的時候,ES也會將前5000條資料載入到記憶體當中,所以ES為了避免使用者的過大分頁請求造成ES服務所在機器記憶體溢位,預設對深度分頁的條數進行了限制,預設的最大條數是10000條,這是正是問題描述中當獲取第10000條資料的時候報Result window is too large異常的原因。

要解決這個問題,可以使用下面的方式來改變ES預設深度分頁的index.max_result_window 最大視窗值

curl -XPUT http://127.0.0.1:9200/my_index/_settings -d '{ "index" : { "max_result_window" : 500000}}'
  • 1

其中my_index為要修改的index名,500000為要調整的新的視窗數。將該視窗調整後,便可以解決無法獲取到10000條後資料的問題。

注意事項

通過上述的方式解決了我們的問題,但也引入了另一個需要我們注意的問題,視窗值調大了後,雖然請求到分頁的資料條數更多了,但它是用犧牲更多的伺服器的記憶體、CPU資源來換取的。要考慮業務場景中過大的分頁請求,是否會造成叢集服務的OutOfMemory問題。在ES的官方文件中對深度分頁也做了討論

https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html

https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html

核心的觀點如下:

Depending on the size of your documents, the number of shards, and the hardware you are using, paging 10,000 to 50,000 results (1,000 to 5,000 pages) deep should be perfectly doable. But with big-enough from values, the sorting process can become very heavy indeed, using vast amounts of CPU, memory, and bandwidth. For this reason, we strongly advise against deep paging.

這段觀點表述的意思是:根據文件的大小,分片的數量以及使用的硬體,分頁10,000到50,000個結果(1,000到5,000頁)應該是完全可行的。 但是,從價值觀上來看,使用大量的CPU,記憶體和頻寬,分類過程確實會變得非常重要。 為此,我們強烈建議不要進行深度分頁

自己的看法是,ES作為一個搜尋引擎,更適合的場景是使用它進行搜尋,而不是大規模的結果遍歷。 大部分場景下,沒有必要得到超過10000個結果專案, 例如,只返回前1000個結果。如果的確需要大量資料的遍歷展示,考慮是否可以用其他更合適的儲存。或者根據業務場景看能否用ElasticSearch的 滾動API (類似於迭代器,但有時間視窗概念)來替代。

原文地址:https://blog.csdn.net/lisongjia123/article/details/79041402


相關文章