最近某客户在使用 Easysearch 做聚合时,报出 OOM 导致掉节点的问题,当时直接让客户试着调整 indices.breaker.request.limit ,但是不起作用,于是又看了下 Easysearch 在断路器相关的代码,并自己测试了下。

断路器的种类和作用

Easysearch 内部有个 Circuit breaker 机制,目的是防止各种请求的负载过大导致 OutOfMemoryError,比较常用的断路器有 7 种,分别是:

  • Parent circuit breaker 父断路器
  • Field data circuit breaker fielddata 断路器
  • Request circuit breaker 请求断路器
  • In flight requests circuit breaker 传输请求断路器
  • Accounting requests circuit breaker lucene 内存占用断路器
  • Script compilation circuit breaker 脚本编译断路器
  • Regex circuit breaker 正则表达式断路器

其中在执行消耗内存较多的聚合查询时,Request circuit breaker 用得最多。

复现测试

我在模拟客户场景测试聚合查询时,发现断路器并没有覆盖查询的整个流程,仍然会有 OOM 的风险。我测试了一个高基数 5 百万的 Terms aggregation,就没有触发断路,而是在等待了 1 分多钟后直接 OOM 了。我的测试环境是单节点 内存配置为 -Xmx1g,测试索引只有 1 个 shard。

测试语句如下:

curl -X GET "localhost:9211/leader-01/_search?pretty" -H 'Content-Type: application/json' -d'
{
"size": 1,
"aggs": {
"a": {
"terms": { "field": "agent.id.keyword", "size": 5000000 }
}
}
}' > a.txt

Easysearch OOM 日志:

内存泄漏分析

使用 MemoryAnalyzer 分析生成的 jvm 堆转储文件:

最大的内存占用来自 Java 线程java.lang.Thread @ 0x7c8bb1d00。这个线程浅层(Shallow)保留的对象占用了 112.8MB 内存。但该线程实际保留(Retained)的对象内存占用高达 851 MB,成为整个内存占用的绝对大头。

进一步查看 Leak Suspects

非常明确的给出了具体的内存泄露的对象:StringTerms$Bucket[7500010]

数组长度达到了七百五十万,占用内存:731,001,720 字节(占总内存的 68.65%)。

按照提示的GlobalOrdinalsStringTermsAggregator.java:586 行,去查看代码,实际上是将收集完的OrdBucket 转换为 StringTerms.Bucket,并且有一个 copy BytesRef的操作。

至此,原因和解决办法都清楚了,只要在转换之前预估一下将要增长的内存并调用断路器检测一下内存,一旦超出允许范围就快速触发 CircuitBreakingException,避免长时间等待后 OOM 引起的节点宕机了。

最新版 Elasticsearch 对比

作为对比,我又测试了下 Elasticsearch 最新版本 8.12.2,同样的测试环境和测试方法,结果依然是 OOM:

从这里可以看出 Elasticsearch 即使是最新版的断路器机制也还有很多改进的余地,比如增加对有 OOM 风险查询的覆盖率,还有就是在触发 GC 时,对 GC 堆内存回收的判断过于简单。

Easysearch 最新版本的改进

Easysearch 刚刚发布的 1.7.1 版本已经增加了上面的改进,后面也会持续改进查询聚合操作的内存控制,最新版本的跨集群复制(CCR)也增加了对 source_reuse 索引的支持,能更好的满足客户降本增效的需求,欢迎大家下载试用。

附官网下载链接:https://www.infinilabs.com/download/?product=easysearch

