Cassandra High Memory Usage
High memory usage can lead to OOM kills, long GC pauses, and degraded performance. This playbook covers diagnosis and resolution of memory-related issues.
Symptoms
Section titled “Symptoms”- OOM (OutOfMemoryError) in logs
- Process killed by Linux OOM killer (
dmesg | grep -i killed) - Long GC pauses (see GC Pause Issues)
- Swap usage increasing
- Cassandra process consuming more than expected memory
- Slow queries during high memory periods
Diagnosis
Section titled “Diagnosis”Step 1: Check Current Memory Usage
Section titled “Step 1: Check Current Memory Usage”# Heap usagenodetool info | grep -i heap
# Process memoryps aux | grep cassandra
# System memoryfree -hStep 2: Check for OOM Events
Section titled “Step 2: Check for OOM Events”# Linux OOM killerdmesg | grep -i "killed process\|oom"
# Cassandra OOM errorsgrep -i "outofmemory\|heap space" /var/log/cassandra/system.logStep 3: Analyze Memory Breakdown
Section titled “Step 3: Analyze Memory Breakdown”# GC statsnodetool gcstats
# Check off-heap usage (bloom filters, compression metadata)nodetool info | grep -i "off.heap\|bloom\|compression"Step 4: Check for Memory-Intensive Operations
Section titled “Step 4: Check for Memory-Intensive Operations”# Large partitions being readgrep -i "large partition" /var/log/cassandra/system.log | tail -20
# Compaction activitynodetool compactionstats
# Streaming activitynodetool netstatsStep 5: Analyze Heap Dump (if available)
Section titled “Step 5: Analyze Heap Dump (if available)”# Generate heap dumpjmap -dump:format=b,file=/tmp/heap.hprof $(pgrep -f CassandraDaemon)
# Analyze with tools like Eclipse MAT or jhatResolution
Section titled “Resolution”Immediate: Reduce Memory Pressure
Section titled “Immediate: Reduce Memory Pressure”# Clear cachesnodetool invalidatekeycachenodetool invalidaterowcache
# Flush memtables to disknodetool flush
# Check GC activitynodetool gcstatsConcurrent Reads/Writes
Concurrent reads/writes are configured via concurrent_reads and concurrent_writes in cassandra.yaml and require a restart to change. There is no runtime nodetool command to adjust these values.
Short-term: Adjust Memory Settings
Section titled “Short-term: Adjust Memory Settings”Right-size heap:
# In jvm.options# Generally 8GB max for most workloads-Xms8G-Xmx8GTune GC:
# For G1GC-XX:+UseG1GC-XX:MaxGCPauseMillis=300-XX:G1HeapRegionSize=16mMedium-term: Address Root Causes
Section titled “Medium-term: Address Root Causes”Cause 1: Large partitions
# Find large partitionsgrep "large partition" /var/log/cassandra/system.lognodetool tablestats my_keyspace | grep -i partitionCause 2: Too many SSTables
# Check SSTable countsnodetool tablestats my_keyspace | grep -E "Table:|SSTable count"
# Run compaction if needednodetool compact my_keyspace my_tableCause 3: Row cache enabled
# Check row cachenodetool info | grep -i "row cache"
# Disable if causing issuesALTER TABLE my_table WITH caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'};Cause 4: Bloom filter memory
# Check bloom filter sizenodetool tablestats my_keyspace | grep -i "bloom"
# Adjust bloom filter FP chance (higher = less memory)ALTER TABLE my_table WITH bloom_filter_fp_chance = 0.1;Cause 5: Concurrent repairs/streaming
# Check active streamsnodetool netstats
# Reduce concurrent repairsnodetool repair_admin cancel --forceLong-term: Capacity Planning
Section titled “Long-term: Capacity Planning”Calculate required memory:
Total memory needed = JVM Heap (8-16GB) + Off-heap structures (~1-4GB depending on data size) + OS page cache (remaining available RAM) + OS overhead (~1GB)Right-size the node:
| Data per node | Recommended RAM |
|---|---|
| < 500 GB | 16 GB |
| 500 GB - 1 TB | 32 GB |
| 1 TB - 2 TB | 64 GB |
| > 2 TB | 64 GB + add nodes |
Recovery
Section titled “Recovery”After OOM
Section titled “After OOM”# Check if node is runningsystemctl status cassandra
# If down, start itsudo systemctl start cassandra
# Monitor startuptail -f /var/log/cassandra/system.log
# Verify node rejoined clusternodetool statusVerify Memory Stability
Section titled “Verify Memory Stability”# Monitor heap usagewatch -n 10 'nodetool info | grep -i heap'
# Watch for GC issueswatch -n 30 'nodetool gcstats'Memory Configuration Reference
Section titled “Memory Configuration Reference”JVM Heap Settings
Section titled “JVM Heap Settings”# jvm.options-Xms8G # Initial heap-Xmx8G # Maximum heap (should equal -Xms)-XX:+AlwaysPreTouch # Pre-touch heap pagesOff-Heap Settings
Section titled “Off-Heap Settings”# Memtable spacememtable_heap_space_in_mb: 2048memtable_offheap_space_in_mb: 2048
# Native transportnative_transport_max_concurrent_connections: 128Memory Guidelines
Section titled “Memory Guidelines”| Component | Typical Size | Notes |
|---|---|---|
| Heap | 8 GB | Rarely benefit from > 16 GB |
| Memtables | 2-4 GB | Configured in cassandra.yaml |
| Bloom filters | Varies | ~1.25 bytes per key |
| Compression metadata | Varies | ~60 bytes per 64KB chunk |
| Page cache | Remaining RAM | OS managed |
Prevention
Section titled “Prevention”- Monitor heap usage - Alert at 75% utilization
- Set heap limits - Don't let JVM grow unbounded
- Avoid large partitions - Design for bounded partition sizes
- Disable row cache - Unless specific use case requires it
- Regular compaction - Reduce SSTable overhead
- Capacity planning - Add nodes before memory becomes critical
Related Commands
Section titled “Related Commands”| Command | Purpose |
|---|---|
nodetool info | Memory usage overview |
nodetool gcstats | GC statistics |
nodetool tablestats | Per-table memory usage |
nodetool invalidatekeycache | Clear key cache |
nodetool invalidaterowcache | Clear row cache |
Related Documentation
Section titled “Related Documentation”- GC Pause Issues - GC-related problems
- Large Partition Issues - Partition size problems
- JVM Options - JVM tuning