背景
以 ES 存储日志,且需要对日志进行分页检索,当数据量过大时,就面临 ES 万条以外的数据检索问题,如何利用滚动检索实现这个需求呢?本文介绍 ES 分页检索万条以外的数据实现方法及注意事项。
需求分析
用 ES 存储数据,分页检索,当 ES 数据量过大时,在页面上直接点击最后一页时,怎么保证请求能正常返回?
常规思路就是,超过万条以后,使用滚动检索,但需要注意:编写滚动检索的分页查询时,滚动请求的 size 一定不能用页面分页参数的 pageSize ,要能快速滚动到目标页所在的数据,最好以 ES 最大检索窗口值。
算法要点
第一,滚动检索的 Request 请求不能包含 from 属性, 且设置了 size 参数后,以后的每次滚动返回的数据量都以 size 为主。
第二,滚动获取数据的 size 选取。 滚动分页检索高效的关键是不能以页面分页参数 pageSize 作为滚动请求的 size ,而是以一个较大的数,或者直接以 ES 默认的滚动窗口最大值 10000 作为每批次获取的数据量。
第三,计算目标页的数据所在的位置。
- 根据分页参数计算出目标数据的位置是
[(pageNo-1)*pageSize, pageNo*pageSize]
,为了拿到目标页的数据,总共的数据量total = pageNo * pageSize
。 - 目标数据在最终数据中的真正范围决定因素:
mode = total % 10000
。 - 计算滚动请求几次能拿到目标数据。实际需要滚动请求的次数
scrollCount = mode == 0 ? total/ esWindowCount : (total/ esWindowCount + 1)
。 - 目标页的数据有没有分布在两次请求中。当
10000 % pageSize !=0
时,说明这一页的数据会横跨两次 ES 请求。例如pageSize =15,pageNo = 2667,total = 40005,
目标页的数据包含在最后两次请求中,倒数第二次请求中有 10 条数据,最后一次请求中有 5 条数据,合起来才是一整页的 15 条数据。 - 最后一页数据不足 pageSize 时,最后一页数据真正的长度。
第四,分页数据所在范围处理。 当最后一批次获取到数据后,从中摘出目标页的数据时,需要考虑的四种情况,主要是 mode 和最终获取的数据总长度直接的关系:
case 1:上图左,mode=0 时存在最后一页不足 size 的情况,realSize = size - (windowSize-length)
。
case 2:上图右,length < mode 时,最后一页不足 size 的情况,realSize = size - (mode -length)
。
最终的数据区间是 [from,to ] = [ length -realSize,length -1 ]
。
数据总长度 = end -start +1 = realSize
。
case 3 :上图左,分页数据在 mode 往前推 size 条。
case 4:上图右,分页数据横跨两次请求,两批数据组合成一页数据。
编写 ES 滚动分页检索请求,处理超过万条之外的查询操作时需注意上面的边界。
滚动分页的关键伪代码:
// 分页滚动计数器
int counter = 2;
// 目标页数据所在的位置
int mode = total % esWindowCount;
// 滚动的总次数
int realPageCount = mode == 0 ? total/ esWindowCount : (total/ esWindowCount + 1);
while (counter <= realPageCount) {
// TODO 滚动请求
// size 非 10 的整数,则当前页数据横跨两个 Scroll 请求
if (mode != 0 && mode < pageSize && counter == (realPageCount -1)) {
// TODO 搜集当前一万条检索结果的后 (size-mode) 条数据
}
// TODO 更新滚动查询id
counter++;
}
// TODO 收集最后一次响应结果中的数据
启示录
滚动查询时优化了 size 用一万,相比用页面的分页参数 pageSize ,可以解决数据量过大时,直接从页面点击最后一页导致页面卡死长时间无响应的问题。
页面分页参数最大不过 100,当总数量几百万、pageSize=10,分页跳转查询后面某页 如 3000 时,ES 的滚动请求次数 是 3000 次,而优化后滚动请求 3次,第三次中的一万条数据的最后10条即本页的数据。文章来源:https://www.toymoban.com/news/detail-775287.html
话说回来,ES 数据量过大时,用分页查询靠后的数据时,也没多大的价值了,列表宽泛条件查询结果过大时,谁看得过来呢?文章来源地址https://www.toymoban.com/news/detail-775287.html
到了这里,关于ES 万条以外分页检索功能实现及注意事项的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!