Skip to content

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

Cassandra Fault Tolerance and Failure Scenarios

This section examines Cassandra’s fault tolerance architecture from both server-side and client-side perspectives. Understanding how failures propagate through the system—and how both the cluster and client drivers respond—is essential for designing resilient applications.


Cassandra’s fault tolerance derives from three architectural properties:

PropertyMechanismBenefit
ReplicationData copied to RF nodesNo single point of failure for data
DecentralizationNo master node, peer-to-peerNo single point of failure for coordination
Tunable consistencyConfigurable read/write guaranteesTrade-off availability vs consistency
Fault Tolerance ArchitectureFault Tolerance ArchitectureClient LayerServer LayerData LayerDriver• Connection pooling• Request routing• Retry policiesLoad Balancing Policy• Token-aware routing• DC-aware routing• Latency-awareRetry Policy• Idempotent retries• Speculative execution• Fallback strategiesCoordinator• Request routing• Replica selection• Timeout handlingGossip• Failure detection• Topology awareness• State propagationHinted Handoff• Write buffering• Eventual delivery• Consistency repairReplication• RF copies per partition• Multi-DC replication• Rack distributionRepair• Anti-entropy• Merkle trees• Consistency restoration

Failures occur at different scopes, each with distinct characteristics and recovery strategies:

Failure Scope HierarchyFailure Scope HierarchyProcess Failure• JVM crash• OOM kill• Application bugNode Failure• Hardware failure• OS crash• Power lossRack Failure• Top-of-rack switch• Power distribution• Cooling failureDatacenter Failure• Network isolation• Power grid• Natural disasterRegion Failure• Multiple DC outage• Wide-area network• Geographic eventescalatescorrelatescorrelatescorrelates
ScopeTypical DurationDetection TimeRecovery Approach
ProcessSeconds-minutesTypically seconds (varies with Phi configuration and inter-arrival history)Automatic restart
NodeMinutes-hoursTypically seconds (varies with Phi configuration)Replacement or repair
RackMinutes-hoursTypically seconds (varies with Phi configuration)Wait or redistribute
DatacenterHours-daysSeconds (network)Failover to other DC
RegionHours-daysSeconds (network)DR procedures

The most common failure scenario. Cassandra continues operating if sufficient replicas remain:

Single Node Failure (RF=3, CL=QUORUM)Single Node Failure (RF=3, CL=QUORUM)Before FailureAfter Node 2 FailsClientNode 1(replica)Node 2(replica)Node 3(replica)ClientNode 1(replica)Node 2(DOWN)Node 3(replica)

Impact Analysis:

Consistency LevelRF=3, 1 Node DownOutcome
ONE2 replicas availableReads/writes succeed
QUORUM2 of 3 availableReads/writes succeed (2 ≥ ⌈3/2⌉ + 1)
ALLOnly 2 availableReads/writes fail
LOCAL_QUORUMDepends on DCSucceeds if local DC unaffected

When a node fails, the server-side components respond:

Server-Side Failure ResponseServer-Side Failure ResponseNode FailureDetected1. Phi Accrual Detectionφ exceeds threshold (timing varies)2. Local DOWN DecisionNode marked DOWN locally3. Hinted HandoffWrites stored for failed node4. Request ReroutingExclude from replica selection

Timeline:

TimeEvent
T+0Node stops responding
T+1-8sPhi value rises as heartbeats missed
T+variablePhi exceeds threshold, node marked DOWN locally on each observing node
T+variableEach node independently detects failure via Phi (DOWN decisions are local, not propagated via gossip)
T+10s+Hints accumulate on coordinators
T+recoveryNode restarts, hints replay

The driver detects and responds to node failures:

Driver Failure ResponseDriver Failure ResponseDetectionResponseRequest HandlingConnection Timeoutor Read TimeoutConnection HeartbeatFailureTopology Event(STATUS_CHANGE)Mark Node DOWNin connection poolSchedule Reconnection(exponential backoff)Route Requeststo other nodesRetry PolicyEvaluates errorRetry onNext HostPropagate Errorto Applicationretryablenon-retryable

