中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ElasticSearch深度分頁怎么實現

發布時間:2023-02-22 11:23:46 來源:億速云 閱讀:102 作者:iii 欄目:開發技術

本篇內容介紹了“ElasticSearch深度分頁怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1 前言

ElasticSearch 是一個實時的分布式搜索與分析引擎,常用于大量非結構化數據的存儲和快速檢索場景,具有很強的擴展性。

2 from + size 分頁方式

from + size 分頁方式是 ES 最基本的分頁方式,類似于關系型數據庫中的 limit 方式。from 參數表示:分頁起始位置;size 參數表示:每頁獲取數據條數。例如:

GET /wms_order_sku/_search
{
  "query": {
    "match_all": {}
  },
  "from": 10,
  "size": 20
}

該條 DSL 語句表示從搜索結果中第 10 條數據位置開始,取之后的 20 條數據作為結果返回。這種分頁方式在 ES 集群內部是如何執行的呢?在 ES 中,搜索一般包括 2 個階段,Query 階段和 Fetch 階段,Query 階段主要確定要獲取哪些 doc,也就是返回所要獲取 doc 的 id 集合,Fetch 階段主要通過 id 獲取具體的 doc。

2.1 Query 階段

如上圖所示,Query 階段大致分為 3 步:

  • 第一步:Client 發送查詢請求到 Server 端,Node1 接收到請求然后創建一個大小為 from + size 的優先級隊列用來存放結果,此時 Node1 被稱為 coordinating node(協調節點);

  • 第二步:Node1 將請求廣播到涉及的 shard 上,每個 shard 內部執行搜索請求,然后將執行結果存到自己內部的大小同樣為 from+size 的優先級隊列里;

  • 第三步:每個 shard 將暫存的自身優先級隊列里的結果返給 Node1,Node1 拿到所有 shard 返回的結果后,對結果進行一次合并,產生一個全局的優先級隊列,存在 Node1 的優先級隊列中。(如上圖中,Node1 會拿到 (from + size) * 6 條數據,這些數據只包含 doc 的唯一標識_id 和用于排序的_score,然后 Node1 會對這些數據合并排序,選擇前 from + size 條數據存到優先級隊列);

2.2 Fetch 階段

如上圖所示,當 Query 階段結束后立馬進入 Fetch 階段,Fetch 階段也分為 3 步:

  • 第一步:Node1 根據剛才合并后保存在優先級隊列中的 from+size 條數據的 id 集合,發送請求到對應的 shard 上查詢 doc 數據詳情;

  • 第二步:各 shard 接收到查詢請求后,查詢到對應的數據詳情并返回為 Node1;(Node1 中的優先級隊列中保存了 from + size 條數據的_id,但是在 Fetch 階段并不需要取回所有數據,只需要取回從 from 到 from + size 之間的 size 條數據詳情即可,這 size 條數據可能在同一個 shard 也可能在不同的 shard,因此 Node1 使用 multi-get 來提高性能)

  • 第三步:Node1 獲取到對應的分頁數據后,返回給 Client;

2.3 ES 示例

依據上述我們對 from + size 分頁方式兩階段的分析會發現,假如起始位置 from 或者頁條數 size 特別大時,對于數據查詢和 coordinating node 結果合并都是巨大的性能損耗。例如:索引 wms_order_sku 有 1 億數據,分 10 個 shard 存儲,當一個請求的 from = 1000000, size = 10。在 Query 階段,每個 shard 就需要返回 1000010 條數據的_id 和_score 信息,而 coordinating node 就需要接收 10 * 1000010 條數據,拿到這些數據后需要進行全局排序取到前 1000010 條數據的_id 集合保存到 coordinating node 的優先級隊列中,后續在 Fetch 階段再去獲取那 10 條數據的詳情返回給客戶端。分析:這個例子的執行過程中,在 Query 階段會在每個 shard 上均有巨大的查詢量,返回給 coordinating node 時需要執行大量數據的排序操作,并且保存到優先級隊列的數據量也很大,占用大量節點機器內存資源。

2.4 實現示例

private SearchHits getSearchHits(BoolQueryBuilder queryParam, int from, int size, String orderField) {
        SearchRequestBuilder searchRequestBuilder = this.prepareSearch();
        searchRequestBuilder.setQuery(queryParam).setFrom(from).setSize(size).setExplain(false);
        if (StringUtils.isNotBlank(orderField)) {
            searchRequestBuilder.addSort(orderField, SortOrder.DESC);
        }
        log.info("getSearchHits searchBuilder:{}", searchRequestBuilder.toString());
        SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
        log.info("getSearchHits searchResponse:{}", searchResponse.toString());
        return searchResponse.getHits();
    }

2.5 小結

其實 ES 對結果窗口的返回數據有默認 10000 條的限制(參數:index.max_result_window = 10000),當 from + size 的條數大于 10000 條時 ES 提示可以通過 scroll 方式進行分頁,非常不建議調大結果窗口參數值。

3 Scroll 分頁方式

scroll 分頁方式類似關系型數據庫中的 cursor(游標),首次查詢時會生成并緩存快照,返回給客戶端快照讀取的位置參數(scroll_id),后續每次請求都會通過 scroll_id 訪問快照實現快速查詢需要的數據,有效降低查詢和存儲的性能損耗。

3.1 執行過程

scroll 分頁方式在 Query 階段同樣也是 coordinating node 廣播查詢請求,獲取、合并、排序其他 shard 返回的數據_id 集合,不同的是 scroll 分頁方式會將返回數據_id 的集合生成快照保存到 coordinating node 上。Fetch 階段以游標的方式從生成的快照中獲取 size 條數據的_id,并去其他 shard 獲取數據詳情返回給客戶端,同時將下一次游標開始的位置標識_scroll_id 也返回。這樣下次客戶端發送獲取下一頁請求時帶上 scroll_id 標識,coordinating node 會從 scroll_id 標記的位置獲取接下來 size 條數據,同時再次返回新的游標位置標識 scroll_id,這樣依次類推直到取完所有數據。

“ElasticSearch深度分頁怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鹤庆县| 衡东县| 福清市| 深圳市| 吉水县| 屯留县| 名山县| 来安县| 石泉县| 博野县| 芜湖市| 江安县| 黄大仙区| 浙江省| 神农架林区| 苏州市| 韶山市| 兰坪| 太和县| 杭州市| 庄河市| 建阳市| 佳木斯市| 溆浦县| 崇州市| 炉霍县| 合山市| 惠安县| 新竹县| 呈贡县| 大田县| 榕江县| 徐州市| 青铜峡市| 盐津县| 仙居县| 蒲江县| 潜山县| 井研县| 仪征市| 汉寿县|