Build a wide-column store (Cassandra / DynamoDB family) (13 scenes)
Scene 09 · Partition forces a choice
Split the cluster in two; one side keeps quorum, the other goes unavailable — or you accept divergence.
Previously
W+R>N gave us read-your-writes when every replica is reachable; once the network splits the cluster in two, the minority side can no longer count to a majority.
Scene 09
Partition forces a choice
Diagram
An RF=3 ring of 8 nodes sliced by a dashed **network partition** into a 5-node majority side (left) and a 3-node minority side (right). The featured key's three replicas land 2 on the majority side and 1 on the minority. The coordinator lives on the majority side. The verdict box on the right reads off which side can serve under the current consistency level. **Network partition** = a temporary loss of connectivity between subsets of nodes; the cluster splits into two reachable groups. **CAP** = Brewer's theorem: during a partition you must choose between consistency or availability — you cannot have both simultaneously.
← network partition: cluster split, sides cannot reach each other
majority side · 2 of 3 replicas · coordinator here
minority side · only 1 of 3 replicas reachable
CAP: during a partition you must choose C or A →
The cluster has split. A dashed line marks the network partition: 5 nodes on side A (with the coordinator), 3 on side B. The featured key has 3 replicas — 2 on the majority side, 1 on the minority. The verdict box on the right reads off whether the cluster can serve this key under the current consistency level.
Implementation
Coordinator.coordinator_reach
count replicas reachable from THIS side of the cut
1def coordinator_reach(key):2 replicas = ring.replicas_for(key) # RF nodes3 reachable = []4 for r in replicas:5 if can_route_to(r): # ping / gossip view6 reachable.append(r)7 # on a partition this is sideA-only count8 return reachable
Coordinator.write_under_partition
fail fast if the chosen quorum can't be formed
1def write(key, value, CL):2 reach = coordinator_reach(key)3 needed = quorum(CL, RF)4 # ONE → 1 · QUORUM → floor(RF/2)+1 · ALL → RF5 if len(reach) < needed:6 return Unavailable7 for r in reach:8 send_async(r, Write(key, value))9 wait_for(reach, count=needed)10 return Ack
Coordinator.quorum
the size of the smallest majority for the chosen CL
1def quorum(CL, RF):2 if CL == 'ONE':3 return 14 if CL == 'QUORUM':5 return RF // 2 + 1 # 2 when RF=36 if CL == 'ALL':7 return RF # 3 when RF=3