首页 > 解决方案 > 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。

标签: memory-managementcassandraheap-memory

解决方案


除了堆内存,Cassandra 还使用堆外内存,例如用于保存压缩元数据、布隆过滤器和其他一些东西。从文档(12):

压缩元数据存储在堆外并随磁盘上的数据扩展。这通常需要磁盘上每 TB 数据 1-3GB 的堆外 RAM,尽管确切的使用量因 chunk_length_in_kb 和压缩比而异。

布隆过滤器存储在 RAM 中,但存储在堆外,因此运营商在选择最大堆大小时不应考虑布隆过滤器。

例如,您可以使用 JMX监控堆和堆外内存使用情况。(我见过一些设置,仅布隆过滤器就占用了大约 40Gb 的 RAM,但它在很大程度上取决于唯一分区键的数量)

通常不建议使用太大的堆,因为它们可能会使用长暂停等。这当然取决于工作负载,但您可以尝试 31Gb 或更低(或仅使用默认设置)。另外,您需要为 Linux 文件缓冲区留出内存,以便它缓存经常使用的文件。这就是为什么默认情况下 Cassandra 只为堆分配 1/4 的系统内存的原因。


推荐阅读