【问题标题】:Cassandra : memory consumption while compactingCassandra:压缩时的内存消耗
【发布时间】:2021-12-28 00:12:37
【问题描述】:

我有 ParNew GC 警告到 system.log 超过 8 秒暂停:

WARN  [Service Thread] GCInspector.java:283 - ParNew GC in 8195ms.  CMS Old Gen: 22316280488 -> 22578261416; Par Eden Space: 1717787080 -> 0; Par Survivor Space: 123186168 -> 214695936

它似乎出现在特定 table 上发生轻微压缩时:

92128ed0-46fe-11ec-bf5a-0d5dfeeee6e2 ks table 1794583380  1754598812  {1:92467, 2:5291, 3:22510}                                                                  
f6e3cd30-46fc-11ec-bf5a-0d5dfeeee6e2 ks table 165814525   160901558   {1:3196, 2:24814}                                                                           
334c63f0-46fc-11ec-bf5a-0d5dfeeee6e2 ks table 126097876   122921938   {1:3036, 2:24599}       

桌子:

  • 配置了LCS策略。
  • 平均行大小为1MB
  • 还有一些宽行,最多60MB(来自cfhistograms,不知道它是否包括应用于该行的LZ4压缩?)。

heap size 为 32GB。

问题:

一个。在压缩过程中必须有多少行(一次!)放入内存?它只是一个,还是多个?

b.压缩时,每个分区是在decompressed form 中读入内存,还是在compressed form 中?

c。你认为我的压缩过程会填满所有的堆内存吗?

谢谢

完整的 GC 设置:

-Xms32G
-Xmx32G
#-Xmn800M
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+CMSParallelRemarkEnabled
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=1
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSWaitDuration=10000
-XX:+CMSParallelInitialMarkEnabled
-XX:+CMSEdenChunksRecordAlways

【问题讨论】:

  • 你用的是G1吗?
  • 不,CMS/ParNew 书面 :)
  • 我确实看到了“ParNew”,但后来我也看到了 32GB 堆,所以我想澄清一下。 NewGen 大小设置为多少?
  • 嗨。我已经更新了我的帖子。 Xmn 未设置。你有足够的信息来回答吗?

标签: cassandra datastax datastax-enterprise


【解决方案1】:

一个。在压缩过程中必须有多少行(一次!)放入内存?它只是一个,还是多个?

肯定是多个。

b.压缩时,每个分区是以解压形式读入内存,还是以压缩形式读入?

压缩仅适用于磁盘级别。在 compaction 可以对它做任何事情之前,它需要解压缩并读取它。

c。你认为我的压缩过程会填满所有的堆内存吗?

是的,压缩过程分配了大量的堆,运行压缩会导致已经紧张的堆出现问题。

TBH,我发现列出的 GC 设置有几个改进的机会。而现在,我认为这就是大多数问题所在。让我们从新的一代尺寸开始:

#-Xmn800M

使用 CMS,您绝对需要明确说明您的堆新大小 (Xmn)。特别是有一个巨大的堆。是的,CMS 32GB 是“巨大的”。每个 CPU 核心 100MB 的智慧是不正确的。使用 Cassandra,堆的新大小应该在最大堆大小 (Xmx) 的 25% 到 50% 之间。对于 32GB,我会说取消注释 Xmn 行并将其设置为 -Xmn12G

以下是 CMS 的内存映射方式:

现在让我们看看这两个:

-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=1

按线性布局,堆分为新生代/年轻代、老年代和永久代。跨代推广(例如:从新世代到旧世代)发生重大的、世界级的收藏。

在新生代中,它被分为伊甸园空间和幸存者空间S0和S1。您想要的是让您的所有对象在新一代空间中被创建、生存和消亡。为此,MaxTenuringThreshold(一个对象可以在幸存者空间之间复制多少次)需要更高。此外,幸存者空间需要足够大以减轻它们的重量。以 1:8 的比例,每个幸存者空间将是伊甸园空间的 1/8。所以我会选择这些,只是开始:

-XX:SurvivorRatio=2
-XX:MaxTenuringThreshold=6

这将使幸存者空间更大,并允许对象在它们之间传递 6 次。希望这段时间足够长,可以避免宣传它们。

添加这些也会有所帮助:

-XX:+AlwaysPreTouch
-XX:+UseTLAB
-XX:+ResizeTLAB
-XX:-UseBiasedLocking

有关这些 ^ 的更多信息,请查看Amy's Cassandra 2.1 Tuning Guide。但是对于 Cassandra,您确实希望“预接触”,您确实希望启用线程本地分配块 (TLAB),您确实希望这些块能够调整大小,并且您不希望有偏向锁定。

选择一个节点,进行这些更改,重新启动并监控性能。如果他们有帮助(我认为他们会),也将它们添加到剩余的节点中。

tl;dr;

我会做出这些改变:

-Xmn12G
-XX:SurvivorRatio=2
-XX:MaxTenuringThreshold=6
-XX:+AlwaysPreTouch
-XX:+UseTLAB
-XX:+ResizeTLAB
-XX:-UseBiasedLocking

参考资料:

  • CASSANDRA-8150 - 更改默认 JVM 设置的最终失败尝试。但随后的讨论产生了 JVM 调优智慧的最佳汇编之一。
  • Amy's Cassandra 2.1 Tuning Guide - 它可能已经过时了,但这仍然是 Cassandra 最全面的管理指南之一。讨论的许多设置和方法仍然非常相关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 2010-10-27
    • 2011-12-13
    • 2011-10-03
    相关资源
    最近更新 更多