2016-07-07 120 views
6

我在24个节点集群中运行Cassandra 3.7,每个节点有3个数据中心和256个vnodes,每个节点使用cron作业每天运行一次“nodetool repair -pr”与其他节点不同的一小时。同时修复导致修复挂起

有时修理需要一个多小时才能完成并且修理重叠。发生这种情况时,修复开始出现异常,并可能处于不良状态。这会导致级联故障,其中每个小时另一个节点将尝试启动修复,并且它也会挂起。

从此恢复很困难。我发现的唯一方法是不仅重新启动停滞不前的节点,而且还重新启动集群中的所有节点。

我唯一的想法就是建立某种服务,检查是否有任何其他节点在开始修复之前正在运行修复,可能是在修复过程中发布在Cassandra表中。

我不知道如果集群变得更大,我将如何修复所有节点,因为那里很快就没有足够的时间在一天中的所有节点上运行修复。

所以我的主要问题是,我运行修复不正确以及建议如何定期修复大型集群的所有节点?

有没有办法一次修复多个节点?该文件暗示存在,但不清楚如何做到这一点。一次在多个节点上运行修复会导致崩溃和烧伤,这是否正常?有没有比重新启动所有节点更简单的方法来终止卡住的维修?

有些事情我想:

  1. 运行“nodetool修”,而不-PR,但如果同时对 多个节点上运行,这也挂起。
  2. 正在运行“nodetool repair -dcpar” - 这个 似乎修复了它在所有数据中心上运行的节点所拥有的令牌范围,但是如果一次在多个节点上运行,它也会挂起。

我的keyspace每个数据中心只保留一个副本,所以我不认为我可以使用-local选项。

一些我看的时候修复挂起是例外的:

ERROR [ValidationExecutor:4] 2016-07-07 12:00:31,938 CassandraDaemon.java (line 227) Exception in thread Thread[ValidationExecutor:4,1,main] 
java.lang.NullPointerException: null 
     at org.apache.cassandra.service.ActiveRepairService$ParentRepairSession.getActiveSSTables(ActiveRepairService.java:495) ~[main/:na] 
     at org.apache.cassandra.service.ActiveRepairService$ParentRepairSession.access$300(ActiveRepairService.java:451) ~[main/:na] 
     at org.apache.cassandra.service.ActiveRepairService.currentlyRepairing(ActiveRepairService.java:338) ~[main/:na] 
     at org.apache.cassandra.db.compaction.CompactionManager.getSSTablesToValidate(CompactionManager.java:1320) ~[main/:na] 

ERROR [Repair#6:1] 2016-07-07 12:00:35,221 CassandraDaemon.java (line 227) Exception in thread Thread[Repair#6:1,5,RMI Runtime] 
com.google.common.util.concurrent.UncheckedExecutionException: org.apache.cassandra.exceptions.RepairException: [repair #67bd9b10-... 
]]] Validation failed in /198.18.87.51 
     at com.google.common.util.concurrent.Futures.wrapAndThrowUnchecked(Futures.java:1525) ~[guava-18.0.jar:na] 
     at com.google.common.util.concurrent.Futures.getUnchecked(Futures.java:1511) ~[guava-18.0.jar:na] 
     at org.apache.cassandra.repair.RepairJob.run(RepairJob.java:160) ~[main/:na] 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_71] 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_71] 
     at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_71] 
Caused by: org.apache.cassandra.exceptions.RepairException: [repair #67bd9b10... 
]]] Validation failed in /198.18.87.51 
     at org.apache.cassandra.repair.ValidationTask.treesReceived(ValidationTask.java:68) ~[main/:na] 
     at org.apache.cassandra.repair.RepairSession.validationComplete(RepairSession.java:183) ~[main/:na] 
     at org.apache.cassandra.service.ActiveRepairService.handleMessage(ActiveRepairService.java:439) ~[main/:na] 
     at org.apache.cassandra.repair.RepairMessageVerbHandler.doVerb(RepairMessageVerbHandler.java:169) ~[main/:na] 