Easysearch 内核完善之 OOM 内存溢出优化案例一则的更多相关文章

  1. phpexcel 内存溢出 优化

    最近我们公司的项目的在导出excel的时候偶尔出现内存溢出错误,经过测试发现当数据量大于5000条就出现这个问题(默认php.ini memory 是128M) Allowed memory size ...

  2. OutOfMemoryError/OOM/内存溢出异常实例分析--虚拟机栈和本地方法栈溢出

    关于虚拟机栈和本地方法栈,在JVM规范中描述了两种异常: 1.如果线程请求的栈深度大于JVM所允许的深度,将抛出StackOverflowError异常: 2.如果虚拟机在扩展栈时无法申请到足够的内存 ...

  3. spark(oom内存溢出异常(out of memory))介绍1

    建立如图maven工程 maven的pom文件内容参考别的随笔 参考pom文件内容 同时记得添加scala oom内存溢出异常(out of memory)

  4. Java内存溢出优化性能优化

    高性能应用构成了现代网络的支柱.LinkedIn有许多内部高吞吐量服务来满足每秒数千次的用户请求.要优化用户体验,低延迟地响应这些请求非常重要. 比如说,用户经常用到的一个功能是了解动态信息——不断更 ...

  5. java 导出 excel 最佳实践,java 大文件 excel 避免OOM(内存溢出) excel 工具框架

    产品需求 产品经理需要导出一个页面的所有的信息到 EXCEL 文件. 需求分析 对于 excel 导出,是一个很常见的需求. 最常见的解决方案就是使用 poi 直接同步导出一个 excel 文件. 客 ...

  6. OutOfMemoryError/OOM/内存溢出异常实例分析--堆内存溢出

    Java堆内存溢出 只要不断创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象, 那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常,代码如下: import ...

  7. android OOM 内存溢出

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 一个应用的可用内存是有限的,如果超过了可用的内存,就会内存溢出. 1,避免 已经不用的对 ...

  8. 造成OOM(内存溢出)的几种情况

    数据库Cursor没关.当我们操作完数据库后,一定要调用close()释放资源. 构造Adapter没有使用缓存ContentView. @Override public View getView(i ...

  9. JVM内存监视手段和内存溢出解决方案

    引言 本文仅关注一些常见的虚拟机内存监视手段,以及JVM运行时数据区各个部分内存溢出的发生和对应的解决方案,总体来说属于概括性总结,涉及相对不是很深入,目的是让自己和其它初学者有一个框架性.概念性的了 ...

  10. JVM总结-内存监视手段及各区域内存溢出解决

    转载:https://blog.csdn.net/xuqu_volition/article/details/53786096 引言 本文仅关注一些常见的虚拟机内存监视手段,以及JVM运行时数据区各个 ...

随机推荐

  1. Kubernetes 稳定性保障手册 -- 极简版

    简介: Kubernetes 在生产环境中的采用率越来越高,复杂度越来越高,由此带来的稳定性保障的挑战越来越大. Kubernetes 在生产环境中的采用率越来越高,复杂度越来越高,由此带来的稳定性保 ...

  2. [FAQ] IDE: Goland or PHPStorm 分屏操作

    如图所示,文件上面点击右键,选择 Split Right 就可以在右侧分屏出编辑区. Refer:Goland下载 PHPStorm下载 Link:https://www.cnblogs.com/fa ...

  3. [Caddy2] URL访问路径的重定向和重写规则 (redir/rewrite 指令)

    当我们在规划网站路径时,为了保留搜索引擎收录 避免404的同时做到升级,常用到重定向跳转和URL重写. 重定向(redirect) 在 Caddy 中为 redir 指令. https://caddy ...

  4. [FAQ] Argument 3 passed to Lcobucci\JWT\Signer\Hmac::doVerify() must be an instance of Lcobucci\JWT\Signer\Key, null given

    出现这个错误,说明没有找到 key,在使用 laravel-jwt 之前需要生成加密 key,使用: $ php artisan jwt:secret Link:https://www.cnblogs ...

  5. 修复 WPF 安装 WindowsAppSDK 库构建失败 NETSDK1082 和 NETSDK1112 找不到 win10-arm 失败

    通过在 WPF 项目上安装 WindowsAppSDK 库,可以让 WPF 使用上 Win10 及以上版本提供的 Windows Runtime 强大的 API 集和使用上更多的黑科技.本文记录在安装 ...

  6. dotnet 构建还原失败 NuGet.targets 错误可能原因

    我在一次断电关机之后,发现我所有的项目都构建不通过了,提示在 NuGet.targets 文件的第 130 行错误.原因就是存在有某个被项目引用的 NuGet 包被损坏,在进行 NuGet 还原时读取 ...

  7. 在 VisualStudio 给文件起一个带分号的文件名会怎样

    小伙伴都知道在 Windows 下是支持文件名使用分号的,而写过 Roslyn 的小伙伴都知道,在 csproj 项目里面使用分号分割数组.那么在 VS 里面将一个文件名添加分号会如何?下面让咱写写看 ...

  8. 理解FPGA内部的同步信号、异步信号和亚稳态

    FPGA(Field-Programmable Gate Array),即现场可编程门阵列.主要是利用内部的可编程逻辑实现设计者想要的功能.FPGA属于数字逻辑芯片,其中也有可能会集成一部分模拟电路的 ...

  9. git安装和git命令:全局设置用户名邮箱配置

    在网上下载并安装git:https://git-scm.com/downloads在开始菜单里面找到 "Git --> Git Bash",如下 运行Git Bash: 如果 ...

  10. ctf_web

    ctfshow web13 访问题目链接 一看是一道文件上传题,上传文件进行测试 上传php会显示 error suffix 因此推测会检测格式 当文件字数超出一定字数时,显示 error file ...