我在aws上有一个9节点的集群。最近,一些节点出现故障,我想在重新启动之后修复集群。但是我发现修复操作导致大量的memtable刷新,然后jvmgc失败。因此,节点挂起。
我使用的是Cassandra3.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)
节点硬件为32gbmem和4核cpu。堆是16gb。对于每个节点,大约有200gbsstables。
jvm挂起的速度非常快。维修过程开始后,一切正常。我检查了内存,cpu和io。未发现应力。在随机时间(流任务正在完成)之后,memtableflushwriter挂起的任务增长非常快,然后gc失败。jvm挂起和heapdump被创建。当问题发生时,cpu的使用率很低,我在aws ebs磁盘度量上找不到i/o延迟。
我检查了堆转储文件。有几个大的memtables对象的表修复。memtable对象的大小约为400-700mb。而memtables是在20秒内创建的。此外,我可以看到12000多个内存表。在这些memtables中,有6000个sstable\活动memtables。
首先,我怀疑memtable flush writer是瓶颈。所以我把它增加到4个线程。我把节点的内存增加了一倍。但它不起作用。在修复过程中,挂起的任务迅速增加,节点再次挂起。我还减少了修复令牌范围,只有一个vnode,但仍然失败。
我们可以看到一些这样的日志
WARN [STREAM-IN-/10.0.113.12:7000] 2020-04-02 05:05:57,150 BigTableWriter.java:211 - Writing large partition ....
写sstables有300-500mbs。一些大的达到2+gb。
我看了Cassandra的源代码。我发现,如果表具有物化视图,则必须在正常的写入过程中处理sstables。所以我怀疑这个问题发生在流媒体的完整阶段。
流式传输之后,receive回调函数加载更新的分区sstables,并像正常写入一样创建变异。所以它增加了堆中的memtables。此外,它还调用flush(),这将在修复的表之外创建额外的memtables。memtables大小超过清除阈值。所以叫做同花顺。但是冲水不能释放足够的记忆。很多次同花顺的电话。另一方面,刷新也会增加内存表。
有人遇到同样的问题吗?如果我的结论是正确的,如何修正它?
1条答案
按热度按时间exdqitrt1#
cassandra中的repair不使用memtable-它使用与节点引导等相同的流机制。但是如果您有大分区,并且它们被损坏,那么cassandra将需要发送它们,并且在接收器端它将需要构建辅助结构,你可以在下面的博客文章中找到更多关于修复可能出现的问题的信息。
一种可能的解决方案是使用范围修复,因此您只能检查令牌环的特定部分。但手动完成这项工作是一项乏味的任务,所以最好使用像cassandra reaper这样的工具来自动化这个过程。