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

ElasticSearch?深度分頁(yè)示例解析

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

1 前言

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

2 from + size 分頁(yè)方式

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

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

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

2.1 Query 階段

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

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

2.2 Fetch 階段

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

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

2.3 ES 示例

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

2.4 實(shí)現(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é)

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

3 Scroll 分頁(yè)方式

scroll 分頁(yè)方式類(lèi)似關(guān)系型數(shù)據(jù)庫(kù)中的 cursor(游標(biāo)),首次查詢(xún)時(shí)會(huì)生成并緩存快照,返回給客戶(hù)端快照讀取的位置參數(shù)(scroll_id),后續(xù)每次請(qǐng)求都會(huì)通過(guò) scroll_id 訪(fǎng)問(wèn)快照實(shí)現(xiàn)快速查詢(xún)需要的數(shù)據(jù),有效降低查詢(xún)和存儲(chǔ)的性能損耗。

3.1 執(zhí)行過(guò)程

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

    Spring注入方式有哪些

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

    Java NIO Buffer過(guò)程詳解

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

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

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

    java 線(xiàn)程方法join簡(jiǎn)單用法實(shí)例總結(jié)

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

    Java中注解@JsonFormat的用法詳解

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

    SpringBoot中使用JdbcTemplate訪(fǎng)問(wèn)Oracle數(shù)據(jù)庫(kù)的案例詳解

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

最新評(píng)論