Skip to content

AxonOps — AI-Native Control Plane for Open Source Data Platforms

Monitoring Operations

Effective Cassandra operations require continuous monitoring of cluster health, performance metrics, and resource utilization. This guide covers what to monitor, how to interpret metrics, and how to respond to alerts.

Proactive vs Reactive Operations

The goal of monitoring is to detect and resolve issues before they impact users. Establish baselines during normal operation, set alerts on deviations, and investigate anomalies promptly.


Cassandra Monitoring with AxonOpsCassandra Monitoring with AxonOpsCassandra NodeAxonOps AgentAxonOps ServerAxonOps DashboardJMX MBeansLogsOS MetricsnodetoolMetrics CollectionLog CollectionSystem MetricsTime Series StorageLog AggregationAlert EngineCluster OverviewDashboardsAlerting
SourceTypeAccess Method
JMX MBeansPerformance metricsJMX client, exporters
nodetoolOperational commandsCLI
System tablesInternal stateCQL queries
OS metricsResource utilizationNode exporter
LogsEvents, errorsLog aggregation

Must-monitor metrics for cluster stability:

MetricJMX PathHealthy RangeAlert Threshold
Live nodesStorageService.LiveNodesAll nodesAny node down
Unreachable nodesStorageService.UnreachableNodesEmptyAny node unreachable
Schema versionsStorageService.SchemaVersionSingle versionMultiple versions >5 min
Pending compactionsCompaction.PendingTasks<50>100 sustained
Dropped messagesDroppedMessage.Dropped0Sustained drops (>10/s)
MetricDescriptionHealthy RangeAlert
Read latency (P99)99th percentile read time<50ms>100ms
Read timeoutsTimed out read requests0>0
Key cache hit rateCache efficiency>80%<50%
Row cache hit rateRow cache efficiency>90% (if enabled)<70%
Tombstone scansTombstones per read<1000>5000
MetricDescriptionHealthy RangeAlert
Write latency (P99)99th percentile write time<20ms>50ms
Write timeoutsTimed out write requests0>0
Memtable sizeMemory used by memtables<heap/3>heap/2
Commit log sizePending commit log<1GB>2GB
Hints storedPending hints0>1000
MetricSourceHealthy RangeAlert
Heap usageJMX<70%>85%
GC pause timeJMX<500ms>1s
GC frequencyJMX<5/min>10/min
Disk usageOS<70%>80%
Disk I/O waitOS<20%>40%
CPU usageOS<70%>85%
Network throughputOSWithin capacityNear saturation

daily-health-check.sh
#!/bin/bash
echo "=== Cluster Status ==="
nodetool status
echo -e "\n=== Schema Agreement ==="
nodetool describecluster | grep -A 5 "Schema versions"
echo -e "\n=== Pending Compactions ==="
nodetool compactionstats | head -20
echo -e "\n=== Thread Pool Status ==="
nodetool tpstats | grep -v "^$"
echo -e "\n=== Dropped Messages ==="
nodetool tpstats | grep -i dropped
Terminal window
# Table statistics for specific keyspace
nodetool tablestats <keyspace>
# Per-table read/write latencies
nodetool tablestats <keyspace>.<table> | grep -E "latency|Bloom"
# Compaction throughput
nodetool compactionstats
# GC statistics
nodetool gcstats
# Streaming status
nodetool netstats
# Client connections
nodetool clientstats
Terminal window
# Token distribution
nodetool ring
# Endpoints for a key
nodetool getendpoints <keyspace> <table> <key>
# Ownership percentages
nodetool status | awk '{print $1, $2, $6}'

Cluster metrics:

org.apache.cassandra.metrics:type=Storage,name=Load
org.apache.cassandra.metrics:type=Storage,name=Exceptions
org.apache.cassandra.metrics:type=ClientRequest,scope=Read,name=Latency
org.apache.cassandra.metrics:type=ClientRequest,scope=Write,name=Latency

Table metrics:

