亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Elasticsearch進(jìn)行深度分頁(yè)的詳細(xì)指南(避免踩坑+報(bào)錯(cuò))

 更新時(shí)間:2025年04月15日 09:56:06   作者:浪浪山老周  
這篇文章主要為大家詳細(xì)介紹了使用Elasticsearch進(jìn)行深度分頁(yè)時(shí)會(huì)員踩的坑以及報(bào)錯(cuò)的相關(guān)解決方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一、問題復(fù)現(xiàn):為何查詢會(huì)觸發(fā)「Result window is too large」

當(dāng)我們?cè)?Elasticsearch 中使用傳統(tǒng)分頁(yè)參數(shù) from 和 size 時(shí),若 from + size > 10000,會(huì)直接觸發(fā)如下異常:

{
  "error": {
    "root_cause": [{
      "type": "illegal_argument_exception",
      "reason": "Result window is too large, from + size must be <= 10000"
    }]
  }
}

??根本原因??:

Elasticsearch 默認(rèn)限制單次查詢返回的文檔總數(shù)不超過 10,000 條(即 index.max_result_window 參數(shù))。當(dāng)進(jìn)行深度分頁(yè)(如查詢第 10001-10100 條數(shù)據(jù))時(shí),協(xié)調(diào)節(jié)點(diǎn)需要從所有分片中??先拉取前 10100 條數(shù)據(jù)??,再進(jìn)行全局排序和截取,導(dǎo)致內(nèi)存和計(jì)算資源爆炸。

二、解決方案對(duì)比:哪種方案適合你的場(chǎng)景

方案原理優(yōu)點(diǎn)缺點(diǎn)適用場(chǎng)景
??調(diào)整 max_result_window??直接修改索引配置增大分頁(yè)窗口實(shí)現(xiàn)簡(jiǎn)單,無需改代碼內(nèi)存風(fēng)險(xiǎn)高,僅適合小數(shù)據(jù)量少量數(shù)據(jù)的分頁(yè)(≤10萬條)
Scroll API??通過快照機(jī)制保持查詢上下文,分批次拉取數(shù)據(jù)支持海量數(shù)據(jù)導(dǎo)出數(shù)據(jù)實(shí)時(shí)性差,資源消耗大批量導(dǎo)出/離線任務(wù)
??Search After??基于上一頁(yè)最后一個(gè)文檔的排序值作為游標(biāo),避免 from 累積性能最優(yōu),支持實(shí)時(shí)分頁(yè)必須定義全局排序字段C端實(shí)時(shí)分頁(yè)(如列表頁(yè)瀏覽)

三、方案詳解與代碼實(shí)現(xiàn)

1. 暴力擴(kuò)容法:調(diào)整 max_result_window(不推薦)

??實(shí)現(xiàn)步驟??:

# 動(dòng)態(tài)修改索引配置(需保留原有設(shè)置)
PUT /your_index/_settings?preserve_existing=true
{
  "index": {
    "max_result_window": "20000"  # 設(shè)置為更大的值
  }
}

核心問題??:

  • 官方明確警告此操作可能導(dǎo)致 ??OOM(內(nèi)存溢出)?? 和節(jié)點(diǎn)故障
  • 深度分頁(yè)時(shí),協(xié)調(diào)節(jié)點(diǎn)仍需加載前 N 條數(shù)據(jù)到內(nèi)存,性能呈指數(shù)級(jí)下降
  • 僅適合臨時(shí)測(cè)試或數(shù)據(jù)量極小的場(chǎng)景(如后臺(tái)管理后臺(tái)導(dǎo)出 10 萬條數(shù)據(jù))

2.批量導(dǎo)出法:Scroll API(適合離線場(chǎng)景)

??實(shí)現(xiàn)原理??:

通過 scroll 參數(shù)創(chuàng)建快照上下文,后續(xù)請(qǐng)求通過 scroll_id 持續(xù)拉取數(shù)據(jù),避免重復(fù)計(jì)算排序。

??Java 代碼示例??:

public JSONArray scrollQuery(JSONObject params) {
    JSONArray result = new JSONArray();
    String scrollId = null;
    
    try {
        // 初始化滾動(dòng)查詢(保持 10 分鐘快照)
        SearchRequest searchRequest = new SearchRequest("logs");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.size(1000);
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        
        searchRequest.source(sourceBuilder);
        searchRequest.scroll(TimeValue.timeValueMinutes(10));
        
        // 首次查詢獲取 scroll_id
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        scrollId = response.getScrollId();
        result.addAll(Arrays.asList(response.getHits().getHits()));
        
        // 持續(xù)拉取數(shù)據(jù)
        while (true) {
            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
            scrollRequest.scroll(TimeValue.timeValueMinutes(10));
            response = client.scroll(scrollRequest, RequestOptions.DEFAULT);
            
            if (response.getHits().getHits().length == 0) break;
            result.addAll(Arrays.asList(response.getHits().getHits()));
            scrollId = response.getScrollId();
        }
    } finally {
        // 清理上下文(必須操作)
        if (scrollId != null) {
            ClearScrollRequest clearRequest = new ClearScrollRequest();
            clearRequest.addScrollId(scrollId);
            client.clearScroll(clearRequest, RequestOptions.DEFAULT);
        }
    }
    return result;
}

