前天,我使用以下命令在5节点Cassandra群集中的一个节点上为单个表进行了完整的顺序修复。
nodetool repair -full -seq -tr <keyspace> <table> > <logfile>
从下面的命令可以推断出,现在已经正确修复了发出命令的节点
nodetool cfstats -H <keyspace.columnFamily>
但是,关于其他节点,不能说相同,因为对于它们,我得到的修理百分比是一个随机值,要小得多。
我不确定这里发生了什么,看来唯一为键空间和列族修复的节点是在其上发出了修复命令的节点。任何关于这里可能发生的事情或如何正确调查问题的猜测
谢谢!
答案 0 :(得分:5)
您说您的集群有5个节点,但没有为表使用哪个复制因子(RF)-我假设您使用了公共RF = 3。当RF = 3时,每个数据在五个节点上重复3次。
您错过的要点是,在这样的设置中,每个特定节点都不包含所有数据。它包含多少总数据?让我们做一些简单的数学运算:如果插入表中的实际数据量为X,则集群存储的数据总量为3 * X(因为RF = 3,所以每条数据都有三个副本)。该总数分布在5个节点上,因此每个节点将保持(3 * X)/ 5,即3/5 * X。
在一个特定节点上开始修复时,它仅修复该节点具有的数据,即,正如我们刚刚计算的那样,修复的是总数据的3/5。此修复针对此节点保存的每条数据进行操作,将其与其他副本保存的副本进行比较,修复不一致之处,并所有修复这些副本。这意味着修复结束后,在我们修复的节点中,所有数据均已修复。但是对于其他节点,并非所有数据都得到了修复-只是与发起此修复的节点相交的部分。这个交集应该大约是数据的3/5 * 3/5或36%(当然,所有数据都是随机分布的,因此,您获得的数字可能接近36%,但不完全是36%)。
因此,您可能已经意识到,这意味着“ nodetool repair”不是集群范围的操作。如果在一个节点上启动它,则只能保证修复一个节点上的所有数据,而在其他节点上修复的数据可能更少。因此,您必须分别在每个节点上运行修复。
现在您可能会问:由于修复节点1也修复了节点2的36%,也因为我们已经完成了36%的工作而也修复了节点2,这不是浪费吗?确实,这是浪费。因此,Cassandra具有修复选项“ -pr”(“主范围”),该选项确保每个片段数据的3个副本中只有一个可以修复它。如果RF = 3,“ nodetool repair -pr”将比不使用“ -pr”的速度快三倍;您仍然需要在每个节点上分别运行它,并且当所有节点完成操作后,将在所有节点上100%修复数据。
所有这些都是相当不便的,而且在长期维修过程中也很难从瞬态故障中恢复。这就是为什么Datastax和ScyllaDB两种商业Cassandra产品都提供单独的修复工具的原因,该工具比“ nodetool修复”更为方便,可确保以最有效的方式修复整个集群,并从瞬态问题中恢复而不会从一开始就重新进行冗长的修复过程。