要了解 nodetool 修复如何影响集群或集群大小如何影响修复,我们需要了解修复期间会发生什么。修复分为两个阶段,第一个阶段是构建数据的 Merkle 树。第二个是让副本实际比较它们的树之间的差异,然后根据需要将它们相互传输。
第一阶段在磁盘 io 上可能很密集,因为它将触及运行修复的节点上磁盘上的几乎所有数据。避免修复触及整个磁盘的一种简单方法是使用 -pr 标志。使用 -pr 时,它将使用 disksize/RF 而不是要修复的 disksize 数据。在节点上运行修复也会向存储任何这些范围的副本的所有节点发送消息,以构建 merkle 树。这可能是一个问题,因为所有副本将同时执行此操作,这可能会使它们都响应您的那部分数据的速度变慢。
决定修复操作如何影响其他数据中心的因素是副本放置策略的使用。由于您将需要跨数据中心的一致性(EACH_QOURUM 案例),因此必须在您的案例中使用像网络拓扑策略这样的跨 dc 复制策略。对于修复,这意味着您在运行修复时不能将自己限制在本地 dc,因为您有一些 EACH_QUORUM 一致性案例。为避免修复影响所有数据中心的所有副本,您应该 a) 使用 Dynamic snitch 包装您的复制策略并正确配置错误阈值 b) 在运行修复时使用 -snapshot 选项。这将做的是对您的数据进行快照(快照只是到现有 sstables 的硬链接,利用 sstables 不可变的事实,从而使快照非常便宜)并从快照顺序修复。这意味着对于任何给定的副本集,一次只有一个副本将执行验证压缩,从而允许动态 snitch 通过其他副本维护您的应用程序的性能。
现在我们可以回答您的问题。
nodetool 修复复杂性是否随着所有数据中心的副本数量线性增长?您可以通过在修复期间使用 Dynamic snitch 和 pass -snapshot 选项包装您的复制策略来限制这一点。
还是 nodetool 修复复杂度会随着当前数据中心的副本数量和数据中心数量的组合而线性增长?模糊地说,这个模型可能会与当前数据中心的每个单独节点同步数据,但对其他数据中心的副本进行类似 EACH_QUORUM 的操作。如果您使用上述方法,复杂性将随着副本数量的增加而增加运行时间。这是因为上述方法将一次对一个副本进行顺序修复。
要扩展集群,是在现有数据中心添加更多节点还是在假设整体副本数量不变的情况下添加新数据中心更好?我在 nodetool 修复性能的背景下问这个问题。从 nodetool repair 的角度来看,如果您采用上述方法,这没有任何区别。因为它取决于副本的总数。
此外,使用 nodetool 进行修复的目的是使删除不会回来。例行修复频率的硬性要求是 gc_grace_seconds 的值。在很少删除或覆盖数据的系统中,您可以提高 gc_grace 的值,而对磁盘空间的影响最小。这允许使用 nodetool 实用程序安排更宽的时间间隔来安排修复操作。避免频繁维修的推荐方法之一是通过设计使记录保持不变。这对您来说可能很重要,因为您需要在数十个数据中心上运行,否则操作会很痛苦。