实战经验 | Cassandra Java堆外内存排查经历全记录

本文涉及的产品
性能测试 PTS,5000VUM额度
简介: 记一次Cassandra Java堆外内存排查经历

背景

最近准备上线cassandra这个产品,同事在做一些小规格ECS(8G)的压测。压测时候比较容易触发OOM Killer,把cassandra进程干掉。问题是8G这个规格我配置的heap(Xmx)并不高(约6.5g)已经留出了足够的空间给系统。只有可能是Java堆外内存使用超出预期,导致RES增加,才可能触发OOM。

调查过程

0.初步怀疑是哪里有DirectBuffer泄漏,或者JNI库的问题。
1.按惯例通过google perftools追踪堆外内存开销,但是并未发现明显的异常。
2.然后用Java NMT 看了一下,也没有发现什么异常。

1.jpeg

3.查到这里思路似乎断了,因为跟DirectBuffer似乎没啥关系。这时候我注意到进程虚拟内存非常高,已经超过ECS内存了。怀疑这里有些问题。

2.jpeg

4.进一步通过/proc/pid/smaps 查看进程内存地址空间分布,发现有大量mmap的文件。这些文件是cassandra的数据文件。

33.jpeg

此时这些mmap file 虚拟内存是2G,但是物理内存是0(因为我之前重启过,调低过内存防止进程挂掉影响问题排查)。

显然mmap的内存开销是不受JVM heap控制的,也就是堆外内存。如果mmap的文件数据被从磁盘load进物理内存(RES增加),Java NMT和google perftool是无法感知的,这是kernel的调度过程。

5.考虑到是在压测时候出现问题的,所以我只要读一下这些文件,观察下RES是否会增加,增加多少,为啥增加,就能推断问题是不是在这里。通过下面的命令简单读一下之前导入的数据。

cassandra-stress read duration=10m cl=ONE -rate threads=20 -mode native cql3 user=cassandra password=123 -schema keysp
ace=keyspace5 -node core-3

6.可以观察到压测期间(sar -B),major page fault是明显上升的,因为数据被实际从磁盘被load进内存。
4.jpeg

同时观察到mmap file物理内存增加到20MB:
5.jpeg

最终进程RES涨到7.1g左右,增加了大约600M:

6.jpeg

如果加大压力(50线程),还会涨,每个mmap file物理内存会从20MB,涨到40MB

7.Root cause是cassandra识别系统是64还是32来确定要不要用mmap,ECS都是64,但是实际上小规格ECS内存并不多。

7.jpeg

结论

1.问题诱因是mmap到内存开销没有考虑进去,具体调整方法有很多。可以针对小规格ECS降低heap配置或者关闭mmap特性(disk_access_mode=standard)

2.排查Java堆外内存还是比较麻烦的,推荐先用NMT查查,用起来比较简单,配置JVM参数即可,可以看到内存申请情况。

相关实践学习
快速体验PolarDB开源数据库
本实验环境已内置PostgreSQL数据库以及PolarDB开源数据库:PolarDB PostgreSQL版和PolarDB分布式版,支持一键拉起使用,方便各位开发者学习使用。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7天前
|
安全 Java 程序员
《从头开始学java,一天一个知识点》之:控制流程:if-else条件语句实战
**你是否也经历过这些崩溃瞬间?** - 看了三天教程,连`i++`和`++i`的区别都说不清 - 面试时被追问"`a==b`和`equals()`的区别",大脑突然空白 - 写出的代码总是莫名报NPE,却不知道问题出在哪个运算符 这个系列为你打造Java「速效救心丸」!每天1分钟,地铁通勤、午休间隙即可完成学习。直击高频考点和实际开发中的「坑位」,拒绝冗长概念,每篇都有可运行的代码示例。明日预告:《for与while循环的使用场景》。 ---
51 19
|
4天前
|
存储 缓存 算法
JVM简介—1.Java内存区域
本文详细介绍了Java虚拟机运行时数据区的各个方面,包括其定义、类型(如程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和直接内存)及其作用。文中还探讨了各版本内存区域的变化、直接内存的使用、从线程角度分析Java内存区域、堆与栈的区别、对象创建步骤、对象内存布局及访问定位,并通过实例说明了常见内存溢出问题的原因和表现形式。这些内容帮助开发者深入理解Java内存管理机制,优化应用程序性能并解决潜在的内存问题。
JVM简介—1.Java内存区域
|
4天前
|
存储 运维 监控
使用阿里云操作系统控制台排查内存溢出
操作系统控制台是阿里云最新推出的一款智能运维工具,专为提升运维效率、优化服务器管理而设计。它集成了多种运维管理功能,包括操作系统助手、插件管理器以及其他实用工具,为用户提供一站式的运维解决方案。无论是个人开发者还是企业运维团队,都可以通过这一平台轻松管理服务器和操作系统。
47 18
 使用阿里云操作系统控制台排查内存溢出
|
1天前
|
消息中间件 Java 应用服务中间件
JVM实战—1.Java代码的运行原理
本文介绍了Java代码的运行机制、JVM类加载机制、JVM内存区域及其作用、垃圾回收机制,并汇总了一些常见问题。
JVM实战—1.Java代码的运行原理
|
8天前
|
存储 Java 编译器
课时11:综合实战:简单Java类
本次分享的主题是综合实战:简单 Java 类。主要分为两个部分: 1.简单 Java 类的含义 2.简单 Java 类的开发
|
8天前
|
Oracle Java 关系型数据库
课时37:综合实战:数据表与简单Java类映射转换
今天我分享的是数据表与简单 Java 类映射转换,主要分为以下四部分。 1. 映射关系基础 2. 映射步骤方法 3. 项目对象配置 4. 数据获取与调试
|
16天前
|
存储 IDE Java
java设置栈内存大小
在Java应用中合理设置栈内存大小是确保程序稳定性和性能的重要措施。通过JVM参数 `-Xss`,可以灵活调整栈内存大小,以适应不同的应用场景。本文介绍了设置栈内存大小的方法、应用场景和注意事项,希望能帮助开发者更好地管理Java应用的内存资源。
29 4
|
2月前
|
存储 缓存 Java
Java中的分布式缓存与Memcached集成实战
通过在Java项目中集成Memcached,可以显著提升系统的性能和响应速度。合理的缓存策略、分布式架构设计和异常处理机制是实现高效缓存的关键。希望本文提供的实战示例和优化建议能够帮助开发者更好地应用Memcached,实现高性能的分布式缓存解决方案。
50 9
|
21天前
|
Java Shell 数据库
【YashanDB 知识库】kettle 同步大表提示 java 内存溢出
【问题分类】数据导入导出 【关键字】数据同步,kettle,数据迁移,java 内存溢出 【问题描述】kettle 同步大表提示 ERROR:could not create the java virtual machine! 【问题原因分析】java 内存溢出 【解决/规避方法】 ①增加 JVM 的堆内存大小。编辑 Spoon.bat,增加堆大小到 2GB,如: if "%PENTAHO_DI_JAVA_OPTIONS%"=="" set PENTAHO_DI_JAVA_OPTIONS="-Xms512m" "-Xmx512m" "-XX:MaxPermSize=256m" "-
|
3月前
|
Java
Java基础却常被忽略:全面讲解this的实战技巧!
本次分享来自于一道Java基础的面试试题,对this的各种妙用进行了深度讲解,并分析了一些关于this的常见面试陷阱,主要包括以下几方面内容: 1.什么是this 2.this的场景化使用案例 3.关于this的误区 4.总结与练习

热门文章

最新文章