【问题标题】:Cassandra repair failing because of GC由于 GC,Cassandra 修复失败
【发布时间】:2017-05-05 17:27:55
【问题描述】:

我们有一个 9 个节点的集群,并按照建议每晚进行维修(每晚 1 个节点)。

我们最近在修复过程中开始遇到问题,一些节点会因为 GC 收集速度不够快而死掉 OutOfMemory。一开始是升级问题(如详细的 GC 日志所示)。

因此我们假设 CMS 的触发速度不够快,并阻止 ParNew 提升存活对象。然后将 XX:CMSInitiatingOccupancyFraction 从 75 降低到 50 以强制旧 GC 更快地触发。

好像可以,但是昨天有两个节点死掉了,因为 GC 无法应付分配速度,产生了这样的日志:

INFO [ScheduledTasks:1] 2013-09-27 23:36:38,111 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 21756 ms for 1 collections, 8003258240 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:36:38,878 GCInspector.java (line 142) Heap is 0.9746211436302873 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:36:57,018 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 17265 ms for 1 collections, 6587223560 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:36:57,243 GCInspector.java (line 142) Heap is 0.802179208376459 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:37:18,180 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 18437 ms for 1 collections, 6961687392 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:37:18,785 GCInspector.java (line 142) Heap is 0.8477806818323523 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:37:40,416 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 19032 ms for 1 collections, 7338693168 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:37:40,456 GCInspector.java (line 142) Heap is 0.893691708259552 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:38:02,994 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 18853 ms for 1 collections, 7570047632 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:38:03,008 GCInspector.java (line 142) Heap is 0.9218656026318086 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:38:26,110 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 19564 ms for 1 collections, 7714594464 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:38:26,132 GCInspector.java (line 142) Heap is 0.9394682332713986 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:38:49,733 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 20388 ms for 1 collections, 7843428464 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:38:49,748 GCInspector.java (line 142) Heap is 0.9551573859456055 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:39:14,564 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 20956 ms for 1 collections, 7934286376 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:39:14,578 GCInspector.java (line 142) Heap is 0.9662218848591505 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:39:40,186 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 22440 ms for 1 collections, 8008275464 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:39:40,915 GCInspector.java (line 142) Heap is 0.9752321313612954 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:40:01,836 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 19911 ms for 1 collections, 8022614576 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:40:06,032 GCInspector.java (line 142) Heap is 0.976978320390438 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [ScheduledTasks:1] 2013-09-27 23:40:27,407 GCInspector.java (line 119) GC for ConcurrentMarkSweep: 22590 ms for 1 collections, 8058828880 used; max is 8211660800
WARN [ScheduledTasks:1] 2013-09-27 23:40:31,091 GCInspector.java (line 142) Heap is 0.9813884275395302 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
INFO [GossipTasks:1] 2013-09-27 23:40:53,798 Gossiper.java (line 799) InetAddress /<datacenter02>.<node2> is now DOWN
INFO [GossipTasks:1] 2013-09-27 23:40:53,846 Gossiper.java (line 799) InetAddress /<datacenter01>.<node3> is now DOWN
INFO [GossipStage:1] 2013-09-27 23:40:53,857 Gossiper.java (line 785) InetAddress /<datacenter01>.<node3> is now UP
INFO [GossipStage:1] 2013-09-27 23:40:53,909 Gossiper.java (line 785) InetAddress /<datacenter02>.<node2> is now UP

这一次堆变大了,GC 运行了 10-20 秒,没有减小堆大小,导致节点认为彼此宕机,因为它们正忙于 GC。最终节点死于OOM。

然后我们尝试更新到最新版本的 Cassandra (1.2.8 -> 1.2.10),尽管这些版本中没有修复的错误表明我们的问题有任何改进。然后我们在昨晚重新进行了修复,但是即使没有节点崩溃,由于这种 GC,它们也无法修复某些范围:

INFO [ScheduledTasks:1] 2013-09-29 04:45:05,467 GCInspector.java (line 119) GC for ParNew: 22875 ms for 2 collections, 4128819328 used; max is 8211660800
INFO [ScheduledTasks:1] 2013-09-29 04:53:24,597 GCInspector.java (line 119) GC for ParNew: 133643 ms for 2 collections, 3102634584 used; max is 8211660800

这次是 ParNew 花费了可笑的时间。

我首先想到的是负载问题,但在 w-e 期间仅进行修复时它继续发生。

我们将不胜感激诊断/解决我们的问题。

【问题讨论】:

  • 查看堆转储以了解内存的去向:eclipse.org/mat
  • 另外,StatusLogger 开始出现问题时会说什么?
  • 关于堆转储,不幸的是它们不适合驱动器并且无法完全转储。关于日志,这里有一个带有 StatusLogger 的 Pastebin 链接,它发生在一个长 GC pastebin.com/gkcCnXGy 周围
  • @jbellis 我应该在 Cassandra 的 JIRA 上提交错误还是您认为这更像是配置问题?

标签: garbage-collection jvm cassandra


【解决方案1】:

StatusLogger 信息没有显示任何异常,除了 GC 需要一段时间。 (您是否在 VM 上运行?这往往会降低 GC 性能:http://www.slideshare.net/eonnen/high-performance-network-programming-on-the-jvm-oscon-2012/62。)

我的猜测:修复给系统增加了足够的负载,以至于它落后于处理请求并花费过多的内存来缓冲它们。您可以通过在日志中查找“丢弃”消息来验证这一点。默认情况下,它将缓冲 10 秒的请求;为了减少这种情况,请降低 cassandra.yaml 中适当的 rpc 超时。

【讨论】:

  • 我们没有在虚拟机上运行。关于缓冲的想法,我不相信,因为这也发生在我们几乎没有活动的周末。无论如何,JVM更新后的第一次修复仍然很长,但之后一切恢复正常。我不相信更新解决了我们的问题,我认为它现在已关闭,但请留意服务器。感谢您的帮助。
【解决方案2】:

尝试使用 G1 GC 而不是 CMS。 G1 不会那样停顿:

https://docs.datastax.com/en/cassandra/3.0/cassandra/operations/opsTuneJVM.html

【讨论】:

    猜你喜欢
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 2017-10-15
    • 2022-07-06
    • 2023-03-17
    • 2018-11-01
    相关资源
    最近更新 更多