Scenario 09.2.3 · Active-active multi-cluster
Active-active Kafka with MirrorMaker 2 and region topics
Each region OWNS a region-named topic (east.orders / west.orders) and mirrors it to the other; both topics live on both sides - local read+write, remote read-only - so there is no same-name ambiguity. An inter-region cut grows lag on both links.
Run this scenario in the playgroundTwo active regions - west and east each serve a local orders, mirroring to the other. t+0.000s
west and east are both live clusters. Each owns one topic (west.orders, east.orders) that it writes locally and mirrors to the other region over mm-w2e and mm-e2w, so both regions hold both topics. The mirror keeps the source name (IdentityReplicationPolicy), so there is no east.east.orders - but MM2 cannot detect cycles under that policy, so each link must replicate only its own region's topic.
Open at this step: step 1, Two active regions - west and east each serve a local orders, mirroring to the otherBoth regions committed one record locally - neither mirrored yet (lag 1 each way). t+0.900s
pw wrote Ow1 to west.orders in west and pe wrote Oe1 to east.orders in east (HW 1 each). Each region's consumer group has read its own local record (committed 1), but neither mirrored-in copy has it yet, so each link has lag 1.
Open at this step: step 2, Both regions committed one record locally - neither mirrored yet (lag 1 each way)Mirror converged - each region now holds the other region record via its remote topic (lag 0). t+1.700s
Both links copied their record at t=1500: west now holds east.orders at HW 1 and east holds west.orders at HW 1. cg-west and cg-east each consumed the mirrored-in record, so each group has seen both orders exactly once, one local and one remote.
Open at this step: step 3, Mirror converged - each region now holds the other region record via its remote topic (lag 0)Inter-region link cut - both regions keep accepting local writes; lag grows on both links (lag 1 each). t+2.600s
The regions were split at t=2000. Both keep accepting local writes: Ow2 lands in west.orders (HW 2) and Oe2 in east.orders (HW 2), and each group reads its local record. The mirrored-in copies stay at HW 1, so each region is missing the other's latest order.
Open at this step: step 4, Inter-region link cut - both regions keep accepting local writes; lag grows on both links (lag 1 each)Healed - both mirrors caught up, each region holds the full union (lag 0). t+3.600s
The network healed at t=3100 and both mirrors copied offset 1 at t=3500. Every copy of both topics is at HW 2, and cg-east and cg-west have each committed 2 on both topics. No write was lost - in active-active a cut only delays cross-region visibility.
Open at this step: step 5, Healed - both mirrors caught up, each region holds the full union (lag 0)What you start with
An active-active topology: two regions, each owning a region-prefixed topic (east.orders / west.orders) that it reads and writes locally and mirrors read-only into the other region. Namespacing topics by region avoids same-name collisions, and a per-region consumer group subscribed to both topics sees the global stream exactly once. We cut the inter-region link to watch lag grow on both mirror directions, then heal.
Step by step
- Two active regions - west and east each serve a local orders, mirroring to the other t+0.000s west and east are both live clusters. Each owns one topic (west.orders, east.orders) that it writes locally and mirrors to the other region over mm-w2e and mm-e2w, so both regions hold both topics. The mirror keeps the source name (IdentityReplicationPolicy), so there is no east.east.orders - but MM2 cannot detect cycles under that policy, so each link must replicate only its own region's topic. Open at this step: step 1, Two active regions - west and east each serve a local orders, mirroring to the other
- Both regions committed one record locally - neither mirrored yet (lag 1 each way) t+0.900s pw wrote Ow1 to west.orders in west and pe wrote Oe1 to east.orders in east (HW 1 each). Each region's consumer group has read its own local record (committed 1), but neither mirrored-in copy has it yet, so each link has lag 1. Open at this step: step 2, Both regions committed one record locally - neither mirrored yet (lag 1 each way)
- Mirror converged - each region now holds the other region record via its remote topic (lag 0) t+1.700s Both links copied their record at t=1500: west now holds east.orders at HW 1 and east holds west.orders at HW 1. cg-west and cg-east each consumed the mirrored-in record, so each group has seen both orders exactly once, one local and one remote. Open at this step: step 3, Mirror converged - each region now holds the other region record via its remote topic (lag 0)
- Inter-region link cut - both regions keep accepting local writes; lag grows on both links (lag 1 each) t+2.600s The regions were split at t=2000. Both keep accepting local writes: Ow2 lands in west.orders (HW 2) and Oe2 in east.orders (HW 2), and each group reads its local record. The mirrored-in copies stay at HW 1, so each region is missing the other's latest order. Open at this step: step 4, Inter-region link cut - both regions keep accepting local writes; lag grows on both links (lag 1 each)
- Healed - both mirrors caught up, each region holds the full union (lag 0) t+3.600s The network healed at t=3100 and both mirrors copied offset 1 at t=3500. Every copy of both topics is at HW 2, and cg-east and cg-west have each committed 2 on both topics. No write was lost - in active-active a cut only delays cross-region visibility. Open at this step: step 5, Healed - both mirrors caught up, each region holds the full union (lag 0)
The takeaway
Active-active runs both regions live by namespacing topics per region and mirroring bidirectionally - each side serves its local writes and reads the other’s via the mirror. An inter-region cut only stalls the mirrors; both regions keep serving local traffic.
Embed this scenario
Paste this into a blog post, a course page or your team's docs. The scenario plays inside your page, and the link under it points readers to this walkthrough.
<iframe src="https://monedula.dev/kafka-simulator/embed/?scenario=09.2.3" title="Kafka Simulator: Active-active multi-cluster" width="100%" height="520" style="border:1px solid #d0d0d0;border-radius:8px" loading="lazy"></iframe>
<p><a href="https://monedula.dev/kafka-simulator/scenarios/active-active/">Active-active Kafka with MirrorMaker 2 and region topics</a></p> Further reading
More in Disaster recovery
- Kafka stretched cluster across two data centers
- 2.5-DC Kafka stretched cluster with a witness site
- 3-DC Kafka cluster: the KRaft quorum survives losing a site
- Kafka in two DCs without a witness: KRaft quorum is lost
- Kafka data center failure: leader failover to the other DC
- Kafka network split inside one DC: ISR drops to the floor
- Kafka MirrorMaker 2 active-passive DR and replication lag
- Kafka DR failover with MirrorMaker 2: measuring RPO
- MirrorMaker 2 offset translation for Kafka consumer failover
- Kafka failback after a MirrorMaker 2 DR failover
- Active-active Kafka DR drill: move clients to the survivor
- Confluent MRC observers: Kafka replicas outside the ISR
- Kafka observer lag in Confluent Multi-Region Clusters
- Kafka observer promotion in Confluent Multi-Region Clusters
- Confluent MRC observer promotion: losing the Kafka leader DC
- Kafka replica placement: durability vs latency across DCs
- Confluent Cluster Linking: offset-preserving Kafka mirroring
- Kafka mirror topics (Confluent): read-only until promoted
- Cluster Linking vs MirrorMaker 2 for Kafka replication
- Kafka consumer offset sync: Cluster Linking vs MirrorMaker 2
- Kafka failover and failback with Confluent Cluster Linking