With NetworkTopologyStrategy and rack-aware placement, Cassandra distributes replicas across racks:

Rack-Aware Replica Placement (RF=3)Rack-Aware Replica Placement (RF=3)Datacenter 1Rack 1Rack 2Rack 3Node 1Replica ANode 2Node 3Replica ANode 4Node 5Replica ANode 6Partition A
Rack Failure Scenario (RF=3, 3 Racks)Rack Failure Scenario (RF=3, 3 Racks)Healthy StateRack 2 FailedRack 12 nodes1 replicaRack 22 nodes1 replicaRack 32 nodes1 replicaRack 12 nodes1 replicaRack 2DOWNRack 32 nodes1 replicaResult:• 2 of 3 replicas available• QUORUM satisfied• ONE satisfied• ALL fails

Rack Failure Tolerance:

ConfigurationRacksRFRack Failure ToleranceNotes
Minimum13NoneAll replicas in same failure domain
Standard331 rackOne replica per rack
Enhanced351 rackAt least 2 replicas survive
High552 racksReplicas spread across 5 racks

Multi-Datacenter Topology (RF=3 per DC)Multi-Datacenter Topology (RF=3 per DC)DC1 (US-East)DC2 (US-West)DC3 (EU-West)Node 1Node 2Node 3Node 4Node 5Node 6Node 7Node 8Node 9asyncreplicationasyncreplication
Datacenter Failure ResponseDatacenter Failure ResponseServer ResponseClient Response (DC-Aware Policy)All DC1 nodesmarked DOWNHints storedfor DC1 nodesDC2/DC3 continueserving requestsLocal DCunavailableFailover toremote DCHigher latency(cross-DC)DC1 Fails(network partition or outage)

Consistency Level Behavior During DC Failure

Section titled “Consistency Level Behavior During DC Failure”
Consistency LevelDC1 DownBehavior
LOCAL_ONEFails for DC1 clients, succeeds for DC2/DC3
LOCAL_QUORUMFails for DC1 clients, succeeds for DC2/DC3
QUORUMDependsMay succeed if enough total replicas (e.g., RF=3×3=9, need 5)
EACH_QUORUMFails - requires quorum in each DC
ONESucceeds if any replica reachable
ALLFails - requires all replicas

The load balancing policy determines how requests are routed, including during failures:

Load Balancing Policy Decision FlowLoad Balancing Policy Decision FlowClient RequestToken-AwareIdentify replica nodesfor partition keyDC-AwarePrefer local DCFallback to remoteRack-Aware(Optional)Distribute across racksLatency-Aware(Optional)Prefer fastest nodesSelect Nodefrom filtered set

Policy Configuration for Fault Tolerance:

// Recommended production configuration
LoadBalancingPolicy policy = new TokenAwarePolicy(
DCAwareRoundRobinPolicy.builder()
.withLocalDc("dc1")
.withUsedHostsPerRemoteDc(2) // Failover capacity
.allowRemoteDCsForLocalConsistencyLevel() // Optional: allow remote DC for LOCAL_*
.build()
);

The retry policy determines whether and how to retry failed requests:

Retry Policy Decision FlowRetry Policy Decision FlowRequest ErrorReadTimeoutError Type?Read TimeoutData received?data received?yesnoRetrySame HostRetryNext HostWriteTimeoutUnavailableWrite TimeoutWrite type?idempotent?yesnoRetrySame HostRethrowto ApplicationUnavailableReplicas available?enough alive?yesnoRetryNext HostRethrowto Application

Error Types and Retry Behavior:

