CMS 后的 Cassandra OOM 使新世代为空

Posted

技术标签:

【中文标题】CMS 后的 Cassandra OOM 使新世代为空【英文标题】:Cassandra OOM after CMS makes new gens empty 【发布时间】:2019-03-14 20:35:16 【问题描述】:

我的 cassandra 集群有 6 个节点,但到目前为止,其中 5 个节点因 OOM 导致的 map failed 而宕机。 在此之前,CMS 会抛出一个 WARN 日志,并且 new-gen 变得完全为空。这不是典型的 CMS 行为,但我不知道发生了什么。

警告 [服务线程] 2018-10-03 23:47:34,510 GCInspector.java:282 - ConcurrentMarkSweep GC 在 4748 毫秒内。 CMS 老一代:4311229160 -> 1434360152; Par Eden 空间:215565624 -> 0;标准生存空间:6320160 -> 0

我使用 Cassandra 3.9,Java 堆大小为 8GB。我没有修改任何 jvm 选项。 接下来我应该如何检查?

这是 system.log 的摘要。

WARN  [Service Thread] 2018-09-22 16:56:28,089 GCInspector.java:282 - ConcurrentMarkSweep GC in 3926ms.  CMS Old Gen: 1768828144 -> 1173494472; Par Eden Space: 68469544 -> 0; Par Survivor Space: 9587608 -> 0    
ERROR [CompactionExecutor:89253] 2018-09-22 16:56:28,311  CassandraDaemon.java:226 - Exception in thread Thread[CompactionExecutor:89253,1,main]    
org.apache.cassandra.io.FSReadError: java.io.IOException: Map failed
Caused by: java.io.IOException: Map failed
Caused by: java.lang.OutOfMemoryError: Map failed
WARN  [GossipTasks:1] 2018-09-22 16:56:38,185 FailureDetector.java:287 - Not marking nodes down due to local pause of 9094437652 > 5000000000
INFO  [CompactionExecutor:89253] 2018-09-22 16:56:38,190 HeapUtils.java:136 - Dumping heap to /cassandra/java_1521034957.hprof ...
Heap dump file created

ERROR [CompactionExecutor:89253] 2018-09-22 16:56:43,305 JVMStabilityInspector.java:141 - JVM state determined to be unstable.  Exiting forcefully due to:
java.lang.OutOfMemoryError: Map failed

【问题讨论】:

您的系统有多少可用内存? 【参考方案1】:

强烈建议 Cassandra 使用 G1GC 而不是 CMS。

为了将 G1 设置为 Java 垃圾收集器

打开 jvm.options。 注释掉 -Xmn800M 行。 注释掉### CMS 设置部分中的所有行。 取消注释中的相关 G1 设置

G1 设置部分:使用热点垃圾优先收集器。 -XX:+使用G1GC

让 JVM 在 STW 期间做更少的记忆集合工作,而不是 更喜欢并发GC。减少 p99.9 延迟。 -XX:G1RSetUpdatingPauseTimePercent=5

Reference设置G1GC

【讨论】:

【参考方案2】:

这看起来您的系统正在抛出 OutOfMemory 异常(包括启动堆转储)。默认情况下,堆外直接字节缓冲区将分配到您的堆大小 - 所以另外 8gb。如果您的节点没有超过 16GB 的空间,您可能会遇到限制。您的直接字节缓冲区也可能超出可以使用-XX:MaxDirectMemorySize=12G 增加的缓冲区(如果您有超过 16gb)。确保您的内核设置也配置了 /etc/sysctl.conf 中的 vm.max_map_count = 1000000 和 nproc 到 32768 memlock 无限制等。Datastax 在 here 提供了与 Cassandra 相关的很好的建议。

【讨论】:

以上是关于CMS 后的 Cassandra OOM 使新世代为空的主要内容,如果未能解决你的问题,请参考以下文章

Cassandra - JVM OOM直接缓冲区错误

一次java进程fork大量子进程导致OOM的解决方案

启用 stomp 后的 activemq oom

ScyllaDB:用 C++ 重写后的 Cassandra ,性能提高了十倍

带有 SearchView 的 UITableView 使新单元格在搜索时与旧单元格重叠

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