ElasticSearch7.x 【深度分页】

各位老爷好,最近太忙了以至于没有更新给大家道歉了。

 

问题1.  深度分页相关优化

背景是脚本循环取es20条数据,平常时间段内,es里符合条件的数据不会超过1w, 而大促期间,则会超越1w,与es里的索引配置起重读而导致报错。

尝试一:

  • 尝试:尝试使用scroll的方式查询,毕竟是个脚本嘛,实时性要求不高,编码很简单,大家对着api写即可。结果是,我查询1w条之后的10条,没有引发报错,但是查询时间直接飙升到20s+,性能算是差极了,如果脚本用的数据是比较急,那怕是跑完所有数据之后,大促也都过去了。
  • 分析:我们分析一下为什么这么慢,因为scroll实际上是将一次深度查询的页码分为多次较小的查询,多次查询的时间累加就是你的总查询次数,我尝试过将size扩大到100,但是查询时间依旧很长,鉴于查询时间因素,我们舍弃这种方案。
  • 缺点:另外scroll有个缺点,实际上是在进行scroll查询的时候,es会产生一个当前的快照,scroll的后续查询都是基于这个快照的,如果在查询过程中有新的文档添加进来,你的这次scroll查询是无法召回这个文档的。
  • 总结: 如果你对数据的实时性不高,我是指能接受查询期间新增加的数据丢失,并且你有充足的时间,那么深度查询的时候你可以选择scroll的方式查询。

尝试二:

  • 尝试:scroll的方式失败后,我尝试在接口调用方进行优化,因为场景里需要的数据没有排序要求,只要把符合条件的文档全部召回即可,所以我在调用方加了排序参数,根据id正序排,一点点取,每次取出数据记录最后一个id,后续查询时增加id作为参数,而es这边直接根据传进来的id过滤掉<id的文档,配合size参数,可以避免深度查询,实时也证明此方式时可以的。
  • 分析:此方式可以避免深度查询,我们实际上时记录了一个游标,即id,每次携带id进入es,直接过滤掉<id的文档,这样我们实际上每次都只是查询这个id之后的size条数据。
  • 缺点: 改起来比较繁琐,涉及到旧的接口,可能会几率遗漏,导致部分功能失效。
  • 总结:实际上我们是模拟了游标查询,id即为游标,而在es侧,我们不再查询出所有的from然后取size,而是直接过滤掉<id的文档,然后取后面的size条数据。

尝试三:

  • 尝试:虽然已经有一个解决方案了,但是我们希望有更专业的,所以我们可以使用es里的search_after的方式进行深度查询,具体如何使用,也很简单,大家可以找api对着用即可,其中要注意的就是

    1)我们需要保证一个唯一的sort,建议将id加入sort排序中去

       2)from需要设置为0或者-1,否则会引发报错。

GET movies/_search
{
  "size": 2, 
  "query": {
    "match_all": {}
  },
  "search_after":[
          "1"
        ],
  "sort": [
    {
      "_id": {
        "order": "asc"
      }
    }
  ]
}
  • 分析:search_after的原理实际上时通过唯一排序定位,将每次要处理的文档都控制为size大小,通过此方式来避免深度分页。

  • 缺点:search_after无法进行跳跃分页。。。只能每次往后查询

  • 总结:search_after是官方给的深度查询方式,在使用条件都符合的情况下,我们推荐使用此方式,如果有条件限制并且有跳跃查询的话,我推荐使用方案而,因为它比较灵活。

from/size、scroll、search_after三者的比较

  • from / size : 该查询的实现原理类似于mysql中的limit,比如查询第10001条数据,那么需要将前面的10000条都拿出来,进行过滤,最终才得到数据。(性能较差,实现简单,适用于少量数据,数据量不超过1w,1w是可配置的,量力而行)。
  •  scroll:该查询实现类似于消息消费的机制,首次查询的时候会在内存中保存一个历史快照以及游标(scroll_id),记录当前消息查询的终止位置,下次查询的时候将基于游标进行消费(性能良好,维护成本高,在游标失效前,不会更新数据,不够灵活,一旦游标创建size就不可改变,适用于大量数据导出或者索引重建)
  • search_after: 性能优秀,类似于优化后的分页查询,历史条件过滤掉数据,不适合存在跳跃查询的场景。

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值