欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ElasticSearch?深度分頁示例解析

 更新時間:2023年02月22日 10:37:50   作者:深巷的貓  
這篇文章主要為大家介紹了ElasticSearch?深度分頁示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

1 前言

ElasticSearch 是一個實時的分布式搜索與分析引擎,常用于大量非結(jié)構(gòu)化數(shù)據(jù)的存儲和快速檢索場景,具有很強的擴展性??v使其有諸多優(yōu)點,在搜索領(lǐng)域遠超關(guān)系型數(shù)據(jù)庫,但依然存在與關(guān)系型數(shù)據(jù)庫同樣的深度分頁問題,本文就此問題做一個實踐性分析探討

2 from + size 分頁方式

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

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

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

2.1 Query 階段

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

  • 第一步:Client 發(fā)送查詢請求到 Server 端,Node1 接收到請求然后創(chuàng)建一個大小為 from + size 的優(yōu)先級隊列用來存放結(jié)果,此時 Node1 被稱為 coordinating node(協(xié)調(diào)節(jié)點);
  • 第二步:Node1 將請求廣播到涉及的 shard 上,每個 shard 內(nèi)部執(zhí)行搜索請求,然后將執(zhí)行結(jié)果存到自己內(nèi)部的大小同樣為 from+size 的優(yōu)先級隊列里;
  • 第三步:每個 shard 將暫存的自身優(yōu)先級隊列里的結(jié)果返給 Node1,Node1 拿到所有 shard 返回的結(jié)果后,對結(jié)果進行一次合并,產(chǎn)生一個全局的優(yōu)先級隊列,存在 Node1 的優(yōu)先級隊列中。(如上圖中,Node1 會拿到 (from + size) * 6 條數(shù)據(jù),這些數(shù)據(jù)只包含 doc 的唯一標識_id 和用于排序的_score,然后 Node1 會對這些數(shù)據(jù)合并排序,選擇前 from + size 條數(shù)據(jù)存到優(yōu)先級隊列);

2.2 Fetch 階段

如上圖所示,當(dāng) Query 階段結(jié)束后立馬進入 Fetch 階段,F(xiàn)etch 階段也分為 3 步:

  • 第一步:Node1 根據(jù)剛才合并后保存在優(yōu)先級隊列中的 from+size 條數(shù)據(jù)的 id 集合,發(fā)送請求到對應(yīng)的 shard 上查詢 doc 數(shù)據(jù)詳情;
  • 第二步:各 shard 接收到查詢請求后,查詢到對應(yīng)的數(shù)據(jù)詳情并返回為 Node1;(Node1 中的優(yōu)先級隊列中保存了 from + size 條數(shù)據(jù)的_id,但是在 Fetch 階段并不需要取回所有數(shù)據(jù),只需要取回從 from 到 from + size 之間的 size 條數(shù)據(jù)詳情即可,這 size 條數(shù)據(jù)可能在同一個 shard 也可能在不同的 shard,因此 Node1 使用 multi-get 來提高性能)
  • 第三步:Node1 獲取到對應(yīng)的分頁數(shù)據(jù)后,返回給 Client;

2.3 ES 示例

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

2.4 實現(xiàn)示例

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 小結(jié)

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

3 Scroll 分頁方式

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

3.1 執(zhí)行過程

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

以上就是ElasticSearch 深度分頁示例解析的詳細內(nèi)容,更多關(guān)于ElasticSearch 深度分頁的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java?SpringBoot集成文件之如何使用POI導(dǎo)出Word文檔

    Java?SpringBoot集成文件之如何使用POI導(dǎo)出Word文檔

    這篇文章主要介紹了Java?SpringBoot集成文件之如何使用POI導(dǎo)出Word文檔,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-08-08
  • Java中的this、super、final關(guān)鍵字詳解

    Java中的this、super、final關(guān)鍵字詳解

    這篇文章主要介紹了Java中的this、super、final關(guān)鍵字詳解,它在方法內(nèi)部使用,表示這個方法所屬對象的引用,它在構(gòu)造器內(nèi)部使用,表示該構(gòu)造器正在初始化的對象,this 可以調(diào)用類的屬性、方法和構(gòu)造器,需要的朋友可以參考下
    2023-09-09
  • spring?boot集成jasypt?并實現(xiàn)自定義加解密的詳細步驟

    spring?boot集成jasypt?并實現(xiàn)自定義加解密的詳細步驟

    由于項目中的配置文件?配置的地方過多,現(xiàn)將配置文件統(tǒng)一放到nacos上集中管理?且密碼使用加密的方式放在配置文件中,配置文件的加密使用加密庫jasypt,本文給大家介紹spring boot集成jasypt并實現(xiàn)自定義加解密,感興趣的朋友一起看看吧
    2023-08-08
  • Java中反射reflect的基礎(chǔ)知識講解

    Java中反射reflect的基礎(chǔ)知識講解

    這篇文章主要介紹了Java中反射reflect的基礎(chǔ)知識講解,Java中的反射,它算是Java當(dāng)中非常底層的一個技術(shù),平時我們我們用得不多,實際上它也的確非常復(fù)雜同時也難以理解,但是涉及到底層的東西Java都給我們封裝好了,我們直接拿來調(diào)用即可,需要的朋友可以參考下
    2023-10-10
  • Spring注入方式有哪些

    Spring注入方式有哪些

    你知道Spring的注入方式有哪幾種嗎?這篇文章主要為大家詳細介紹了Spring的注入方式,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Java NIO Buffer過程詳解

    Java NIO Buffer過程詳解

    這篇文章主要介紹了Java NIO Buffer過程詳解,緩沖區(qū)在java nio中負責(zé)數(shù)據(jù)的存儲。緩沖區(qū)就是數(shù)組。用于存儲不同數(shù)據(jù)類型的數(shù)據(jù)。,需要的朋友可以參考下
    2019-06-06
  • Java設(shè)計模式之備忘錄模式(Memento模式)介紹

    Java設(shè)計模式之備忘錄模式(Memento模式)介紹

    這篇文章主要介紹了Java設(shè)計模式之備忘錄模式(Memento模式)介紹,memento是一個保存另外一個對象內(nèi)部狀態(tài)拷貝的對象,這樣以后就可以將該對象恢復(fù)到原先保存的狀態(tài),需要的朋友可以參考下
    2015-03-03
  • java 線程方法join簡單用法實例總結(jié)

    java 線程方法join簡單用法實例總結(jié)

    這篇文章主要介紹了java 線程方法join簡單用法,結(jié)合實例形式總結(jié)分析了Java線程join方法的功能、原理及使用技巧,需要的朋友可以參考下
    2019-11-11
  • Java中注解@JsonFormat的用法詳解

    Java中注解@JsonFormat的用法詳解

    這篇文章主要給大家介紹了關(guān)于Java中注解@JsonFormat用法的相關(guān)資料,以及分享了@JsonFormat 將枚舉序列化為對象的方法,文中給出了詳細的代碼實例,需要的朋友可以參考下
    2023-01-01
  • SpringBoot中使用JdbcTemplate訪問Oracle數(shù)據(jù)庫的案例詳解

    SpringBoot中使用JdbcTemplate訪問Oracle數(shù)據(jù)庫的案例詳解

    JdbcTemplate是Spring框架中的一個核心類,用于簡化Java應(yīng)用程序與關(guān)系型數(shù)據(jù)庫的交互操作,本文給大家介紹SpringBoot中使用JdbcTemplate訪問Oracle數(shù)據(jù)庫的方法,感興趣的朋友跟隨小編一起看看吧
    2023-10-10

最新評論