org.apache.cassandra.metrics:type=Table,keyspace=<ks>,scope=<table>,name=ReadLatency
org.apache.cassandra.metrics:type=Table,keyspace=<ks>,scope=<table>,name=WriteLatency
org.apache.cassandra.metrics:type=Table,keyspace=<ks>,scope=<table>,name=LiveSSTableCount
org.apache.cassandra.metrics:type=Table,keyspace=<ks>,scope=<table>,name=TombstoneScannedHistogram

Thread pool metrics:

org.apache.cassandra.metrics:type=ThreadPools,path=request,scope=ReadStage,name=PendingTasks
org.apache.cassandra.metrics:type=ThreadPools,path=request,scope=MutationStage,name=PendingTasks
org.apache.cassandra.metrics:type=ThreadPools,path=internal,scope=CompactionExecutor,name=PendingTasks

Compaction metrics:

org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
org.apache.cassandra.metrics:type=Compaction,name=TotalCompactionsCompleted
org.apache.cassandra.metrics:type=Compaction,name=BytesCompacted
Terminal window
# Using jmxterm
java -jar jmxterm.jar -l localhost:7199
> domain org.apache.cassandra.metrics
> bean type=ClientRequest,scope=Read,name=Latency
> get 99thPercentile
# Using jconsole (GUI)
jconsole localhost:7199

LogLocationPurpose
system.log/var/log/cassandra/system.logMain operational log
debug.log/var/log/cassandra/debug.logDetailed debugging
gc.log/var/log/cassandra/gc.logGC activity
Terminal window
# Errors requiring immediate attention
grep -E "ERROR|FATAL" /var/log/cassandra/system.log | tail -50
# OutOfMemory events
grep -i "OutOfMemory\|OOM" /var/log/cassandra/system.log
# Compaction issues
grep -i "compaction" /var/log/cassandra/system.log | grep -i "error\|fail"
# Streaming problems
grep -i "stream" /var/log/cassandra/system.log | grep -i "error\|fail"
# Gossip issues
grep -i "gossip" /var/log/cassandra/system.log | grep -i "error\|fail"
# Dropped messages
grep -i "dropped" /var/log/cassandra/system.log
# Slow queries (if enabled)
grep "SLOW" /var/log/cassandra/system.log
cassandra.yaml
slow_query_log_timeout_in_ms: 500

SeverityResponse TimeExamples
CriticalImmediateNode down, disk full, OOM
WarningWithin 1 hourHigh latency, compaction backlog
InfoNext business dayElevated tombstones, GC time increase

Critical Alerts (Page immediately):

AlertConditionResponse
Node DownAny node unreachableInvestigate immediately, check network/process
Disk FullDisk usage >85%Add capacity or clean up snapshots
OOM/Frequent GCFull GC >5 times in 5 minInvestigate heap usage, potential memory leak
Schema DisagreementMultiple schema versions >5 minCheck for stuck schema migrations

Warning Alerts:

AlertConditionResponse
High Read LatencyP99 >100ms sustainedCheck compaction, tombstones, GC
Compaction BacklogPending >100 for 30 minIncrease throughput or investigate blockers
Dropped MessagesAny message dropsCheck thread pools, network, timeouts
Hints Growing>1000 hints storedCheck target node health

AxonOps provides pre-configured alerts for these conditions. See Setup Alert Rules for configuration details.


Cluster Overview:

  • Node status (up/down) per DC
  • Total cluster load
  • Request rates (reads/writes per second)
  • Error rates

Performance:

  • P50/P95/P99 read latency
  • P50/P95/P99 write latency
  • Requests per second (by node)
  • Timeouts per second

Resources:

  • Heap usage per node
  • Disk usage per node
  • CPU usage per node
  • Network I/O per node

Operations:

  • Pending compactions
  • SSTable count
  • Tombstone ratios
  • Hint storage

AxonOps provides pre-built dashboards for Cassandra monitoring:

  • Cluster Overview: Node status, load distribution, request rates across all nodes
  • Node Details: Per-node metrics including heap, disk, CPU, and thread pools
  • Table Metrics: Per-table read/write latency, SSTable counts, partition sizes
  • Compaction: Pending tasks, throughput, history across the cluster
  • Repair: Repair coverage, progress, and scheduling status

See Metrics Dashboard for dashboard usage and customization.


