Es因scroll查询引起的gc问题怎么解决

发布时间:2022-05-07 11:11:15 作者:iii
来源:亿速云 阅读:527

这篇“Es因scroll查询引起的gc问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Es因scroll查询引起的gc问题怎么解决”文章吧。

问题:

某日下午正开心的逛着超市,突然收到线上es机器的fgc电话告警,随之而来的是一波es reject execution,该es机器所处集群出现流量抖动。

排查:

回到家打开监控页面,内存占用率有明显的上升,通常服务端不会无端的爆内存,首先排查可能性最高的:读写流量变化。

通过监控页发现入口流量并没有明显抖动,考虑到集群中的不同索引以及不同查询类型,总的入口流量可能会掩盖一些问题,所以继续查看各索引的分操作流量监控,发现索引 A 的scroll流量在故障发生时存在明显的波动,从正常的 10qps 以内涨到最高 100qps 左右,这对于普通查询来说并不高,看来是 scroll 查询有些异样。

起因1:

先说结论:scroll 查询相对普通查询占用的内存开销大很多,考虑到遍历数据的场景,安全的量是控制在 10qps 左右。

相比于普通query,scroll 查询需要后端保留遍历请求的上下文,具体的就是当有init scroll请求到达时,当时的 index searcher 会持有全部索引段的句柄直至scroll请求结束,如果处理不当,比如段缓存等,容易在server端占用大量内存;另外, scroll 查询还需要在server端保存请求上下文,比如翻页深度、scroll context等,也会占用内存资源。

在后续的测试中,客户端单线程使用scroll查询遍历百万级别的索引数据,server端的CPU占用率高达70%左右,观察进程的CPU占用,发现大部分的CPU时间都耗在gc上,这使得server没有足够的CPU时间调度其他任务,导致正常的读写请求不能被及时响应。

# 压测机器配置:1c2g x 10# 索引配置:5 number_of_shards x 1 number_of_replica,共计约180万数据

起因2:

继续排查scroll执行的查询内容,发现的主要有两种类型。

其一:

{    "query": {"bool":{"must":[{"terms":[11,22,…2003]}]}},    "size":200}# terms子句中包含200个id

上面的示例query省略了其他一些过滤条件,白话一下这个查询的含义:

从索引中查询id字段值为数组所包含的200条记录

可以看到的几个特征是:

其二:

{    "query": {"bool":{"must":[        {"range":{"create_time":{"gt":0, "lte":604800}}},        {"term":{"shop_id":1}}    ]}},    "size":200}# range条件包含的数据大约为1000条# 全索引包含的数据大约1000万条# create_time不固定,但是区间固定在1周

这里也省略了一些其他干扰条件,只保留最重要的,白话过来的含义:

从1000万全量索引中查询shop_id=1并且create_time在符合条件区间内的数据,条件区间每10秒变更一次,也就是每10秒查询一次当前时刻之前1周的新数据.

可以得出的几个结论:

并没有发现filter或者must_not这样在官方文档中明确标明的filter context条件,但是实际上的filter cache在scroll发生期间单机从 500 MB 左右逐渐升高到 6 GB(配置的filter cache最大空间),理论上说不通,直接从代码里找答案。

跟踪query流程,发现bool子句中不论是must还是filter,最终被rewrite之后没有本质上的区别,判断是否可以进入filter cache的条件是:

而在出现频次这个部分,Lucene缓存策略还会有isCostly这样的判断,目的是尽量将高消耗的查询尽可能早的缓存起来,提高查询性能,符合isCostly判断的查询包括 terms 和 range 等查询,只要重复出现2次即会被缓存起来,结合起来分析:

  1. terms查询并不需要scroll查询,使用普通查询就能解决需求,使用scroll查询增加了server负载

  2. range查询重复次数达到了isCostly阈值,也就是说每次遍历数据都会往filter cache中丢入几百万的缓存value,而且命中率极低(下次scroll查询的range起止条件有细微的变化),加大了server的gc负担

解决:

通过上面的分析,我们可以看到有两个因素的影响导致了server的拒绝响应:

  1. 大量的scroll并发

  2. 不当的range请求,具体又可以拆分为:

针对上面的几点各个击破就是我们的解决方案:

scroll请求:

不当的range请求:

以上就是关于“Es因scroll查询引起的gc问题怎么解决”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。

推荐阅读:
  1. 解决一个因Bitmap引起的OOM问题
  2. 一次因HashSet引起的并发问题详解

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

es scroll gc

上一篇:java泛型容器Collection怎么用

下一篇:Python作为小程序后端的实现方法有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》