...
| Code Block |
|---|
|
# 9091 (source) -----> 9094 (destination)
# in case of disaster, the operator can failover by running the following command
bin/kafka-mirror.sh --bootstrap-server :9094 --removestop --topic .* --mirror my-mirror
# 9091 (source) --x--> 9094 (destination)
# now all mirror topics are detached from the source cluster and accept writes (the two clusters are allowed to diverge) |
...
| Code Block |
|---|
|
# when the source cluster is back, the operator can failback by creating a mirror with the same name
echo "bootstrap.servers=localhost:9094" > /tmp/my-mirror.properties
bin/kafka-mirrors.sh --bootstrap-server :9091 --create --mirror my-mirror --mirror-config /tmp/my-mirror.properties
bin/kafka-mirrors.sh --bootstrap-server :"9091 --addstart --topic .* --mirror my-mirror
# 9091 (destination) <----- 9094 (source) |
...
| Code Block |
|---|
|
$ bin/kafka-mirrors.sh --help
This tool helps to create cluster mirrors and addmanage mirrored topics to them.
Option Description
------ -----------
--add Add topic(s) to an existing cluster
mirror (supports regex).
--alter Alter the configuration of an existing
cluster mirror.
--bootstrap-server <String: server to REQUIRED: The destination Kafka server
connect to> to connect to.
--command-config <String: command Property file containing configs to be
config property file> passed to Admin Client.
--create Create a new cluster mirror from a
source cluster.
--describedelete DescribeDelete a cluster mirror. including
--describe Describe a partitioncluster lagmirror andincluding state.
--help partition lag Printand usage informationstate.
--listhelp ListPrint allusage clusterinformation. mirrors.
--mirrorjson <String: mirror> The name of the cluster mirror.
--mirror-config <String: mirror config Property file containing source Output description in JSON format
--list
property file> clusterList configsall forcluster mirroringmirrors.
--pause
--mirror <String: mirror> The name of the cluster mirror. Pause mirroring for topic(s) matching
--mirror-config <String: mirror config Property file containing source
property file> thecluster patternconfigs (supportsfor regex)mirroring.
--removepause Pause mirroring Removefor topic(s) from an existing matching
clusterthe mirrorpattern (supports regex).
--replication-factor <Short: The replication factor to use for the
replication-factor> mirror topic. If not specified, uses
the destination cluster's default.
--resume Resume mirroring for previously paused
topic(s) matching the pattern
(supports regex).
--start Start mirroring topic(s) in an
existing cluster mirror (supports
regex).
--stop Stop mirroring topic(s) in an existing
(supports regex). cluster mirror (supports regex).
--topic <String: topic> Topic name or regex pattern to match
topics (e.g., 'my-topic' or 'test-.
*').
--version Display Kafka version. |
...
| Code Block |
|---|
|
$ echo "bootstrap.servers=localhost:9092" >/tmp/mirror.properties
$ bin/kafka-mirror.sh --bootstrap-server :9094 --create --mirror my-mirror --mirror-config /tmp/mirror.properties
Created mirror my-mirror |
Add Start mirroring a topic or set of topics to an existing cluster mirror (start mirroring; the topic flag accepts regex expression):
| Code Block |
|---|
|
$ bin/kafka-mirror.sh --bootstrap-server :9094 --addstart --topic my-topic --mirror my-mirror
Added 1 topic(s) to mirror my-mirror: [my-topic] |
Remove Stop mirroring a specific topic or set of topics from a mirror (failover; topics become writable):
| Code Block |
|---|
|
$ bin/kafka-mirror.sh --bootstrap-server :9094 --removestop --topic my-topic --mirror my-mirror
Removed 1 topic(s) from mirror my-mirror: [my-topic] |
...
| Code Block |
|---|
|
/**
* Create a new cluster mirror.
*
* @param mirrorName The name of the cluster mirror
* @param configs Configuration for the cluster mirror, including bootstrap servers and security settings
* @param options Options for the create mirror operation
* @return The CreateMirrorResult
*/
CreateMirrorResult createMirror(String mirrorName, Map<String, String> configs, CreateMirrorOptions options);/**
/** * Create a new cluster mirror.
*
* @param mirrorName The name of the cluster mirror
* Add@param topicsconfigs toConfiguration anfor existingthe cluster mirror, including bootstrap servers and security settings
* @param options Options for the create mirror operation
* @return The CreateMirrorResult
*/
CreateMirrorResult createMirror(String mirrorName, Map<String, String> configs, CreateMirrorOptions options);
/**
* Start mirroring for the cross-clusterspecified replicationtopics.
*
* When topics are addedstarted toin a mirror, they become read-only on the destination cluster and start
* replicating data from the source cluster. This operation marks the specified topics with the
* mirror name, preventing local writes and enabling the MirrorFetcherThread to begin replication.
*
* @param mirrorName The cluster mirror name to add the topics to
* @param topics Set of topic names to add tostart mirroring
* @param options Options for the add topics tostart mirror topics operation
* @return The AddTopicsToMirrorResultStartMirrorTopicsResult containing futures for each topic addition
*/
AddTopicsToMirrorResultStartMirrorTopicsResult addTopicsToMirrorstartMirrorTopics(String mirrorName, Set<String> topics, AddTopicsToMirrorOptionsStartMirrorTopicsOptions options);
/**
* RemoveStop topics from cluster mirror, making them writable on the destination clustermirroring for the specified topics.
*
* This operation is typically used during failover scenarios when the destination cluster needs to
* be promoted from passive (read-only mirror) to active (accepting writes). Stopping Removingmirror topics from
* the mirror clears the mirrorName field from partition metadata, which allows producers to write
* to these partitions.
*
* @param mirrorName The cluster mirror name to remove the topics from
* @param topics Set of topic names to removestop from mirroring
* @param options Options for the stop removemirror topics from mirror operation
* @return The RemoveTopicsFromMirrorResultStopMirrorTopicsResult containing futures for each topic removal
*/
RemoveTopicsFromMirrorResultStopMirrorTopicsResult removeTopicsFromMirrorstopMirrorTopics(String mirrorName, Set<String> topics, RemoveTopicsFromMirrorOptionsStopMirrorTopicsOptions options);
/**
* Pause mirroring for the specified topics.
*
* Paused topics remain read-only on the destination cluster but stop fetching new data from the
* source cluster. The mirror fetcher threads are removed for these partitions, preserving the
* current replicated state. Mirroring can be resumed later with {@link #resumeMirrorTopics}.
*
* @param mirrorName The cluster mirror name to pause the topics for
* @param topics Set of topic names to pause mirroring for
* @param options Options for the pause mirror topics operation
* @return The PauseMirrorTopicsResult containing futures for each topic
*/
PauseMirrorTopicsResult pauseMirrorTopics(String mirrorName, Set<String> topics, PauseMirrorTopicsOptions options);
/**
* Resume mirroring for previously paused topics.
*
* Resumed topics restart fetching data from the source cluster, picking up from where they
* left off. New mirror fetcher threads are created and the partitions transition back to the
* MIRRORING state.
*
* @param mirrorName The cluster mirror name to resume the topics for
* @param topics Set of topic names to resume mirroring for
* @param options Options for the resume mirror topics operation
* @return The ResumeMirrorTopicsResult containing futures for each topic
*/
ResumeMirrorTopicsResult resumeMirrorTopics(String mirrorName, Set<String> topics, ResumeMirrorTopicsOptions options);
/**
* Delete a cluster mirror including its configuration.
*
* The mirror must be empty (no topics) or all its topics must have been removed (in STOPPED
* state). After deletion, all mirror metadata are tombstoned and failback is no longer possible.
*
* @param mirrorName The name of the cluster mirror to deletename
* @param options Options for the delete mirror operation
* @return The DeleteMirrorResult
*/
DeleteMirrorResult deleteMirror(String mirrorName, DeleteMirrorOptions options);
/**
* List the cluster mirrors available in the cluster.
*
* @param options The options to use when listing the mirrors.
* @return The ListMirrorsResult.
*/
ListMirrorsResult listMirrors(ListMirrorsOptions options);
/**
* Describe cluster mirrors.
*
* This operation retrieves detailed information about cluster mirrors including:
* - Topics being mirrored
* - Partition-level lag information (source offset vs destination offset)
* - Mirroring state for each partition (INITIALIZING, PREPARING, MIRRORING, etc.)
*
* @param mirrorNames The names of the mirrors to describe
* @param options The options to use when describing mirrors
* @return The DescribeMirrorsResult
*/
DescribeMirrorsResult describeMirrors(Collection<String> mirrorNames, DescribeMirrorsOptions options); |
...
| Code Block |
|---|
{
"apiKey": TBD,
"type": "response",
"name": "CreateMirrorResponse",
// Version 0 is the initial version.
"validVersions": "0",
"flexibleVersions": "0+",
"fields": [
{ "name": "ThrottleTimeMs", "type": "int32", "versions": "0+",
"about": "The duration in milliseconds for which the request was throttled due to a quota violation, or zero if the request did not violate any quota." },
{ "name": "ErrorCode", "type": "int16", "versions": "0+",
"about": "The error code, or 0 if there was no error." },
{ "name": "ErrorMessage", "type": "string", "versions": "0+", "nullableVersions": "0+",
"about": "The error message, or null if there was no error." }
]
} |
AddTopicsToMirror
StartMirrorTopics
Start mirroring for the specified topicsAdds topics to a specified mirror. The broker validates that all target topic partitions are in either UNKNOWN or STOPPED state; otherwise, the request is rejected with an INVALID_REQUEST error. Once validated, the request is forwarded to the controller, which sets the mirror.name topic config to the specified mirror name.
...
StartMirrorTopicsRequest
| Code Block |
|---|
{
"apiKey": TBD,
"type": "request",
"listeners": ["broker", "controller"],
"name": "AddTopicsToMirrorRequestStartMirrorTopicsRequest",
// Version 0 is the initial version.
"validVersions": "0",
"flexibleVersions": "0+",
"fields": [
{ "name": "MirrorName", "type": "string", "versions": "0+", "entityType": "mirrorName",
"about": "The cluster mirror name." },
{ "name": "Topics", "type": "[]TopicData", "versions": "0+", "about": "The data for the topics.",
"fields": [
{ "name": "TopicId", "type": "uuid", "versions": "0+", "about": "The unique topic ID."},
{ "name": "TopicName", "type": "string", "versions": "0+", "mapKey": true, "entityType": "topicName",
"about": "The topic name." }
]}
]
} |
...
StartMirrorTopicsResponse
| Code Block |
|---|
{
"apiKey": TBD,
"type": "response",
"name": "AddTopicsToMirrorResponseStartMirrorTopicsResponse",
// Version 0 is the initial version.
"validVersions": "0",
"flexibleVersions": "0+",
"fields": [
{ "name": "ThrottleTimeMs", "type": "int32", "versions": "0+",
"about": "The duration in milliseconds for which the request was throttled due to a quota violation, or zero if the request did not violate any quota." },
{ "name": "ErrorCode", "type": "int16", "versions": "0+",
"about": "The error code, or 0 if there was no error." },
{ "name": "ErrorMessage", "type": "string", "versions": "0+", "nullableVersions": "0+", "default": "null",
"about": "The top-level error message, or null if there was no error." },
{ "name": "MirrorName", "type": "string", "versions": "0+", "entityType": "mirrorName",
"about": "The cluster mirror name." },
{ "name": "Topics", "type": "[]TopicResult", "versions": "0",
"about": "The results for the topics.", "fields": [
{ "name": "Name", "type": "string", "versions": "0", "entityType": "topicName",
"about": "The topic name." },
{ "name": "ErrorCode", "type": "int16", "versions": "0",
"about": "The error code, or 0 if there was no error." }
]}
]
} |
RemoveTopicsFromMirror
StopMirrorTopics
Stop mirroring for the specified topicsAllows users to detach topics from their associated mirror. The broker validates that all target topic partitions are in either PREPARING or MIRRORING state. Once validated, the request is forwarded to the controller, which appends the ".removed" suffix to the mirror.name topic config to mark the topics as no longer mirrored.
...
StopMirrorTopicsRequest
| Code Block |
|---|
{
"apiKey": TBD,
"type": "request",
"listeners": ["broker", "controller"],
"name": "RemoveTopicsFromMirrorRequestStopMirrorTopicsRequest",
// Version 0 is the initial version.
"validVersions": "0",
"flexibleVersions": "0+",
"fields": [
{ "name": "MirrorName", "type": "string", "versions": "0+",
"about": "The cluster mirror name." },
{ "name": "Topics", "type": "[]TopicData", "versions": "0+", "about": "The data for the topics.",
"fields": [
{ "name": "TopicId", "type": "uuid", "versions": "0+", "about": "The unique topic ID."},
{ "name": "TopicName", "type": "string", "versions": "0+", "mapKey": true, "entityType": "topicName",
"about": "The topic name." }
]}
]
} |
...
StopMirrorTopicsResponse
| Code Block |
|---|
{
"apiKey": TBD,
"type": "response",
"name": "RemoveTopicsFromMirrorResponseStopMirrorTopicsResponse",
// Version 0 is the initial version.
"validVersions": "0",
"flexibleVersions": "0+",
"fields": [
{ "name": "ThrottleTimeMs", "type": "int32", "versions": "0+",
"about": "The duration in milliseconds for which the request was throttled due to a quota violation, or zero if the request did not violate any quota." },
{ "name": "ErrorCode", "type": "int16", "versions": "0+",
"about": "The error code, or 0 if there was no error." },
{ "name": "ErrorMessage", "type": "string", "versions": "0+", "nullableVersions": "0+", "default": "null",
"about": "The top-level error message, or null if there was no error." },
{ "name": "MirrorName", "type": "string", "versions": "0+", "entityType": "mirrorName",
"about": "The cluster mirror name." },
{ "name": "Topics", "type": "[]TopicResult", "versions": "0",
"about": "The results for the topics.", "fields": [
{ "name": "Name", "type": "string", "versions": "0", "entityType": "topicName",
"about": "The topic name." },
{ "name": "ErrorCode", "type": "int16", "versions": "0",
"about": "The error code, or 0 if there was no error." }
]}
]
} |
...