elasticsearch翻页与深度翻页,以及获取全部数据

我们通常会有需求:根据指定条件,查询数据。并分页展示。甚至还有可能要导出全部的数据。

在工作中,经常会有需求,将指定条件的数据导出(这个数据量多数在2亿以上,有一次是18亿)。导出数据的速度是挺慢的,特别是在单线程的情况下!

我们在这篇文章中,主要说三种分页查询数据的方式。

from+size

查询性能时间复杂度O(n),空间复杂度O(n)

从时间复杂度和空间复杂度上,可以看出来,随着向后翻页,数据量变多,一定会有性能问题。严重情况下,会有OOM问题。会出现越来越慢的问题。

from + size的原理是:每次每个分片返回 from + size的数据给协调节点。问题也出在这里,协调节点要承载 分片数*(from + size)的队列数据,并做排序,然后取出 size条数据返回。

官方也给我们限制了翻页的大小,总数据小于10000

SearchAfter

查询性能时间复杂度O(n),空间复杂度O(1)

可以看出来,这种方式不会有OOM问题,因为时间复杂度为O(1)。但是查询时间就不一样了。它会随着数据变多,越来越慢的。

SearchAfter是一种动态指针的技术,每次查询都会携带上一次的排序值,这样下次取结果只需要从上次的位点继续扫数据,前提条件也是该字段是数值类型且设置了docValue。举个例子,假设"val_1"是数值类型的字段,然后使用Search接口查询时候添加Sort("val_1"),那么response中可以拿到最后一条数据的"val_1"的值,,也就是response中sort字段的值,然后下次查询将该值放在query中的searchAfter参数中,下次查询就可以在上一次结果之后继续查询,如此反复,最后可以翻页很深,内存消耗相比size+from的方式降低了数倍。该方式效果类似于我们直接在bool查询中主动加一个rangeFilter,可以达到类似的效果。表面看这种方案能将查询速度降到O(1)的复杂度,实际上其内部还是会扫sort字段的docValue,翻页越深,则扫docValve越多,因此复杂度和翻页深度成正比,越往后查询越慢,但是相比size+from的方式,至少可以完成深度翻页的任务,不至于OOM,速度勉强可以接受。SearchAfter的翻页方式在性能上有了质的提升,但是其限制了用户只能一页一页往后翻,无法跳页,因此很多产品在功能设计时候是不允许跳页的,只能一页一页往后翻,也是有一定的技术原因的。

SearchScroll 

查询性能时间复杂度O(1),空间复杂度O(1)

这个是非常好的处理方式。因为它不会因为数据多而变慢。不会因为数据多浪费的内存越来越大!

Search接口在使用SearchAfter后,相比size+from的翻页方式,翻页性能有质的提升,但是和SearchScroll相比,性能逊色很多,用户需要获取的数据越多,翻的越深,则差别越大。

在查询性能上,SearchScroll的翻页方式,时间复杂度O(1),空间复杂度O(1)。SearchScroll能够以恒定的速度翻页获取完所有数据,而采用SearchAfter的方式获取数据会随翻页深度增大而吞吐能力大幅下降。在我们的单机单shard2亿数据测试中,采用SearchScroll方式能够以每次50ms延时稳定获取完2亿数据,而SearchAfter深度翻页到千万级条数据后查询延时就到了秒级别,查询速度线性下降。

在吞吐能力上,SearchScroll请求天然支持多并发方式查询,因此SearchScroll特别适合批量快速拉取大量数据,然后交给spark等计算平台进行后续数据分析处理。在Elasticsearch中把每个并发称之为一个Slice(分片),Elasticsearch内部对用户的请求进行分片,分片越多则速度越快,拉取数据的速度翻倍提高。当然之前的普通的Search查询方式也可以并发访问,但是需要用户将Search请求的query进行拆分,比如原来是获取1年的数据,那么可以将query拆分为12个,一个月一个请求,体现在查询语句里就是将月份条件添加到query语句中的filter中来保证仅返回某一个月的数据。Search查询通过拆分query有时候可以达到类似的并发效果,来加速Search查询,但是有些query语句是难以拆分的,使用成本较高,因此直接利用SearchScroll让Elasticsearch帮助我们进行并发拆分是一个不错的选择。

在结果稳定性上,SearchScroll由于会“打snapshot”,context会保留目前的segments,后续写入的数据都是感知不到的,因此不会造成查到的结果中存在重复数据或者缺失数据。在批量导数据等要求结果稳定的场景下,SearchScroll特别适用。从另一个角度讲,对需要稳定结果的用户来说是件好事,但是会导致该部分segments暂时无法被merge,也会占用一些操作系统的文件句柄,因此需要留意系统的这些方面的指标,确保Elasticsearch系统稳定运行。

总之,SearchScroll的查询速度很快,吞吐能力很高,结果很稳定。

并且 SearchScroll 还有优化提升的空间,因为它还能用并发的方式来更快的获取数据。我们可以适当的增加它的并发数。

参考文章:Elasticsearch之SearchScroll原理剖析和性能及稳定性优化 - 知乎Elasticsearch是一款优秀的开源企业级搜索引擎,其查询接口主要为Search接口,提供了丰富的各类查询、排序、统计聚合等功能。本文将要介绍的是另一个查询接口SearchScroll,同时介绍一下我们在这方面做的一些性能…https://zhuanlan.zhihu.com/p/231790621

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值