【问题标题】:Cassandra node JVM hang during node repair a table with materialized viewCassandra 节点 JVM 在节点修复具有物化视图的表期间挂起
【发布时间】:2020-07-16 17:10:07
【问题描述】:

我在 AWS 上有一个 9 个节点的集群。最近有些节点宕机了,我想重启后修复集群。但是我发现修复操作会导致大量的 memtable 刷新,然后 JVM GC 失败。因此,节点挂起。

我使用的是 cassandra 3.1.0。

java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b32)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b32, mixed mode)

节点硬件为 32GB 内存和 4 核 CPU。堆为 16GB。对于每个节点,大约 200 GB sstables。

JVM 挂起非常快。修复过程开始后,一切正常。我检查了内存、cpu 和 IO。没有发现压力。随机时间后(流式任务完成),memtableflushwriter 挂起任务增长非常快,然后 GC 失败。 JVM 挂起并创建了堆转储。问题发生时,CPU 使用率较低,并且我在 AWS EBS 磁盘指标上找不到 I/O 延迟。

我检查了堆转储文件。表修复有几个大的memtables对象。 memtable 对象大小约为 400 - 700MB。并且 memtables 在 20 秒内创建。另外,我可以看到超过 12000 个 memtables。在这些 memtables 中,有 6000 个 sstable_activity memtables。

起初,我怀疑 memtable 刷新写入器是瓶颈。所以我把它增加到4个线程。我将节点的内存加倍。但它不起作用。在修复过程中,挂起的任务增加很快,然后节点再次挂起。我还减少了修复令牌范围,只有一个 vnode,但仍然失败。

我们可以看到一些这样的日志

WARN [STREAM-IN-/10.0.113.12:7000] 2020-04-02 05:05:57,150 BigTableWriter.java:211 - Writing large partition ....

写入 sstable 有 300 - 500 MB。一些大的达到 2+ GB。

我浏览了 cassandra 源代码。而且我发现如果表具有物化视图,则必须在正常写入过程中处理 sstables。所以我怀疑这个问题发生在流媒体的 COMPLETE 阶段。

流式传输后,接收回调函数加载更新的分区 sstables 并像正常写入一样创建突变。所以它增加了堆中的内存表。此外,它还调用flush(),这将在修复的表之外创建额外的memtables。内存表大小超过清理阈值。所以叫冲洗。但是刷新不能释放足够的内存。这么多次同花跟注。另一方面,flush 也会增加内存表。

那么有人遇到同样的问题吗?如果我的结论是正确的,如何解决?

【问题讨论】:

    标签: cassandra cassandra-3.0 cassandra-stress


    【解决方案1】:

    Cassandra 中的修复不使用 memtable - 它使用用于引导节点等的相同流机制。但是如果您有大分区并且它们已损坏,那么 Cassandra 将需要发送它们,并且在接收端,它将需要构建辅助结构等。您可以在following blog post 中找到有关修复可能出现的问题的更多信息。

    一种可能的解决方案是使用范围修复,因此您只能检查令牌环的特定部分。但手动执行此操作是一项繁琐的任务,因此最好使用Cassandra Reaper 之类的工具来自动执行此过程。

    【讨论】:

    • 谢谢。我使令牌范围非常小。但问题仍然在这里。我阅读了源代码,似乎问题是由物化视图引起的。如果表有视图,sstable 将通过正常的写入路径进行处理。
    猜你喜欢
    • 1970-01-01
    • 2015-05-20
    • 2019-08-22
    • 2019-08-29
    • 2022-01-24
    • 2019-05-28
    • 2015-03-06
    • 2020-07-12
    • 1970-01-01
    相关资源
    最近更新 更多