您当前的位置: 首页 >  ar

大别山码将

暂无认证

  • 2浏览

    0关注

    126博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

大别山码将 发布时间:2022-09-25 18:53:38 ,浏览量:2

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

  • 搜索引擎
  • Elasticsearchcategories:
  • 搜索引擎
  • Elasticsearchabbrlink: 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"
    }
  ]
}

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

三种分页方式比较

关注
打赏
1664364263
查看更多评论
立即登录/注册

微信扫码登录

0.0362s