ErrorCauseDefault Retry Behavior
ReadTimeoutExceptionCoordinator timeout waiting for replicasRetry same host if data received
WriteTimeoutExceptionCoordinator timeout waiting for acksRetry only if idempotent (BATCH_LOG, UNLOGGED_BATCH)
UnavailableExceptionInsufficient replicas known aliveRetry on next host (once)
NoHostAvailableExceptionAll hosts exhaustedNo retry, propagate to application
OperationTimedOutExceptionClient-side timeoutNo retry, propagate to application

Speculative execution sends redundant requests to reduce tail latency:

Speculative Execution (delay=100ms)Speculative Execution (delay=100ms)TimelineT+0msSend to Node 1T+100msNo responseSend to Node 2T+150msNode 2 respondsCancel Node 1ClientNode 1(slow/failed)Node 2(fast)timeout

Speculative Execution Configuration:

// Speculative execution for read-heavy workloads
SpeculativeExecutionPolicy specPolicy =
new ConstantSpeculativeExecutionPolicy(
100, // Delay before speculation (ms)
2 // Maximum speculative executions
);
// Or percentile-based
SpeculativeExecutionPolicy percentilePolicy =
new PercentileSpeculativeExecutionPolicy(
tracker, // PercentileTracker
99.0, // Percentile threshold
2 // Maximum speculative executions
);

Node Recovery ProcessNode Recovery ProcessNode Restarts1. Gossip RejoinContact seeds/peersSync cluster state2. Hints ReplayReceive buffered writesfrom coordinators3. Read RepairFix inconsistencieson read path4. Full Repair(if needed)Anti-entropy syncFully Synchronized

Recovery Timeline:

PhaseDurationData Synchronized
Gossip rejoinSecondsCluster topology, schema
Hints replayMinutes-hoursWrites during downtime (if hints available)
Read repairOngoingData accessed by reads
Full repairHours-daysAll data (comprehensive)

Full repair should be run after recovery if:

ConditionReason
Downtime > max_hint_window_in_ms (default 3 hours)Hints expired, writes lost
Hints delivery failedCheck nodetool tpstats for dropped hints
Multiple node failuresHints may be incomplete
Consistency-critical dataEnsure complete synchronization
Datacenter Recovery ProcessDatacenter Recovery ProcessImmediate (Automatic)Manual (If Needed)Gossip SyncAll nodes rejoin clusterHints ReplayBuffered writes deliveredResume TrafficClients reconnectAssess Data LossCheck hint deliveryReview logsRepair DCnodetool repair -dc <dc>Verify ConsistencyCompare cross-DCDC Comes Onlineif prolonged outage

Application traffic before and after failover from the active dc1 to the standby dc2Application traffic before and after failover from the active dc1 to the standby dc2Normal OperationDuring DC1 FailureApplicationDC1 (Active)local_dc=dc1DC2 (Standby)receives async replicationApplicationDC1 (DOWN)DC2 (Active)failover triggeredall trafficreplicationfailover traffic
Active-Active Multi-DC PatternActive-Active Multi-DC PatternApplication LayerCassandra ClusterApp (US-East)local_dc=dc1App (US-West)local_dc=dc2DC1 (US-East)RF=3DC2 (US-West)RF=3locallocalfailoverfailoverasync replication

Active-Active Considerations:

AspectRecommendation
ConsistencyUse LOCAL_QUORUM for low latency
ConflictsLast-write-wins (LWW) by default; design for idempotency
FailoverAutomatic via driver DC-aware policy
CapacityEach DC sized to handle full load

MetricSourceFailure Indication
org.apache.cassandra.metrics.ClientRequest.TimeoutsJMXRequest timeouts increasing
org.apache.cassandra.metrics.ClientRequest.UnavailablesJMXInsufficient replicas
org.apache.cassandra.metrics.Storage.HintsJMXHints accumulating (node down)
org.apache.cassandra.metrics.DroppedMessage.*JMXMessages dropped under load
ConditionWarningCritical
Node DOWNAny nodeMultiple nodes
Rack DOWNN/AAny rack
Hints pending> 1000> 10000
Timeout rate> 0.1%> 1%
Unavailable rate> 0> 0.1%