同时维修导致维修挂起

时间:2016-07-07 15:15:12

标签: cassandra

我在24节点集群中运行Cassandra 3.7,每个节点有3个数据中心和256个vnode,每个节点使用cron作业在一天中的不同时段每天运行一次“nodetool repair -pr”其他节点。

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

从中恢复很困难。我找到的唯一方法是不仅重新启动卡住修复的节点,而且还要重新启动集群中的所有节点。

我处理这个问题的唯一想法是构建某种服务,在开始修复之前检查是否有其他节点正在运行修复,也许是在修复过程中通过Cassandra表发布。

我不确定如果集群变大,我将如何能够修复所有节点,因为很快就会有足够的时间在所有节点上逐一运行修复。

所以我的主要问题是,我是否正常运行修复,以及定期修复大型集群的所有节点的推荐方法是什么?

有没有办法一次修复多个节点?文档暗示有,但不清楚如何做到这一点。在一次在多个节点上运行时,修复是否会崩溃并烧毁,这是正常的吗?有没有比重新启动所有节点更容易杀死卡住的维修?

我尝试过的一些事情:

  1. 在没有-pr的情况下运行“nodetool repair”,但如果继续运行,它也会挂起 一次多个节点。
  2. 运行“nodetool repair -dcpar” - 这个     似乎修复了运行它的节点所拥有的令牌范围     所有数据中心,但如果同时在多个节点上运行,它也会挂起。
  3. 我的密钥空间每个数据中心只保留一个副本,所以我认为我不能使用-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]
    

4 个答案:

答案 0 :(得分:0)

根据您的数据大小以及架构如何按键空间和表格传播数据以及按节点划分的令牌数量,您可以针对这些维度运行多次修复。对于大键空间和表,您还可以在修复时使用开始/结束标记选项。您可以通过运行nodetool ring命令逐节点找到令牌。另一种使维护范围更小的方法是运行增量和并行修复,检查nodetool修复中的选项。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以尝试使用cassandra-reaper:软件来运行Cassandra的自动修复 https://github.com/spotify/cassandra-reaper

答案 3 :(得分:0)

这可能是另一个问题的提示。例如,您可能有一个非常大的 sstable 文件,该文件与您的修复策略不兼容,限制在不到一小时。这个非常大的文件可能包含来自多个令牌范围的数据,这会导致修复任务之间的竞争

您可能会发现从中心点启动修复以按顺序而不是每小时有效地进行修复更容易。 可能的解决方案:

  • cassandra-reaper 如果可能
  • 一个节点上的脚本,它将通过 ssh 连接到所有节点以运行 nodetool 命令
  • 一个节点上的脚本,可以使用 nodetool -h x.x.X.X repair -pr 命令,但需要允许每个主机上的远程 JMX 连接