Kafka MirrorMaker
Kafka MirrorMaker is a tool provided by Apache Kafka that copies (replicates) data from one Kafka cluster to another. In simple words, it keeps topics in two different Kafka clusters in sync.
This guide explains why cross-cluster replication is needed, how MirrorMaker 2 works internally, how to configure and run it step by step, how topic names and consumer offsets are handled during failover, and how to monitor it, with formatted configuration, command-line and Java examples. It builds on Kafka Cluster and Kafka Connect.
1. What Is Kafka MirrorMaker?
Think of MirrorMaker as a bridge between two Kafka clusters. Messages produced to selected topics in the source cluster are automatically copied to the target cluster, usually within seconds.
Cluster A (source) Cluster B (target)
+--------------------+ +--------------------+
| orders | +------------+ | A.orders |
| payments | -> | MirrorMaker| -> | A.payments |
| consumer offsets | | 2 | | translated offsets|
+--------------------+ +------------+ +--------------------+
MirrorMaker is commonly used for:
- Disaster recovery.
- Multi-data-center and multi-region setups.
- Migrating data between Kafka clusters.
- Sharing data across teams or regions.
2. Why Do We Need Kafka MirrorMaker?
Kafka already replicates each partition across brokers inside one cluster, which protects against a broker or disk failure. It does not protect against losing a whole cluster or data center, and a single cluster stretched across distant regions would be slow.
In real-world systems, companies often run Kafka clusters in several locations, for example one in India and another in the US. If one cluster goes down, the data should still be available in the other. MirrorMaker continuously copies messages between clusters, so both have the same data.
| Replication type | Protects against | Handled by |
|---|---|---|
| Inside one cluster | Broker, disk or rack failure | Kafka partition replicas (replication factor) |
| Between clusters | Data center or region outage, migration needs, data sharing | MirrorMaker 2 or similar tools |
3. Key Features of Kafka MirrorMaker
| Feature | Explanation |
|---|---|
| Cross-cluster replication | Copies topics from a source cluster to a target cluster, even across data centers or regions |
| Built on Kafka clients | Internally uses consumers to read from the source and producers to write to the target |
| Topic selection | Replicates one topic, a list, or patterns such as all topics starting with orders |
| Config and ACL sync | Copies topic settings, partition counts and ACLs to the target |
| Offset translation | Records how source offsets map to target offsets so consumers can fail over |
| Fault tolerant | Runs on Kafka Connect; if a worker fails, its tasks move to the others and resume from saved progress |
| Scalable | Replication is split into tasks that run in parallel on several workers |
| Near real-time | Messages are copied continuously, typically within seconds |
4. MirrorMaker 1 vs MirrorMaker 2
Kafka has had two generations of the tool:
| Aspect | MirrorMaker 1 (legacy) | MirrorMaker 2 |
|---|---|---|
| Built on | A simple consumer and producer pair | Kafka Connect connectors |
| Topic configuration sync | No | Yes, including partition counts and ACLs |
| New topics | Picked up through a topic pattern | Detected automatically at a regular interval |
| Consumer offset translation | No | Yes, through checkpoints |
| Loop prevention for two-way replication | No | Yes, through remote topic names |
| Status | Deprecated, and removed in Kafka 4.0 | The supported tool |
For all new projects, use MirrorMaker 2 (often written MM2). The rest of this tutorial covers MirrorMaker 2.
5. How MirrorMaker 2 Works
MirrorMaker 2 is a set of three Kafka Connect connectors that work together:
| Connector | Job |
|---|---|
| MirrorSourceConnector | Copies records from source topics to remote topics in the target, and syncs topic configs and ACLs |
| MirrorCheckpointConnector | Translates consumer group offsets and writes them as checkpoints in the target |
| MirrorHeartbeatConnector | Sends regular heartbeat records so you can check that replication is alive |
MirrorMaker 2 also creates a few internal topics:
| Internal topic | Purpose |
|---|---|
heartbeats | Heartbeat records showing that the link between clusters is working |
A.checkpoints.internal | Translated consumer offsets for groups from cluster A, stored in the target |
mm2-offset-syncs.B.internal | Mapping between source and target offsets, stored in the source by default |
mm2-configs, mm2-offsets, mm2-status topics | Kafka Connect’s own state for the MirrorMaker 2 connectors |
6. Simple Example of Kafka MirrorMaker
Let’s understand this with a simple scenario:
- Source cluster: Kafka cluster A (India).
- Target cluster: Kafka cluster B (US).
- Topic:
order-events.
An application produces order messages to order-events in cluster A. MirrorMaker 2 is configured to:
- Consume messages from
order-eventsin cluster A. - Produce the same messages to
A.order-eventsin cluster B. TheA.prefix shows where the data came from. - Translate the offsets of consumer groups reading in cluster A, so they can continue in cluster B.
Whenever a new order message is published in cluster A, it appears in cluster B shortly afterwards. If cluster A goes down, applications can read the order data from cluster B and continue close to where they stopped.
7. Running MirrorMaker 2 Step by Step
The simplest way to run MirrorMaker 2 is dedicated mode, using a script and one properties file that ship with Kafka.
Step 1: Create the configuration file
# Names (aliases) for the two clusters
clusters = A, B
A.bootstrap.servers = kafka-a1:9092,kafka-a2:9092
B.bootstrap.servers = kafka-b1:9092,kafka-b2:9092
# Enable replication from A to B
A->B.enabled = true
# Topics and consumer groups to replicate (regular expressions)
A->B.topics = order-events, payments.*
A->B.groups = .*
# Translate consumer offsets into cluster B every 60 seconds
A->B.sync.group.offsets.enabled = true
# Replication factor for the copied topics in cluster B
replication.factor = 3
# Replication factor for MirrorMaker 2 internal topics
checkpoints.topic.replication.factor = 3
heartbeats.topic.replication.factor = 3
offset-syncs.topic.replication.factor = 3
offset.storage.replication.factor = 3
status.storage.replication.factor = 3
config.storage.replication.factor = 3
# Parallel tasks for copying data
tasks.max = 4
Step 2: Start MirrorMaker 2
bin/connect-mirror-maker.sh config/mm2.properties
Run the same command on two or more machines for high availability. The instances form a group and share the work automatically.
Step 3: Check the replicated topic
# List topics in the target cluster
bin/kafka-topics.sh --bootstrap-server kafka-b1:9092 --list
# Read the mirrored messages
bin/kafka-console-consumer.sh --bootstrap-server kafka-b1:9092 \
--topic A.order-events --from-beginning
Place MirrorMaker 2 close to the target cluster. Reading over a long network link and writing locally is more reliable than the other way round.
8. Remote Topic Names and Replication Policies
By default, MirrorMaker 2 uses the DefaultReplicationPolicy, which names each copied topic <source alias>.<topic>. These copies are called remote topics.
| Source cluster topic | Target cluster topic |
|---|---|
order-events in A | A.order-events in B |
payments-in in A | A.payments-in in B |
The prefix has two benefits: you can always see where data came from, and two-way replication cannot loop, because MirrorMaker 2 never copies A.order-events back to cluster A.
If you need identical names, for example during a one-way migration, use the IdentityReplicationPolicy:
replication.policy.class = org.apache.kafka.connect.mirror.IdentityReplicationPolicy
With identical names, MirrorMaker 2 cannot tell local and copied topics apart, so use this policy only for one-way replication.
9. Consumer Offset Translation and Failover
Offsets in cluster B are different from offsets in cluster A: the same message may be at offset 5,000 in A and offset 1,200 in B. A consumer cannot simply reuse its old offset after failing over.
MirrorMaker 2 solves this with checkpoints. It regularly records how source offsets map to target offsets and writes each group’s translated position to the target cluster. With sync.group.offsets.enabled=true, it also commits these positions directly to the target’s consumer offsets, so a consumer that switches to cluster B with the same group.id starts close to where it stopped.
1. Cluster A fails.
2. Stop consumers that were reading from cluster A.
3. Point consumers to cluster B (topic A.order-events, same group.id).
4. Consumers resume from the translated offsets.
5. A few recently processed messages may be read again.
Translation is not exact to the last message, and the newest messages may not have been copied when cluster A failed. Design consumers to be idempotent, so a few repeated messages cause no harm.
10. Working with Mirrored Topics in Java
A consumer in cluster B can read both the local topic and the remote copy with a regular-expression subscription:
package com.example.kafka;
import java.time.Duration;
import java.util.Properties;
import java.util.regex.Pattern;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
public class MirroredOrdersConsumer {
public static void main(String[] args) {
Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka-b1:9092");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "order-reporting");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
try (KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props)) {
// matches "order-events" and remote copies such as "A.order-events"
consumer.subscribe(Pattern.compile("(.*\\.)?order-events"));
while (true) {
for (ConsumerRecord<String, String> record : consumer.poll(Duration.ofMillis(500))) {
System.out.printf("topic=%s offset=%d value=%s%n",
record.topic(), record.offset(), record.value());
}
}
}
}
}
To look up translated offsets yourself, for example in a failover script, use RemoteClusterUtils from the connect-mirror-client library:
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>connect-mirror-client</artifactId>
<version>4.0.0</version>
</dependency>
package com.example.kafka;
import java.time.Duration;
import java.util.Map;
import org.apache.kafka.clients.consumer.OffsetAndMetadata;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.connect.mirror.RemoteClusterUtils;
public class TranslateOffsets {
public static void main(String[] args) throws Exception {
// connection settings for the TARGET cluster (B)
Map<String, Object> targetProps = Map.of("bootstrap.servers", "kafka-b1:9092");
Map<TopicPartition, OffsetAndMetadata> offsets =
RemoteClusterUtils.translateOffsets(
targetProps,
"A", // alias of the source cluster
"order-service", // consumer group
Duration.ofSeconds(30));
offsets.forEach((partition, offset) ->
System.out.println(partition + " -> " + offset.offset()));
}
}
The returned map can be passed to consumer.commitSync(offsets), or used with seek(), before the consumer starts reading from cluster B.
11. Replication Topologies: Active-Passive and Active-Active
| Topology | How it works | Typical use |
|---|---|---|
| Active-passive | A → B only; applications use A, and B is a standby copy | Disaster recovery |
| Active-active | A → B and B → A; each region has local producers and reads both local and remote topics | Multi-region applications with low local latency |
| Hub and spoke | Several edge clusters replicate into one central cluster | Central analytics, aggregating data from many sites |
| Migration | Old → new cluster, often with identical topic names, until clients switch | Moving to new hardware, cloud or version |
clusters = A, B
A.bootstrap.servers = kafka-a1:9092
B.bootstrap.servers = kafka-b1:9092
A->B.enabled = true
A->B.topics = order-events
B->A.enabled = true
B->A.topics = order-events
Here cluster B ends up with order-events (local writes) and A.order-events (copied from A), and cluster A has the mirror image. Consumers that need all orders subscribe to both topics, as in the Java pattern above.
12. Running MirrorMaker 2 on a Kafka Connect Cluster
If you already run a Kafka Connect cluster, you can deploy the MirrorMaker 2 connectors there through the Connect REST API instead of using the dedicated script:
curl -X POST http://connect:8083/connectors \
-H "Content-Type: application/json" \
-d '{
"name": "mm2-source-A-to-B",
"config": {
"connector.class": "org.apache.kafka.connect.mirror.MirrorSourceConnector",
"source.cluster.alias": "A",
"target.cluster.alias": "B",
"source.cluster.bootstrap.servers": "kafka-a1:9092",
"target.cluster.bootstrap.servers": "kafka-b1:9092",
"topics": "order-events",
"tasks.max": "4"
}
}'
Create MirrorCheckpointConnector and MirrorHeartbeatConnector the same way. This mode gives you Connect’s REST API and existing monitoring, but needs more configuration; dedicated mode is simpler to start with.
13. Monitoring MirrorMaker 2
| What to watch | Why it matters |
|---|---|
replication-latency-ms | Time between a record being written in the source and copied to the target |
record-age-ms | Age of records when MirrorMaker reads them; a growing value means it is falling behind |
| Consumer lag of MirrorMaker on the source | Messages waiting to be copied |
| Connector and task status | Failed tasks stop replication for their partitions |
heartbeats topic in the target | New heartbeat records prove that the link between clusters is working |
These metrics are exposed through JMX, so they can be collected with tools such as Prometheus and shown in dashboards. Alert when replication latency keeps rising or when heartbeats stop arriving.
14. Real-World Use Cases
| Use case | How MirrorMaker 2 helps |
|---|---|
| Disaster recovery | Keeps a standby cluster with recent data and translated offsets, ready for failover |
| Geo-replication | Shares data across regions so local applications read from a nearby cluster |
| Data migration | Moves topics from an old cluster to a new one while both keep running |
| Analytics | Copies production data to a separate analytics cluster, so heavy reports do not affect production |
| Edge to cloud | Collects data from many smaller clusters, such as factories or stores, into one central cluster |
15. Limitations to Know
- Asynchronous copy: if the source fails, the newest messages may not have reached the target yet.
- At-least-once by default: after a restart, some records may be copied twice. Newer Kafka versions can be configured for exactly-once copying, but it needs extra setup.
- Different offsets: offsets in the target do not match the source; consumers rely on offset translation.
- Network cost: all replicated data crosses the network between sites, which can be slow or expensive.
- Not a backup of everything: it does not copy broker settings, users or data from topics you did not select.
16. Best Practices
| Do | Avoid |
|---|---|
| Use MirrorMaker 2 for all new setups | Starting new projects with the legacy MirrorMaker 1 |
| Run MirrorMaker 2 near the target cluster | Writing to a distant cluster over a slow link |
| Run at least two instances for high availability | A single MirrorMaker process for important data |
| Use replication factor 3 for remote and internal topics | Leaving low defaults on production copies |
| Keep the default replication policy for two-way replication | Identity names with active-active, which can create loops |
| Enable offset sync and practise failover regularly | Discovering failover problems during a real outage |
| Make consumers idempotent | Assuming no message is ever repeated after failover |
| Monitor replication latency and heartbeats | Noticing broken replication only when it is needed |
| Secure both connections with TLS and authentication | Sending data between data centers unencrypted |
17. Summary
Kafka MirrorMaker is a simple and powerful tool for replicating Kafka topics from one cluster to another. MirrorMaker 2, built on Kafka Connect, is the version to use today: it copies records, topic settings and ACLs, renames copied topics to show their source and prevent loops, translates consumer offsets for failover, and reports its health through heartbeats and metrics. Configure it with a single properties file, run several instances near the target cluster, and plan for asynchronous replication by making consumers idempotent.
By copying messages in near real time, MirrorMaker helps build reliable, scalable and fault-tolerant systems, and it is an essential component for anyone running Kafka across several data centers or regions.
18. Frequently Asked Questions (FAQ)
Q1. What is Kafka MirrorMaker in simple words?
Kafka MirrorMaker is a tool that copies messages from topics in one Kafka cluster to another, continuously and in near real time. It acts like a bridge that keeps two clusters in sync.
Q2. Should I use MirrorMaker 1 or MirrorMaker 2?
Use MirrorMaker 2. MirrorMaker 1 was deprecated and removed in Kafka 4.0. MirrorMaker 2 adds topic config sync, automatic detection of new topics, consumer offset translation and loop prevention.
Q3. Why not just add more replicas instead of using MirrorMaker?
Replicas protect data inside one cluster against broker or disk failures. They do not help if the whole cluster or data center is lost, and stretching one cluster across distant regions makes every write slow. MirrorMaker copies data to a separate cluster asynchronously.
Q4. Is MirrorMaker 2 a separate product?
No. It is part of Apache Kafka and ships with it. You start it with bin/connect-mirror-maker.sh, or run its connectors on an existing Kafka Connect cluster.
Q5. Why does my mirrored topic have a prefix like A.orders?
The default replication policy names copied topics <source alias>.<topic>. The prefix shows where the data came from and prevents loops in two-way replication. To keep the same names, set replication.policy.class to IdentityReplicationPolicy, but only for one-way replication.
Q6. How do I choose which topics to replicate?
Use regular expressions in the configuration:
A->B.topics = order-events, payments.*
A->B.topics.exclude = .*internal.*
New topics that match the pattern are detected automatically, every 10 minutes by default.
Q7. Does MirrorMaker 2 copy topic settings and partitions?
Yes. It creates remote topics with the same number of partitions, syncs topic configurations such as retention, and by default syncs ACLs. If you add partitions to a source topic, the remote topic is updated too.
Q8. Are offsets the same in the source and target clusters?
No. The same message usually has a different offset in each cluster. MirrorMaker 2 stores a mapping between them and uses it to translate consumer group offsets, so consumers can continue in the target cluster.
Q9. How do consumers fail over to the target cluster?
Enable sync.group.offsets.enabled=true so translated offsets are committed in the target. During failover, stop the consumers, point them to the target cluster and the remote topic (such as A.orders) with the same group.id, and start them again. They resume close to where they stopped.
Q10. Can MirrorMaker lose or duplicate messages?
Replication is asynchronous, so if the source cluster fails suddenly, the newest messages may not have been copied yet. By default delivery is at-least-once, so some records can be copied twice after a restart. Newer Kafka versions can be configured for exactly-once copying with extra setup.
Q11. Can MirrorMaker replicate in both directions?
Yes, this is called active-active. Enable A->B and B->A. With the default replication policy, copied topics get a prefix, so records are never copied back to the cluster they came from.
Q12. Where should MirrorMaker 2 run?
Run it close to the target cluster. Consuming over a long network link and producing locally is more reliable than producing over the long link. Run at least two instances so replication continues if one fails.
Q13. How do I scale MirrorMaker 2?
Increase tasks.max so the work is split into more parallel tasks, and run more MirrorMaker instances to share those tasks. The useful maximum is roughly the total number of partitions being replicated.
Q14. What are the heartbeats and checkpoints topics?
heartbeats receives regular records that prove replication between two clusters is working. <source>.checkpoints.internal stores translated consumer group offsets in the target cluster. Both are internal to MirrorMaker 2.
Q15. How do I monitor MirrorMaker 2?
Watch the JMX metrics replication-latency-ms and record-age-ms, the lag of MirrorMaker’s consumers on the source, the status of connectors and tasks, and whether new heartbeat records arrive. Alert when latency keeps rising or heartbeats stop.
Q16. Can I use MirrorMaker to migrate to a new Kafka cluster?
Yes. Replicate the topics and consumer groups to the new cluster, often with IdentityReplicationPolicy to keep topic names. When the copy has caught up, move consumers, then producers, to the new cluster and stop MirrorMaker.
Q17. Does MirrorMaker work with secured clusters?
Yes. Add security settings per cluster alias in the configuration:
A.security.protocol = SASL_SSL
A.sasl.mechanism = SCRAM-SHA-512
A.sasl.jaas.config = org.apache.kafka.common.security.scram.ScramLoginModule required \
username="mm2" password="${file:/etc/mm2/secrets.properties:a.password}";
Give the MirrorMaker user only the permissions it needs, and keep passwords out of the file with a config provider.
Q18. Can MirrorMaker copy data between different Kafka versions?
Yes. Kafka clients work with older and newer brokers, so MirrorMaker 2 can replicate between clusters running different versions. This makes it useful for upgrades and migrations. Check that both clusters support the features you use, such as the message format.
Q19. How can a Java application read both local and mirrored topics?
Subscribe with a pattern that matches both names:
consumer.subscribe(Pattern.compile("(.*\\.)?order-events"));
This matches order-events as well as remote copies such as A.order-events.
Q20. What are alternatives to MirrorMaker 2?
Some commercial Kafka platforms and managed cloud services offer their own cluster replication features, which can keep offsets identical or need less setup. MirrorMaker 2 is the free, open-source option included with Apache Kafka and works with any Kafka cluster.