• @Elasticsearch之深度应用及原理剖析--深度分页问题



    title: ElasticSearch之深度应用及原理剖析
    author: Xoni
    tags:

    • 搜索引擎
    • Elasticsearch
      categories:
    • 搜索引擎
    • Elasticsearch
      abbrlink: 5a1f6e0b

    第14节 deep paging性能问题 和 解决方案

    在这里插入图片描述

    深度分页问题

    ES 默认采用的分页方式是 from+ size 的形式,类似于mysql的分页limit。当请求数据量比较大时, Elasticsearch会对分页做出限制,因为此时性能消耗会很大。举个例子,一个索引 分10个 shards,然后,一个搜索请求,from=990,size=10,这时候,会带来严重的性能问题:

    • CPU
    • 内存
    • IO
    • 网络带宽

    CPU、内存和IO消耗容易理解,网络带宽问题稍难理解一点。在 query 阶段,每个shard需要返回 1000条数据给 coordinating node,而 coordinating node 需要接收 10*1000 条数据,即使每条数据只有 _doc _id 和 _score,这数据量也很大了,而且,这才一个查询请求,那如果再乘以100呢?
    es中有个设置 index.max_result_window,默认是10000条数据,如果分页的数据超过第1万条,就拒绝返回结果了。如果你觉得自己的集群还算可以,可以适当的放大这个参数,比如100万。
    我们意识到,有时这种深度分页的请求并不合理,因为我们是很少人为的看很后面的请求的,在很多的业务场景中,都直接限制分页,比如只能看前100页。
    不过,这种深度分页确实存在,比如有1千万粉丝的微信大V,要给所有粉丝群发消息,或者给某省粉丝群发,这时候就需要取得所有符合条件的粉丝,而最容易想到的就是利用 from + size 来实现,但这是不现实的,我们需要使用下面的解决方案。

    深度分页解决方案

    利用 scroll 遍历方式

    **

    • 初始化时将所有符合搜索条件的搜索结果缓存起来,可以想象成快照
    • 在遍历时,从这个快照里取数据,也就是说,在初始化后对索引插入、删除、更新数据都不会影响遍历结果。

    因此,scroll 并不适合用来做实时搜索,而更适用于后台批处理任务,比如群发。

    1)初始化

    POST /book/_search?scroll=1m&size=2 
    {
    	"query": {
    	  "match_all": {}
    	}
    }
    

    初始化时需要像普通 search 一样,指明 index 和 type (当然,search 是可以不指明 index 和 type 的),然后,加上参数 scroll,表示暂存搜索结果的时间,其它就像一个普通的search请求一样。
    初始化返回一个 scroll_id,scroll_id 用来下次取数据用

    1. 遍历
    GET /_search/scroll
    { 
      "scroll": "1m",
      "scroll_id" : "步骤1中查询出来的值"
    }
    

    这里的 scroll_id 即 上一次遍历取回的 _scroll_id 或者是初始化返回的 _scroll_id,同样的,需要带scroll 参数。 重复这一步骤,直到返回的数据为空,即遍历完成。注意,每次都要传参数 scroll,刷新搜索结果的缓存时间。另外,不需要指定 index 和 type。设置scroll的时候,需要使搜索结果缓存到下一次遍历完成,同时,也不能太长,毕竟空间有限。

    search after方式

    满足实时获取下一页的文档信息,search_after 分页的方式是根据上一页的最后一条数据来确定下一页的位置,同时在分页请求的过程中,如果有索引数据的增删改,这些变更也会实时的反映到游标上,这种方式是在es-5.X之后才提供的。为了找到每一页最后一条数据,每个文档的排序字段必须有一个全局唯一值 使用 _id 就可以了。

    GET /book/_search
    {
      "query": {
        "match_all": {}
      },
      "size": 2,
      "sort": [
        {
          "_id": "desc"
        }
      ]
    }
    
    GET /book/_search
    {
      "query": {
        "match_all": {}
      },
      "size": 2,
      "search_after": [
        3
      ],
      "sort": [
        {
          "_id": "desc"
        }
      ]
    }
    

    下一页的数据依赖上一页的最后一条的信息所以不能跳页。

    三种分页方式比较

  • 相关阅读:
    FANUC机器人实现本地自动运行的相关配置和参数设置
    实现简单的shared_ptr
    力扣197. 上升的温度
    钉钉7.5版本多项产品升级,打造年轻人爱用的AI工具
    除了ChatGPT,跨境电商必备的7个AI工具
    电子作业票系统:消除安全管理漏洞,科技赋能企业业务洞察
    以太网的概念
    京东金融客户端用户触达方式的探索与实践
    记录使用Docker Compose 部署《XAPI项目》遇道的问题及解决方案
    ns3入门基础教程
  • 原文地址:https://blog.csdn.net/weixin_45992021/article/details/127041228