Elasticsearch 分頁

1.傳統分頁(from&size)

按照一般的查詢流程來說,如果我們想查詢前10條數據:

  1. 客戶端請求發送給某個節點;
  2. 節點轉發給各個分片,查詢每個分片上的前10條數據;
  3. 查詢結果返回給節點,並將數據進行整合,提取前10條數據;
  4. 將查詢結果返回給客戶端。

其原理就是當我們需要查詢第10條到第20條數據時,節點從各個分片上獲取10條數據並進行數據整合,然後從整合的數據中獲取第10條到第20條數據作爲請求的結果。
在這裏插入圖片描述
其中from定義了目標數據的偏移值,size定義了當前返回的事件數目。默認from爲0,size爲10,即所有的查詢默認返回前10條數據。

在實際測試過程中,當此方式的訪問頁碼越高,其執行的查詢效率就越低。假設我們現在需要獲取第20頁的數據,ElasticSearch不得不取出所有分片上的第1頁到第20頁的所有文檔,並對其進行合併排序,最終再取出from後的size條作爲最終的返回結果;假設我們現在服務器上有16個分片,則我們需要彙總到shards*(from+size)條記錄,即需要16*(20+10)條記錄後,對其進行整合再做一次全局排序。

因此,當索引非常大時,我們是無法使用from+size方式做深分頁的,分頁越深越容易OOM或者消耗內存,所以ES使用index.max_result_window:10000作爲保護措施來避免這種情況的發生。但實際上當訪問數據非常大時,我們採用scroll遊標的方式來獲取數據是更好地一種選擇。

2. 大數據量的快照分頁(scroll)

相對於from&size的分頁來說,使用scroll可以模擬一個傳統的遊標來記錄當前讀取的文檔信息位置。採用此分頁方法,不是爲了實時查詢數據,而是爲了查詢大量甚至全部的數據。此方式相對於維護了一份當前索引的快照信息,在執行數據查詢時,scroll將會從這個快照信息中獲取數據。它相對於傳統的分頁方式來說,不是查詢所有數據再剔除掉不需要的部分,而是記錄一個讀取的位置來保證下次對數據的繼續獲取

訪問數據過程
在使用scroll方式進行數據請求的過程中,主要分爲四步:

  1. 首先通過設置訪問地址和端口號等信息獲取到客戶端對象;
  2. 設置請求的索引名稱、類型值、分頁大小以及每次請求的scroll遊標存活時間等信息,然後向服務器發送數據查詢請求,並保存返回結果中的scroll_id值,此id值作爲下次訪問的必要內容;
  3. 獲取到第一次請求的scroll_id值,再次設置數據請求的scroll遊標存活時間,即可訪問下一組size大小的索引數據,依次循環直到數據請求完畢;
  4. 清除滾屏的scroll_id值,釋放內存資源。

缺點
scroll是對數據的一種快照,當數據發生任何變化的情況下(比如新增、更新和刪除操作),是不會被感知到的,且維護scroll上下文也是非常昂貴的,因此不適用於實時和高併發的場景;
因爲採用scroll方式,每次的數據請求都需要上一次請求結果中的scroll_id值來作爲下次訪問時的標誌,因此採用此方式無法進行頁面的隨機跳轉功能,只能進行滾動式數據瀏覽(類似於微博);

3. search_after

search_after分頁的方式是根據上一頁的最後一條數據來確定下一頁的位置,同時再分頁請求的過程中,如果有索引數據的增刪改查,這些變更也會實時的反映到遊標上。但是需要注意,因爲每一頁的數據依賴於上一頁的最後一條數據,所以沒法跳頁請求

爲了找到每一頁最後一條數據,每個文檔那個必須有一個全局唯一值,官方推薦使用_uuid作爲全局唯一值,當然在業務上的id也可以。

參考:
ElasticSearch——分頁查詢
Elasticsearch分頁解決方案

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章