ERROR [ValidationExecutor:3] 2016-07-07 12:42:01,298 CassandraDaemon.java (line 227) Exception in thread Thread[ValidationExecutor:3,1,main] 
java.lang.RuntimeException: Cannot start multiple repair sessions over the same sstables 
     at org.apache.cassandra.db.compaction.CompactionManager.getSSTablesToValidate(CompactionManager.java:1325) ~[main/:na] 
     at org.apache.cassandra.db.compaction.CompactionManager.doValidationCompaction(CompactionManager.java:1215) ~[main/:na] 
     at org.apache.cassandra.db.compaction.CompactionManager.access$700(CompactionManager.java:81) ~[main/:na] 
     at org.apache.cassandra.db.compaction.CompactionManager$11.call(CompactionManager.java:844) ~[main/:na] 
+0

我可以问为什么“修理”是不断有必要吗?从表面上看,我认为这是修补一些潜在的问题。 –

+0

由于我们的网络通常需要重新启动计算机,并且这会导致Cassandra节点错过数据并变得不一致。有时我们也有网络中断节点。 –

+0

啊,我明白了。重新启动总是一个bugaboo。 –

回答

0

根据您的数据大小和模式如何传播的密钥空间和表格,并通过节点的令牌数量的数据,你可以运行多个针对这些维度进行修理。对于大型密钥空间和表格,您也可以在修复时使用开始/结束标记选项。您可以通过运行nodetool ring命令找到节点的令牌。另一种维持小范围修复的方法是运行增量并行修复,检查nodetool修复中的选项。

+0

我不明白你建议的解决方案。你是说我应该制造一个中央修理控制器,以某种方式分析nodetool环的输出并且并行运行一些修理?你是怎样做的? 3.7中的默认值用于增量和并行修复,所以我已经在使用这些设置。如果修复一次在多个节点上运行,那么这不会阻止修复挂起。 –

0

我认为@viorel建议子范围修复。 Here's the datastax doc for cassandra 3.0他们将其描述为快速修复。为什么它可能会更快,并且here's an explanation。基本上,不是在整个范围内计算Merkle树,而是将分区范围分解为子范围,然后进行比较。 Here's an explanation为什么工作。

+0

修复的速度对我来说并不重要,我只是想避免修复抛出异常并挂起。如果我能修补Cassandra,以便修复在检测到另一个修复正在进行时能正常退出,那么至少我不需要操作员手动重新启动节点来清理卡住的修复。 –

+0

我正在考虑通过让它们更快地完成来避免重叠的修复。我想最终的负载将会大到足以让这只是一个临时的解决方案。 – LHWizard

+0

是的,那是我的经验。当其中一个节点大量分页内存时(由于非Cassandra应用程序在同一台机器上运行),我首先遇到了这个问题,这似乎大大减缓了修复,导致它与另一个节点重叠。因此,似乎需要某种协调机制或中央规划者,因为节点不能保护自己免受同时修理。 –

0

您可以尝试卡桑德拉 - 收割机:软件运行卡桑德拉 的自动修理https://github.com/spotify/cassandra-reaper

+0

看起来这个工具不再被维护,其中一个公开问题是,它不适用于像3.x这样的新版本。我不想使用集中式修复调度程序,因为这会成为单点故障。文档中提到“在不同节点上同时运行多个并行修复”,但我并不清楚哪些可以并行修复,哪些会引发修复引发异常并挂起。看起来,修复不能防止尝试修复同一个表的多个节点。 –

+0

没有一个答案是我正在寻找的,但你的答案是最有用的,所以我会奖赏你的奖金。感谢您的信息。 –

+0

我使用2个DC来维护50多个节点群集。我在一个节点上安装修复任务并每天修复不同的密钥空间,以确保每个密钥空间每周修复一次。我不使用-pr标志,一切正常。希望这可能会有所帮助。 –