【Kafka】MM2同步Kafka集群时如何自定义复制策略(ReplicationPolicy)
创始人
2024-06-01 08:42:14
0

文章目录

  • 需求
  • 准备工作
  • 自定义复制策略
  • 编译代码

需求

使用MM2同步集群数据,topic名称不能变,默认的复制策略为:DefaultReplicationPolicy,这个策略会把同步至目标集群的topic都加上一个源集群别名的前缀,比如源集群别名为A,topic为:bi-log,该topic同步到目标集群后会变成:A.bi-log,为啥这么做呢,就是为了避免双向同步的场景出现死循环。

官方也给出了解释:

这是 MirrorMaker 2.0 中的默认行为,以避免在复杂的镜像拓扑中重写数据。 需要在复制流设计和主题管理方面小心自定义此项,以避免数据丢失。 可以通过对“replication.policy.class”使用自定义复制策略类来完成此操作,所以本文主要记录一下自定义复制策略的流程。

准备工作

下载源码

https://kafka.apache.org/downloads

kafka源码是使用Gradle编译的,需要安装Gradle,具体安装操作不赘述了,可以百度。

源码使用IDEA打开后,在connect模块下找到接口:org.apache.kafka.connect.mirror.ReplicationPolicy

自定义复制策略

ReplicationPolicy这个接口主要有几个方法:

  • formatRemoteTopic:重命名topic名称
  • topicSource:根据topic获取source集群别名
  • upstreamTopic:获取topic在source集群中的名称
  • originalTopic:获取topic原始的名称(针对多次同步过程中,被重命名过多次的topic)
  • isInternalTopic:判断是否为内部topic

根据我们的需求,自定义策略需要满足:

  • 不重命名source集群中topic的名称
  • 能返回source集群别名

实现很简单,就是保证topic原封不动即可,完整代码如下:

package org.apache.kafka.connect.mirror;import org.apache.kafka.common.Configurable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.Map;
import java.util.regex.Pattern;/*** Defines remote topics like "us-west.topic1". The separator is customizable and defaults to a period.*/
public class CustomReplicationPolicy implements ReplicationPolicy, Configurable {// In order to work with various metrics stores, we allow custom separators.public static final String SEPARATOR_CONFIG = MirrorClientConfig.REPLICATION_POLICY_SEPARATOR;public static final String SEPARATOR_DEFAULT = ".";private static final Logger log = LoggerFactory.getLogger(CustomReplicationPolicy.class);private String separator = SEPARATOR_DEFAULT;private Pattern separatorPattern = Pattern.compile(Pattern.quote(SEPARATOR_DEFAULT));@Overridepublic void configure(Map props) {if (props.containsKey(SEPARATOR_CONFIG)) {separator = (String) props.get(SEPARATOR_CONFIG);log.info("Using custom remote topic separator: '{}'", separator);separatorPattern = Pattern.compile(Pattern.quote(separator));}}/*** 拼接Topic名(if you need)** @param sourceClusterAlias 源集群标识* @param topic              源Topic名称* @return java.lang.String* @date 2023/03/03 4:28 下午*/@Overridepublic String formatRemoteTopic(String sourceClusterAlias, String topic) {return topic;}/*** 获取源集群标(source.cluster.alias)** @param topic Topic nameMirrorSourceConnector* @return source alias*/@Overridepublic String topicSource(String topic) {// 和source.cluster.alias配置的一致,可通过读取配置,为了方便直接返回return "source";}/*** 截取上游真实Topic名称** @param topic Topic name* @return java.lang.String* @date 2023/03/03 4:22 下午*/@Overridepublic String upstreamTopic(String topic) {return topic;}/*** 获取原始Topic名,没做过加工,直接返回即可** @param topic 源Topic名* @return java.lang.String* @date 2023/03/03 6:42 下午*/@Overridepublic String originalTopic(String topic) {return topic;}
}

还需要修改一个地方:org.apache.kafka.connect.mirror.MirrorSourceConnector#isCycle

这个方法是判断是否出现循环复制,会递归调用,如果不修改会死循环:

原始代码:

修改为:

    // Recurse upstream to detect cycles, i.e. whether this topic is already on the target clusterboolean isCycle(String topic) {String source = replicationPolicy.topicSource(topic);if (source == null) {return false;} else {return source.equals(sourceAndTarget.target());}}

不改的话,后果如下:

编译代码

只需要编译connect模块即可,从Gradle视图中找到对应模块的build方法,修改参数,跳过单元测试(不跳过的话电脑得卡死):

build完成之后,在项目目录下找到对应jar文件,用这两个jar文件替换掉你执行脚本所使用kafka的libs目录下的jar即可:(原jar文件记得备份,以防万一)

libs目录示例:

完成上述操作之后,修改MM2配置文件中的:

replication.policy.class=org.apache.kafka.connect.mirror.CustomReplicationPolicy

还有一种方法是直接将class文件上传到classpath下,这种方式我没试。

再次执行脚本,可以看到同步后的topic已经保持原来的名称了,大功告成!

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...