??關(guān)鍵問題??:

  • 每次滾動(dòng)需維護(hù) scroll_id,內(nèi)存占用隨數(shù)據(jù)量增長(zhǎng)
  • 數(shù)據(jù)快照版本可能導(dǎo)致查詢結(jié)果不一致(如文檔被更新或刪除)

3.實(shí)時(shí)分頁(yè)法:Search After(推薦方案)

??實(shí)現(xiàn)原理??:

通過記錄上一頁(yè)最后一個(gè)文檔的排序值(如時(shí)間戳或唯一ID),在下一次查詢時(shí)直接定位到該位置,??跳過無效數(shù)據(jù)掃描??。

??Java 代碼實(shí)現(xiàn)??:

java
public JSONObject searchData(JSONObject queryConditionsParam) {
    int pageSize = queryConditionsParam.getInt("pageSize");
    double[] searchAfter = null;
    
    // 提取游標(biāo)參數(shù)(上一頁(yè)最后一個(gè)文檔的排序值)
    if (queryConditionsParam.containsKey("search_after")) {
        JSONArray searchAfterArray = queryConditionsParam.getJSONArray("search_after");
        searchAfter = searchAfterArray.toDoubleArray();
    }

    SearchRequest searchRequest = new SearchRequest("my_log");
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

    // 關(guān)鍵配置:排序字段必須與 search_after 對(duì)應(yīng)
    sourceBuilder.sort("created_start_time", SortOrder.DESC);
    if (searchAfter != null) {
        sourceBuilder.searchAfter(searchAfter);
    }
    sourceBuilder.size(pageSize); // 無需設(shè)置 from 參數(shù)

    // 構(gòu)建查詢條件(示例:按日志ID過濾)
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(QueryBuilders.termQuery("log_id", queryConditionsParam.getInt("log_id")));
    // 其他復(fù)雜條件可在此追加...

    sourceBuilder.query(boolQueryBuilder);
    searchRequest.source(sourceBuilder);

    try {
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        return buildResult(response); // 封裝結(jié)果并返回游標(biāo)
    } catch (IOException e) {
        log.error("ES查詢失敗", e);
        throw new RuntimeException("查詢異常");
    }
}

// 結(jié)果封裝方法:提取游標(biāo)并返回下一頁(yè)參數(shù)
private JSONObject buildResult(SearchResponse response) {
    JSONObject result = new JSONObject();
    JSONArray hits = new JSONArray();
    double[] nextCursor = null;

    for (SearchHit hit : response.getHits()) {
        hits.add(new JSONObject(hit.getSourceAsString()));
        // 提取排序字段值作為下一頁(yè)游標(biāo)
        if (hit.getSortValues().length > 0) {
            nextCursor = Arrays.stream(hit.getSortValues())
                              .mapToDouble(Double::valueOf)
                              .toArray();
        }
    }

    result.put("data", hits);
    result.put("totalCount", response.getHits().getTotalHits().value);
    if (nextCursor != null) {
        result.put("search_after", nextCursor); // 返回游標(biāo)供下次查詢
    }
    return result;
}

??性能優(yōu)勢(shì)??:

??無深度分頁(yè)開銷??: 每次查詢僅獲取當(dāng)前頁(yè)數(shù)據(jù),避免全量數(shù)據(jù)掃描

??實(shí)時(shí)性保障??: 直接訪問最新數(shù)據(jù)快照,不受索引刷新影響

??資源消耗低??: 內(nèi)存占用與分頁(yè)大小線性相關(guān),而非與數(shù)據(jù)總量相關(guān)

四、方案選型決策樹

數(shù)據(jù)量 ≤10 萬條?? → 調(diào)整 max_result_window(快速實(shí)現(xiàn))

??需要全量導(dǎo)出?? → Scroll API(配合異步任務(wù))

??C端實(shí)時(shí)交互?? → Search After(最佳實(shí)踐)

五、避坑指南

1. 游標(biāo)失效場(chǎng)景??:

數(shù)據(jù)更新或刪除時(shí),可能導(dǎo)致游標(biāo)失效(需結(jié)合業(yè)務(wù)場(chǎng)景評(píng)估)

