Cassandra:压缩时的内存消耗
Cassandra : memory consumption while compacting
我在 system.log
中收到 ParNew GC
警告,暂停时间超过 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}
table :
- 配置了
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
a. how many rows must fit into memory (at once!) during compaction process ? It is just one, or more ?
肯定是多个
b. while compacting, does each partition is read in decompressed form into memory, or in compressed form ?
压缩仅适用于磁盘级别。在压缩可以对其进行任何操作之前,它需要解压缩并读取它。
c. do you think the compaction process in my case could fill up all the heap memory ?
是的,压缩过程会分配大量堆,运行 压缩会导致已经紧张的堆出现问题。
TBH,我看到了几个改进列出的 GC 设置的机会。而现在,我认为这就是大多数问题所在。让我们从新一代尺寸开始:
#-Xmn800M
使用 CMS,您绝对需要明确您的堆新大小 (Xmn
)。特别是有一个巨大的堆。是的,对于 CMS,32GB 是“巨大的”。每个 CPU 核心智慧 100MB 是不正确的。对于 Cassandra,新堆大小应在最大堆大小 (Xmx
) 的 25% 到 50% 范围内。对于 32GB,我会说取消注释 Xmn
行并将其设置为 -Xmn12G
.
下面是为 CMS 映射内存的方式:
现在让我们看看这两个:
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=1
线性布局,堆分为 new/young 代、老年代和永久代。主要,stop-the-world collections 发生在 inter-generational 晋升(例如:新世代到旧世代)。
在新世代中,它分为伊甸园space和幸存者spaceS0和S1。你想要的,是你所有的 object 都在新一代 space 中被创造、生存和死亡。为此,MaxTenuringThreshold
(object 可以在幸存者 space 之间复制多少次)需要更高。此外,幸存者 space 需要足够大才能承受重量。以 1:8 的比率,每个幸存者 space 将是伊甸园 space 的 1/8。所以我会选择这些,只是为了开始:
-XX:SurvivorRatio=2
-XX:MaxTenuringThreshold=6
这将使幸存者 spaces 变大,并允许 objects 在它们之间传递 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 管理指南之一。讨论的许多设置和方法仍然非常相关。
我在 system.log
中收到 ParNew GC
警告,暂停时间超过 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}
table :
- 配置了
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
a. how many rows must fit into memory (at once!) during compaction process ? It is just one, or more ?
肯定是多个
b. while compacting, does each partition is read in decompressed form into memory, or in compressed form ?
压缩仅适用于磁盘级别。在压缩可以对其进行任何操作之前,它需要解压缩并读取它。
c. do you think the compaction process in my case could fill up all the heap memory ?
是的,压缩过程会分配大量堆,运行 压缩会导致已经紧张的堆出现问题。
TBH,我看到了几个改进列出的 GC 设置的机会。而现在,我认为这就是大多数问题所在。让我们从新一代尺寸开始:
#-Xmn800M
使用 CMS,您绝对需要明确您的堆新大小 (Xmn
)。特别是有一个巨大的堆。是的,对于 CMS,32GB 是“巨大的”。每个 CPU 核心智慧 100MB 是不正确的。对于 Cassandra,新堆大小应在最大堆大小 (Xmx
) 的 25% 到 50% 范围内。对于 32GB,我会说取消注释 Xmn
行并将其设置为 -Xmn12G
.
下面是为 CMS 映射内存的方式:
现在让我们看看这两个:
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=1
线性布局,堆分为 new/young 代、老年代和永久代。主要,stop-the-world collections 发生在 inter-generational 晋升(例如:新世代到旧世代)。
在新世代中,它分为伊甸园space和幸存者spaceS0和S1。你想要的,是你所有的 object 都在新一代 space 中被创造、生存和死亡。为此,MaxTenuringThreshold
(object 可以在幸存者 space 之间复制多少次)需要更高。此外,幸存者 space 需要足够大才能承受重量。以 1:8 的比率,每个幸存者 space 将是伊甸园 space 的 1/8。所以我会选择这些,只是为了开始:
-XX:SurvivorRatio=2
-XX:MaxTenuringThreshold=6
这将使幸存者 spaces 变大,并允许 objects 在它们之间传递 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 管理指南之一。讨论的许多设置和方法仍然非常相关。