memory-management - Cassandra java 进程使用的内存超过其分配的最大堆大小 (Xmx)
问题描述
我们有我们的 cassandra 集群,它在一组 unix 主机 (18) 中运行 Apache Cassandra 3.11.4。这些主机中的每一个都有 96G 的 RAM,我们已将堆大小配置为 -Xms=64G -Xmx=64G 但主机上的顶部命令(top -M)显示实际内存利用率平均约为 85G,即远高于分配的堆( 64G)。
内存使用的趋势是,在 cassandra 守护进程启动期间,top -M 显示该进程已经占用了 ~75G,其中 (75G-64G)=9G 超过分配的堆大小,并且此内存使用率随着时间的推移而增加并达到最大值85G 只需 3-4 小时,并且一直保持在那个阶段,而堆利用率(~40-50%)是正常的,GS 活动很正常,次要 GC 照常启动。
已确认所有键空间使用的总堆外内存在每台主机上低于 2G。
除了分配的堆外,我们无法追踪还有什么正在消耗 RAM。
解决方案
除了堆内存,Cassandra 还使用堆外内存,例如用于保存压缩元数据、布隆过滤器和其他一些东西。从文档(1、2):
压缩元数据存储在堆外并随磁盘上的数据扩展。这通常需要磁盘上每 TB 数据 1-3GB 的堆外 RAM,尽管确切的使用量因 chunk_length_in_kb 和压缩比而异。
布隆过滤器存储在 RAM 中,但存储在堆外,因此运营商在选择最大堆大小时不应考虑布隆过滤器。
例如,您可以使用 JMX监控堆和堆外内存使用情况。(我见过一些设置,仅布隆过滤器就占用了大约 40Gb 的 RAM,但它在很大程度上取决于唯一分区键的数量)
通常不建议使用太大的堆,因为它们可能会使用长暂停等。这当然取决于工作负载,但您可以尝试 31Gb 或更低(或仅使用默认设置)。另外,您需要为 Linux 文件缓冲区留出内存,以便它缓存经常使用的文件。这就是为什么默认情况下 Cassandra 只为堆分配 1/4 的系统内存的原因。
推荐阅读
- mysql - 将子字符串值插入到已经存在的条目中
- typescript - 带有 vscode 的打字稿路径在 ctrl 单击时解析错误
- apache-spark - Pyspark:java.lang.IllegalArgumentException:HOUR_OF_DAY:0 -> 1
- amazon-web-services - 使用 terraform 将 AWS 备份还原到 RDS
- flutter - Flutter中不同的元素位置
- pdf - 将可填写的 pdf 嵌套到新的 pdf 文档中
- r - ggplot 多列(一些列有很多 NaN),在 r 的一个图中带有线和点
- spring-boot - Spring Cloud Config Server 无法使用 SSH 克隆私有 Git 存储库
- java - JsonIgnore 除了一个端点
- json - AWS Spectrum 扫描错误压缩文件意外结束