避免在頻繁更新的字段上使用 search_after

2.分頁(yè)深度限制??:

即使使用 search_after,仍建議限制最大分頁(yè)深度(如最多 1000 頁(yè)),防止惡意請(qǐng)求

??3.監(jiān)控與告警??:

通過 Elasticsearch 的 _cat/indices 接口監(jiān)控分頁(yè)查詢頻率,設(shè)置閾值告警

六、總結(jié)

方案推薦指數(shù)適用階段
調(diào)整 max_result_window?☆☆☆☆早期驗(yàn)證階段
Scroll API??☆☆☆臨時(shí)數(shù)據(jù)遷移/批量導(dǎo)出
Search After?????生產(chǎn)環(huán)境實(shí)時(shí)分頁(yè)

??終極建議: 在日志分析、用戶行為追蹤等場(chǎng)景中,結(jié)合 search_after + 時(shí)間范圍過濾 + 適當(dāng)?shù)木彺娌呗裕蓪?shí)現(xiàn)億級(jí)數(shù)據(jù)的高效分頁(yè)。立即升級(jí)你的分頁(yè)方案,告別 Result window is too large 報(bào)錯(cuò)!

到此這篇關(guān)于Elasticsearch進(jìn)行深度分頁(yè)的詳細(xì)指南(避免踩坑+報(bào)錯(cuò))的文章就介紹到這了,更多相關(guān)Elasticsearch深度分頁(yè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java的主要特性學(xué)習(xí)總結(jié)

    java的主要特性學(xué)習(xí)總結(jié)

    在本篇文章里小編給大家分享了一篇關(guān)于java的主要特性學(xué)習(xí)總結(jié)內(nèi)容,有興趣的朋友們可以參考下。
    2020-05-05
  • 使用棧的迷宮算法java版代碼

    使用棧的迷宮算法java版代碼

    這篇文章主要為大家詳細(xì)介紹了使用棧的迷宮算法java版代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • eclipse輸出Hello World的實(shí)現(xiàn)方法

    eclipse輸出Hello World的實(shí)現(xiàn)方法

    這篇文章主要介紹了eclipse輸出Hello World的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java整合騰訊云短信發(fā)送實(shí)例代碼

    Java整合騰訊云短信發(fā)送實(shí)例代碼

    大家好,本篇文章主要講的是Java整合騰訊云短信發(fā)送實(shí)例代碼,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • java編譯時(shí)指定classpath的實(shí)現(xiàn)方法

    java編譯時(shí)指定classpath的實(shí)現(xiàn)方法

    在Java編程中,classpath是用于指定Java虛擬機(jī)在運(yùn)行時(shí)查找類文件的路徑,本文主要介紹了java編譯時(shí)指定classpath的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • Java如何連接數(shù)據(jù)庫(kù)圖文教程

    Java如何連接數(shù)據(jù)庫(kù)圖文教程

    關(guān)于java數(shù)據(jù)庫(kù)的文章早已是非常多了,本文是對(duì)我個(gè)人過往學(xué)習(xí)java數(shù)據(jù)庫(kù),理解及應(yīng)用java數(shù)據(jù)庫(kù)的一個(gè)總結(jié),下面這篇文章主要給大家介紹了關(guān)于Java如何連接數(shù)據(jù)庫(kù)的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • java讀取文件字符集示例方法

    java讀取文件字符集示例方法

    這篇文章主要介紹了java讀取文件字符集的示例,需要的朋友可以參考下
    2014-02-02
  • Spring Bean實(shí)例的創(chuàng)建及構(gòu)造器的挑選

    Spring Bean實(shí)例的創(chuàng)建及構(gòu)造器的挑選

    這篇文章主要介紹了Spring Bean實(shí)例的創(chuàng)建及構(gòu)造器的挑選,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-04-04
  • 圖文講解IDEA中根據(jù)數(shù)據(jù)庫(kù)自動(dòng)生成實(shí)體類

    圖文講解IDEA中根據(jù)數(shù)據(jù)庫(kù)自動(dòng)生成實(shí)體類

    這篇文章主要以圖文講解IDEA中根據(jù)數(shù)據(jù)庫(kù)自動(dòng)生成實(shí)體類,本文主要以Mysql數(shù)據(jù)庫(kù)為例,應(yīng)該會(huì)對(duì)大家有所幫助,如果有錯(cuò)誤的地方,還望指正
    2023-03-03
  • springmvc接收json串,轉(zhuǎn)換為實(shí)體類List方法

    springmvc接收json串,轉(zhuǎn)換為實(shí)體類List方法

    今天小編就為大家分享一篇springmvc接收json串,轉(zhuǎn)換為實(shí)體類List方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08

最新評(píng)論