Cassandra High CPU Usage Playbook
Symptoms
Section titled “Symptoms”- CPU utilization consistently above 70%
- Slow query response times
- Node performance degradation
- Increased latency across the cluster
Impact
Section titled “Impact”- Severity: Medium to High
- Services Affected: All queries to the affected node
- User Impact: Increased latency, potential timeouts
Immediate Assessment
Section titled “Immediate Assessment”Step 1: Confirm High CPU
Section titled “Step 1: Confirm High CPU”# Check overall CPU usagetop -b -n 1 | head -20
# Check Cassandra processps aux | grep -i cassandra
# Check CPU usage over timesar -u 1 10
# Expected output showing high CPU:# %user %nice %system %iowait %idle# 75.50 0.00 8.20 2.30 14.00Step 2: Identify CPU Consumer
Section titled “Step 2: Identify CPU Consumer”# Cassandra JVM CPU breakdowntop -H -p $(pgrep -f CassandraDaemon)
# Look for:# - GC threads (high = memory pressure)# - CompactionExecutor threads# - ReadStage/MutationStage threads
# Check thread distributionnodetool tpstatsStep 3: Check for Common Causes
Section titled “Step 3: Check for Common Causes”# 1. Check compaction activitynodetool compactionstats
# 2. Check for GC pressuretail -100 /var/log/cassandra/gc.log | grep "pause"
# 3. Check thread poolsnodetool tpstats | grep -E "Pending|Blocked"
# 4. Check for expensive queriesgrep -i "slow" /var/log/cassandra/system.log | tail -20Common Causes and Solutions
Section titled “Common Causes and Solutions”Cause 1: Heavy Compaction
Section titled “Cause 1: Heavy Compaction”Diagnosis:
nodetool compactionstats
# High CPU during compaction:# Active compactions: 4# pending tasks: 45Resolution:
# Reduce compaction throughputnodetool setcompactionthroughput 32 # MB/s
# Reduce concurrent compactors# Edit cassandra.yaml:# concurrent_compactors: 1
# For immediate relief (temporary)nodetool stop COMPACTION# WARNING: Only temporary, compaction backlog will growCause 2: Garbage Collection
Section titled “Cause 2: Garbage Collection”Diagnosis:
# Check GC activitygrep -E "GC pause|Total time" /var/log/cassandra/gc.log | tail -50
# Check heap usagenodetool info | grep "Heap Memory"
# High GC means heap pressureResolution:
# Tune GC settings in jvm11-server.options# -XX:MaxGCPauseMillis=500# -XX:InitiatingHeapOccupancyPercent=70
# If heap is too small, increase (max 31GB)# -Xmx16G -Xms16G
# After changes, rolling restart requiredCause 3: High Query Volume
Section titled “Cause 3: High Query Volume”Diagnosis:
# Check request ratesnodetool proxyhistograms
# Check thread pool saturationnodetool tpstats | grep -E "ReadStage|MutationStage"
# Active or Pending > 0 indicates loadResolution:
# Scale cluster (add nodes)# Or redirect traffic (load balancer)
# Temporary: Increase thread pool size# Edit cassandra.yaml:# concurrent_reads: 64# concurrent_writes: 64# Requires restartCause 4: Expensive Queries
Section titled “Cause 4: Expensive Queries”Diagnosis:
# Check for ALLOW FILTERING or large scansgrep -i "allow filtering\|full scan" /var/log/cassandra/system.log
# Enable slow query logging# cassandra.yaml: slow_query_log_timeout_in_ms: 500
# Check table statistics for problem tablesnodetool tablestats | grep -A20 "Table: "Resolution:
-- Fix query patterns-- Instead of ALLOW FILTERING, create proper table
-- Check for missing indexes or bad data modelDESCRIBE TABLE problem_table;
-- Review and optimize queriesTRACING ON;SELECT * FROM problem_table WHERE ...;Cause 5: Large Partitions
Section titled “Cause 5: Large Partitions”Diagnosis:
# Check partition sizesnodetool tablehistograms keyspace table | grep "Partition Size"
# Large partitions cause CPU during reads# 99th percentile > 100MB indicates problemResolution:
-- Implement time bucketing-- Split large partitions-- See data modeling best practicesCause 6: Tombstone Scanning
Section titled “Cause 6: Tombstone Scanning”Diagnosis:
# Check tombstone countsnodetool tablestats keyspace | grep -i tombstone
# Large tombstone counts cause CPU on readsResolution:
# Run compaction to remove tombstonesnodetool compact keyspace table
# Review delete patterns# Use TTL instead of explicit deletesDetailed Investigation
Section titled “Detailed Investigation”Thread Dump Analysis
Section titled “Thread Dump Analysis”# Take thread dumpjstack $(pgrep -f CassandraDaemon) > /tmp/threaddump_$(date +%s).txt
# Look for:# - Many threads in RUNNABLE state# - Threads blocked on locks# - GC threads consuming CPU
# Analyze hot methodsgrep -A 10 "RUNNABLE" /tmp/threaddump_*.txt | head -100Profile with async-profiler
Section titled “Profile with async-profiler”# Download async-profilerwget https://github.com/jvm-profiling-tools/async-profiler/releases/download/v2.9/async-profiler-2.9-linux-x64.tar.gztar xzf async-profiler-2.9-linux-x64.tar.gz
# Profile CPU for 60 seconds./profiler.sh -d 60 -f /tmp/profile.html $(pgrep -f CassandraDaemon)
# Open profile.html in browser to see flame graphCheck for Hot Partitions
Section titled “Check for Hot Partitions”# Enable tracingcqlsh -e "TRACING ON; SELECT * FROM keyspace.table WHERE partition_key = ?;"
# Look for:# - High number of rows read# - Long read time# - Many SSTables accessedResolution Steps
Section titled “Resolution Steps”Immediate Actions
Section titled “Immediate Actions”# 1. Reduce compaction impactnodetool setcompactionthroughput 16
# 2. Check if single node is hot (route traffic away)nodetool status # Check load distribution
# 3. If GC-related, restart node (clears heap)nodetool drainsudo systemctl restart cassandraShort-term Fixes
Section titled “Short-term Fixes”# 1. Add capacity (if needed)# Scale horizontally
# 2. Tune thread pools# cassandra.yaml adjustments
# 3. Optimize queries# Fix ALLOW FILTERING# Add appropriate indexesLong-term Solutions
Section titled “Long-term Solutions”# 1. Review and fix data model# Implement proper partitioning# Time bucketing for time-series
# 2. Upgrade hardware# More CPU cores# Faster storage (NVMe)
# 3. Scale cluster appropriately# Add nodes before hitting limitsPrevention
Section titled “Prevention”Monitoring
Section titled “Monitoring”# Alert on:- CPU > 60% for 10 minutes (warning)- CPU > 80% for 5 minutes (critical)- Pending compactions > 20- GC pause > 500msCapacity Planning
Section titled “Capacity Planning”Monitor trends:- CPU utilization over time- Request rate growth- Data growth rate
Plan scaling:- Scale before hitting 70% sustained CPU- Add nodes in pairs for balance- Test new capacity in stagingQuery Review
Section titled “Query Review”-- Regularly review slow queries-- Enable slow query logging
-- Audit ALLOW FILTERING usagegrep -r "ALLOW FILTERING" /app/queries/
-- Review data model quarterlyVerification
Section titled “Verification”After resolution, verify:
# CPU returned to normaltop -b -n 1 | grep Cpu
# Latency improvednodetool proxyhistograms
# Thread pools healthynodetool tpstats | grep -E "Pending|Blocked"
# Compaction backlog managednodetool compactionstatsRelated Issues
Section titled “Related Issues”- High Memory Usage - Memory troubleshooting
- Slow Queries - Query optimization
- Compaction Issues - Compaction troubleshooting
Next Steps
Section titled “Next Steps”- Performance Tuning - Optimization guide
- Monitoring Guide - Set up alerts
- Data Modeling - Schema design