Cassandra两节点容量不一致,多次nodetool repair无效求助
我们拥有两个Cassandra节点,Node1曾长时间离线。在此期间Node2的容量增至1TB,而Node1仅为100GB。我们尝试在Node1上执行
nodetool repair进行修复,但无任何变化。随后我们在Node2上启动nodetool repair,压缩耗时5天但同样没有效果。当前节点状态如下:Datacenter: dc1 =============== Status=Up/Down |/ State=Normal/Leaving/Joining/Moving -- Address Load Tokens Owns (effective) Host ID Rack UN 172.x.y.z 149.46 GB 256 100.0% xxx rack1 UN 172....
这种双节点集群里数据同步卡住的情况我碰过好几次,核心问题大概率是节点离线太久,导致常规repair没办法处理这么大的增量数据,或者是修复的参数、集群配置没到位。给你几个一步步排查和解决的方案:
先确认集群的核心配置是否正确
首先跑DESCRIBE KEYSPACE <你的键空间名>;检查复制因子是不是2——双节点集群必须设为2,不然Node2上的新数据本来就不会同步到Node1,repair自然没用。另外,确认写入时的一致性级别至少是QUORUM,如果一直用ONE的话,离线期间的写入根本不会触发同步逻辑(不过离线本身也同步不了,但复制因子是前提)。放弃全量repair,尝试细粒度修复
全量repair在数据量差10倍的情况下很容易超时、卡住,还会占满节点资源。你可以先针对单个键空间做全量修复:nodetool repair -full <键空间名>,甚至细化到单个表:nodetool repair -full <键空间名>.<表名>。另外加上--jobs参数指定并行任务数(比如--jobs 4),能加快速度,但别超过节点的CPU核心数,避免把节点跑崩。查日志定位修复卡住的具体原因
去Cassandra的日志目录(一般是/var/log/cassandra/)翻system.log,搜索repair相关的条目,看看有没有报错——比如“stream failed”(数据传输失败)、“timeout”(超时)或者某个表因为大量墓碑(tombstone)卡住。如果是墓碑问题,先跑nodetool compact <键空间名>.<表名>清理墓碑,再重新执行repair。如果repair彻底走不通,试试快照+增量同步的方案
这是数据量差异极大时的兜底方案:- 在Node2上给目标键空间拍快照:
nodetool snapshot -t repair_snapshot <键空间名>,快照会存在/var/lib/cassandra/data/<键空间名>/<表名>-<uuid>/snapshots/repair_snapshot/目录下。 - 把Node2的快照文件复制到Node1对应的目录,记得把权限改成cassandra用户的:
chown -R cassandra:cassandra /var/lib/cassandra/data/。 - 在Node1上加载快照:
nodetool refresh <键空间名>.<表名>,每个表都要执行。 - 加载完快照后,跑一次增量repair:
nodetool repair -incremental <键空间名>,同步快照之后产生的新数据。
- 在Node2上给目标键空间拍快照:
检查token分配是否异常
从你给出的节点状态看,Node1的Owns (effective)是100%?这完全不正常——双节点集群正常应该各占50%左右的token。这说明Node1重新加入集群时token分配出了问题,导致它认为自己拥有全部数据,根本不会从Node2同步。你可以跑nodetool ring看看token分布,如果确实Node1占满了,那需要用nodetool move给它重新分配token,或者重启Node2时重新初始化token(操作前记得备份数据,小心数据丢失)。
内容的提问来源于stack exchange,提问作者Ekrem Gurdal

