Cassandra节点卡在Mutation阶段且CPU利用率极高,请求技术解决方案
Cassandra节点Mutation阻塞+CPU高负载排查解决指南
一、当前节点状态拆解
先把各监控命令的输出转成中文并做针对性分析:
1. 线程池状态(nodetool tpstats)
$ NODETOOL tpstats 线程池名称 活跃数 等待数 已完成数 阻塞数 累计阻塞数 RequestResponseStage 0 0 26110939 0 0 MutationStage 124 13165 874648434519 0 0 ReadStage 0 0 4197248 0 0 CompactionExecutor 0 0 6855061 0 0
- MutationStage是处理写请求的核心线程池,当前有124个活跃线程、13165个排队任务,摆明了写请求严重积压,这是CPU飙高的核心原因。
- 其他线程池无积压,可排除读请求、压缩任务导致的负载问题。
2. 系统负载(top)
top - 22:46:48 已运行59天, 2:34, 1个用户, 负载平均值: 132.11, 135.86, 135.80 任务总数: 387, 6个运行中, 380个睡眠, 0个停止, 1个僵尸进程 CPU使用率: 98.7% 用户态, 0.5% 内核态, 0.0% 优先级调整, 0.3% 空闲, 0.0% IO等待, 0.3% 硬中断, 0.1% 软中断, 0.0% 虚拟机窃取时间 内存(MB): 总63857.6, 空闲613.9, 使用26076.0, 缓冲/缓存37167.7 交换分区(MB): 总0.0, 空闲0.0, 使用0.0. 可用内存35953.2
PID 用户 优先级 偏移 虚拟内存 物理内存 共享内存 状态 %CPU %内存 累计运行时间 命令 1240 cassand+ 20 0 162.9g 22.4g 207912 S 983.1 35.9 45122:57 java
- 系统负载远超CPU核心数(均值130+),Cassandra的Java进程占用983% CPU,说明进程内持续运行大量CPU密集型操作。
- 内存剩余充足、无交换分区使用,可排除内存不足导致的问题。
3. GC统计(nodetool gcstats)
NODETOOL gcstats 统计间隔(ms) 单次GC最长耗时(ms)GC总耗时(ms)GC耗时标准差(ms) GC回收内存(MB) GC次数 直接内存字节数 3490349390 45781 1832856 384 249097766280528 36321 -1
- GC总耗时超180万毫秒(合30分钟),单次最长GC达45秒,GC次数累计3.6万次——说明GC异常频繁,要么是Young GC反复触发,要么是Full GC持续占用CPU。GC消耗大量资源会拖慢Mutation任务处理速度,进而导致写请求积压,形成恶性循环。
二、解决步骤
1. 紧急止血措施
- 限流写入请求:立刻要求客户端降低写入速率,避免等待队列持续膨胀;如果是批量写入,拆分批次大小,减少单次提交的数据量。
- 动态调整Mutation线程数:用
nodetool setconcurrentwrites <num>命令调整,比如CPU为32核时,可设为48(核心数的1.5倍),上限不超过32,避免线程上下文切换开销飙升,无需重启节点即可生效。 - 手动触发Full GC:在业务低峰期执行
jcmd 1240 GC.run_full,强制回收堆内存,短暂停顿节点但能快速缓解GC压力。
2. 根因排查与修复
- 优化GC配置:打开
jvm.options检查GC参数,若使用CMS GC,建议切换为G1GC(Cassandra 3.11+官方推荐);调整堆内存大小,64G物理内存节点的Xms/Xmx设为24-32G,不超过物理内存的50%,降低GC压力。 - 排查写入热点:用
nodetool tablehistograms <keyspace> <table>查看表的写入分布,确认是否存在单分区写入过载(如每秒数千次写入);若有热点,调整数据模型,增加分区键基数,将热点分散到多个分区。 - 检查压缩策略:当前
CompactionExecutor无任务,暂不考虑压缩抢资源,但需检查表的compaction_throughput_mb_per_sec参数,设置合理阈值,避免后续压缩突然占用CPU。 - 分析日志:查看
system.log中Mutation相关的错误、超时或慢查询日志,比如WriteTimeoutException、分区过大提示等,定位具体异常写入操作。
3. 长期优化方案
- 集群扩容:若写入量持续超出单节点处理能力,新增集群节点,分散写入负载。
- 数据模型优化:避免宽行设计,控制单分区大小在100MB以内;采用时间窗口分区(按天/小时分区),自动老化旧数据,减轻分区压力。
- 完善监控告警:新增Mutation队列长度、GC耗时、分区大小的监控告警,提前发现异常,避免问题恶化。
内容的提问来源于stack exchange,提问作者Balu
相关产品推荐
相关产品推荐

