Green on Every Dashboard, Refusing Every Write
One Annotation Instead of Ninety Lines
// Gradle
testImplementation 'com.macstab.chaos:macstab-chaos-redis:1.0.0'
@RedisSentinel // 1 master + 2 replicas + 3 sentinels, quorum 2
class FailoverTest { }
Six Containers, in the Only Order That Works
Quorum Is Not the Election Majority
Linux-Only, and Honest About It
Failover as an Assertion
@RedisSentinel(replicas = 2, sentinels = 3)
class FailoverTest {
@Test
void promotesWithinSlo(SentinelCluster cluster) {
Duration elapsed = cluster.getControl().triggerFailover(Duration.ofSeconds(30));
assertThat(elapsed).isLessThan(Duration.ofSeconds(15));
assertThat(cluster.getControl().getMaster().isRunning()).isTrue();
}
}
Real Faults on a Real Topology
- @IncidentChaosRedisNetworkFlap: ECONNRESET on connect and recv, producing an election storm rather than a clean failover
- @IncidentChaosRedisFailoverStorm: ECONNREFUSED on connect, EAI_AGAIN on DNS lookups and a CLOCK_REALTIME offset
- @IncidentChaosRedisClockDrift: inter-node clock skew, TTL expiry races and Sentinel miscalculating its own timeouts
- @IncidentChaosRedisOomEviction, @IncidentChaosRedisCacheAvalanche and @IncidentChaosRedisSlowlog: eviction pressure, synchronised expiry storms and SLOWLOG-level latency
tags
conclusion
Christian Schnapka
Macstab Engineering
Christian Schnapka builds the open engineering tools behind Macstab. He publishes the long-form versions of these investigations on Medium — every measurement, every caveat and every loss included.