-- Node status from system tables
SELECT peer, data_center, rack, release_version, tokens
FROM system.peers;
-- Local node info
SELECT cluster_name, data_center, rack, release_version
FROM system.local;
-- Schema versions
SELECT schema_version, peer FROM system.peers;
-- Table sizes
SELECT keyspace_name, table_name,
mean_partition_size,
partitions_count
FROM system_schema.tables;
-- Compaction history
SELECT keyspace_name, columnfamily_name, compacted_at, bytes_in, bytes_out
FROM system.compaction_history
WHERE compacted_at > '2024-01-01'
ALLOW FILTERING;

Record metrics during normal operation periods:

baseline-capture.sh
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M)
OUTPUT="baseline_${DATE}.txt"
echo "Capturing baseline at $(date)" > $OUTPUT
echo -e "\n=== Table Stats ===" >> $OUTPUT
nodetool tablestats >> $OUTPUT
echo -e "\n=== Thread Pools ===" >> $OUTPUT
nodetool tpstats >> $OUTPUT
echo -e "\n=== GC Stats ===" >> $OUTPUT
nodetool gcstats >> $OUTPUT
echo -e "\n=== Compaction Stats ===" >> $OUTPUT
nodetool compactionstats >> $OUTPUT

Track these for capacity planning:

MetricPurposeGrowth Trigger
Disk usageStorage capacity>60%
Data per nodeNode sizing>500GB
Write rateThroughput capacityNear limits
P99 latencyPerformance capacity>SLA threshold

AxonOps Monitoring provides purpose-built monitoring for Apache Cassandra, eliminating the complexity of assembling custom monitoring stacks.

CapabilityDescription
Zero-configuration collectionAgent automatically discovers and collects all relevant Cassandra metrics
Pre-built dashboardsProduction-tested dashboards for cluster, node, and table views
Historical analysisLong-term metric storage with efficient compression
Cross-cluster visibilityMonitor multiple clusters from a single interface
Intelligent alertingPre-configured alerts with anomaly detection
Centralized loggingAggregate and analyze logs from all nodes

AxonOps extends beyond metrics collection:

  • Repair monitoring: Track repair progress and coverage across the cluster
  • Backup monitoring: Verify backup completion and health status
  • Capacity forecasting: Predict when resources will be exhausted
  • Performance analysis: Identify slow queries and hot partitions

Terminal window
# 1. Check if specific tables affected
nodetool tablestats | grep -A 10 "Table: problem_table"
# 2. Check tombstone counts
nodetool tablestats <ks>.<table> | grep -i tombstone
# 3. Check SSTable count
nodetool tablestats <ks>.<table> | grep "SSTable count"
# 4. Check compaction pending
nodetool compactionstats
# 5. Check GC activity
nodetool gcstats
Terminal window
# 1. Check commit log disk
df -h /var/lib/cassandra/commitlog
# 2. Check memtable flush status
nodetool tpstats | grep -i memtable
# 3. Check mutation stage
nodetool tpstats | grep -i mutation
# 4. Check hints
nodetool tpstats | grep -i hint
# 5. Check disk I/O
iostat -x 1 5
Terminal window
# 1. Identify which message types dropped
nodetool tpstats | grep -i dropped
# 2. Check thread pool queues
nodetool tpstats | grep -i pending
# 3. Check if specific nodes affected
# (Check each node)
# 4. Check network connectivity
ping -c 5 <other_node>
nc -zv <other_node> 7000

  1. Start with cluster-level metrics: Node count, total throughput, overall latency
  2. Drill down on anomalies: Identify affected nodes, tables, operations
  3. Correlate across metrics: High latency often correlates with GC, compaction, or disk I/O
  4. Keep historical data: Compare current vs baseline
  1. Alert on symptoms, not causes: Alert on high latency, not high CPU (unless CPU is the issue)
  2. Avoid alert fatigue: Too many alerts lead to ignoring alerts
  3. Include runbook links: Every alert should link to resolution steps
  4. Review and tune regularly: Adjust thresholds based on experience
  1. Document normal ranges: What does "healthy" look like for this cluster?
  2. Record incidents: What happened, how it was detected, how it was resolved
  3. Maintain runbooks: Step-by-step procedures for common alerts