Cassandra CPU占用超1000%需每小时执行repair如何排查解决?
问题根因分析
- 最核心的原因是读修复风暴 + 过量墓碑/小SSTable积压:集群副本因子为3、读一致性级别为QUORUM,每次读请求需要读取2个副本做数据对比,一旦副本间存在数据不一致(比如写入超时、删除产生的墓碑未同步),就会触发读修复流程。当集群中存在大量过期TTL数据、删除墓碑或者小SSTable文件时,读修复需要遍历的文件和对比的数据量会暴增,后台读修复线程持续满负载运行,直接把CPU拉到1000%以上。
- 执行repair后CPU下降的逻辑:repair操作会主动同步所有副本间的数据差异,同时会触发compaction清理过期墓碑、合并小SSTable,读修复的工作量骤降,CPU就回到正常水平。但如果持续有小写入、删除或者TTL过期数据产生,几小时内就会重新积累大量不一致数据和小文件,读修复再次打满CPU。
- 集群总数据量仅500M、读写QPS极低,排除了业务请求本身带来的CPU开销,也排除了JVM堆内存配置问题(8G堆完全满足当前业务需求)。
解决方案
定位问题表
执行命令nodetool tablestats查看所有表的统计信息,重点关注Tombstone read histogram指标,如果单读请求平均扫描墓碑数超过10,就可以定位是该表墓碑过量导致的问题。快速缓解CPU飙升
临时把对应表的读修复概率调整为0,确认CPU是否回落:
ALTER TABLE <你的keyspace名>.<你的表名> WITH read_repair_chance = 0 AND dclocal_read_repair_chance = 0;
如果调整后CPU恢复正常,即可实锤是读修复导致的问题。
- 永久修复方案
- 调整GC宽限期:你当前已经每小时执行一次repair,可以把表的gc_grace_seconds从默认的10天(864000秒)调整为3600秒,让过期墓碑更快被compaction清理:
ALTER TABLE <你的keyspace名>.<你的表名> WITH gc_grace_seconds = 3600;
- 更换压缩策略:小数据量场景下把默认的SizeTieredCompactionStrategy更换为LeveledCompactionStrategy,大幅减少读请求需要扫描的SSTable数量:
ALTER TABLE <你的keyspace名>.<你的表名> WITH compaction = {'class': 'LeveledCompactionStrategy'};
- 调整后台线程配置:修改cassandra.yaml配置,把
concurrent_read_repairers从默认的16降低到24,限制读修复的并发上限,避免CPU被打满;如果是SSD磁盘可以把`compaction_throughput_mb_per_sec`从默认的16调整到3264,加快compaction清理墓碑和小文件的速度。 - 业务优化:排查业务侧是否存在频繁删除、大量小写入或者不合理的TTL配置,比如取消不必要的删除操作、合并小批量写入,从源头减少墓碑和小SSTable的生成。
- 可选优化:如果业务可以接受最终一致性,可以把读一致性级别从QUORUM调整为ONE,不需要每次读都对比2个副本,从根源上避免触发读修复。
- 版本升级:如果以上优化后问题仍存在,可以尝试升级到3.11系列的最新补丁版(3.11.14+),该版本修复了3.11.10存在的多个读修复、compaction相关的CPU异常占用问题。
内容的提问来源于stack exchange,提问作者cuilin li
相关产品推荐
相关产品推荐

