mirror of
https://github.com/alibaba/canal.git
synced 2026-11-04 00:30:15 +08:00
kafka producer 修改配置,一个destination可以对应多个kafka topic
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package com.alibaba.otter.canal.kafka.producer;
|
package com.alibaba.otter.canal.kafka.producer;
|
||||||
|
|
||||||
import com.alibaba.otter.canal.kafka.CanalServerStarter;
|
import com.alibaba.otter.canal.kafka.CanalServerStarter;
|
||||||
|
import com.alibaba.otter.canal.kafka.producer.KafkaProperties.CanalDestination;
|
||||||
import com.alibaba.otter.canal.kafka.producer.KafkaProperties.Topic;
|
import com.alibaba.otter.canal.kafka.producer.KafkaProperties.Topic;
|
||||||
import com.alibaba.otter.canal.protocol.ClientIdentity;
|
import com.alibaba.otter.canal.protocol.ClientIdentity;
|
||||||
import com.alibaba.otter.canal.protocol.Message;
|
import com.alibaba.otter.canal.protocol.Message;
|
||||||
@@ -31,13 +32,15 @@ public class CanalKafkaStarter {
|
|||||||
|
|
||||||
private static CanalKafkaProducer canalKafkaProducer;
|
private static CanalKafkaProducer canalKafkaProducer;
|
||||||
|
|
||||||
|
private static KafkaProperties kafkaProperties;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
logger.info("## load kafka configurations");
|
logger.info("## load kafka configurations");
|
||||||
String conf = System.getProperty("kafka.conf", "classpath:kafka.yml");
|
String conf = System.getProperty("kafka.conf", "classpath:kafka.yml");
|
||||||
|
|
||||||
KafkaProperties kafkaProperties;
|
|
||||||
if (conf.startsWith(CLASSPATH_URL_PREFIX)) {
|
if (conf.startsWith(CLASSPATH_URL_PREFIX)) {
|
||||||
conf = StringUtils.substringAfter(conf, CLASSPATH_URL_PREFIX);
|
conf = StringUtils.substringAfter(conf, CLASSPATH_URL_PREFIX);
|
||||||
kafkaProperties = new Yaml().loadAs(CanalKafkaStarter.class.getClassLoader().getResourceAsStream(conf), KafkaProperties.class);
|
kafkaProperties = new Yaml().loadAs(CanalKafkaStarter.class.getClassLoader().getResourceAsStream(conf), KafkaProperties.class);
|
||||||
@@ -50,16 +53,16 @@ public class CanalKafkaStarter {
|
|||||||
canalKafkaProducer.init(kafkaProperties);
|
canalKafkaProducer.init(kafkaProperties);
|
||||||
|
|
||||||
//对应每个instance启动一个worker线程
|
//对应每个instance启动一个worker线程
|
||||||
List<Topic> topics = kafkaProperties.getTopics();
|
List<CanalDestination> destinations = kafkaProperties.getCanalDestinations();
|
||||||
|
|
||||||
executorService = Executors.newFixedThreadPool(topics.size());
|
executorService = Executors.newFixedThreadPool(destinations.size());
|
||||||
|
|
||||||
logger.info("## start the kafka workers.");
|
logger.info("## start the kafka workers.");
|
||||||
for (final Topic topic : topics) {
|
for (final CanalDestination destination : destinations) {
|
||||||
executorService.execute(new Runnable() {
|
executorService.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
worker(topic);
|
worker(destination);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -88,12 +91,12 @@ public class CanalKafkaStarter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void worker(Topic topic) {
|
private static void worker(CanalDestination destination) {
|
||||||
while (!running) ;
|
while (!running) ;
|
||||||
while (!CanalServerStarter.isRunning()) ; //等待server启动完成
|
while (!CanalServerStarter.isRunning()) ; //等待server启动完成
|
||||||
logger.info("## start the canal consumer: {}.", topic.getCanalDestination());
|
logger.info("## start the canal consumer: {}.", destination.getCanalDestination());
|
||||||
CanalServerWithEmbedded server = CanalServerWithEmbedded.instance();
|
CanalServerWithEmbedded server = CanalServerWithEmbedded.instance();
|
||||||
ClientIdentity clientIdentity = new ClientIdentity(topic.getCanalDestination(), (short) 1001, "");
|
ClientIdentity clientIdentity = new ClientIdentity(destination.getCanalDestination(), (short) 1001, "");
|
||||||
while (running) {
|
while (running) {
|
||||||
try {
|
try {
|
||||||
if (!server.getCanalInstances().containsKey(clientIdentity.getDestination())) {
|
if (!server.getCanalInstances().containsKey(clientIdentity.getDestination())) {
|
||||||
@@ -105,21 +108,23 @@ public class CanalKafkaStarter {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
server.subscribe(clientIdentity);
|
server.subscribe(clientIdentity);
|
||||||
logger.info("## the canal consumer {} is running now ......", topic.getCanalDestination());
|
logger.info("## the canal consumer {} is running now ......", destination.getCanalDestination());
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
Message message = server.getWithoutAck(clientIdentity, 5 * 1024); // 获取指定数量的数据
|
Message message = server.getWithoutAck(clientIdentity, kafkaProperties.getCanalBatchSize()); // 获取指定数量的数据
|
||||||
long batchId = message.getId();
|
long batchId = message.getId();
|
||||||
try {
|
try {
|
||||||
int size = message.getEntries().size();
|
int size = message.getEntries().size();
|
||||||
if (batchId == -1 || size == 0) {
|
if (batchId != -1 && size != 0) {
|
||||||
try {
|
if (!StringUtils.isEmpty(destination.getTopic())) {
|
||||||
Thread.sleep(1000);
|
Topic topic = new Topic();
|
||||||
} catch (InterruptedException e) {
|
topic.setTopic(destination.getTopic());
|
||||||
//ignore
|
topic.setPartition(destination.getPartition());
|
||||||
|
destination.getTopics().add(topic);
|
||||||
|
}
|
||||||
|
for (Topic topic : destination.getTopics()) {
|
||||||
|
canalKafkaProducer.send(topic, message); //发送message到所有topic
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
canalKafkaProducer.send(topic, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (batchId != -1) {
|
if (batchId != -1) {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.alibaba.otter.canal.kafka.producer;
|
package com.alibaba.otter.canal.kafka.producer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kafka 配置项
|
* kafka 配置项
|
||||||
@@ -16,12 +18,23 @@ public class KafkaProperties {
|
|||||||
private int lingerMs = 1;
|
private int lingerMs = 1;
|
||||||
private long bufferMemory = 33554432L;
|
private long bufferMemory = 33554432L;
|
||||||
|
|
||||||
private List<Topic> topics = new ArrayList<Topic>();
|
private int canalBatchSize = 5;
|
||||||
|
|
||||||
public static class Topic {
|
private List<CanalDestination> canalDestinations = new ArrayList<CanalDestination>();
|
||||||
|
|
||||||
|
public static class CanalDestination {
|
||||||
|
private String canalDestination;
|
||||||
private String topic;
|
private String topic;
|
||||||
private Integer partition;
|
private Integer partition;
|
||||||
private String canalDestination;
|
private Set<Topic> topics = new HashSet<Topic>();
|
||||||
|
|
||||||
|
public String getCanalDestination() {
|
||||||
|
return canalDestination;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCanalDestination(String canalDestination) {
|
||||||
|
this.canalDestination = canalDestination;
|
||||||
|
}
|
||||||
|
|
||||||
public String getTopic() {
|
public String getTopic() {
|
||||||
return topic;
|
return topic;
|
||||||
@@ -39,12 +52,51 @@ public class KafkaProperties {
|
|||||||
this.partition = partition;
|
this.partition = partition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCanalDestination() {
|
public Set<Topic> getTopics() {
|
||||||
return canalDestination;
|
return topics;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCanalDestination(String canalDestination) {
|
public void setTopics(Set<Topic> topics) {
|
||||||
this.canalDestination = canalDestination;
|
this.topics = topics;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Topic {
|
||||||
|
private String topic;
|
||||||
|
private Integer partition;
|
||||||
|
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTopic(String topic) {
|
||||||
|
this.topic = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPartition() {
|
||||||
|
return partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPartition(Integer partition) {
|
||||||
|
this.partition = partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
Topic topic1 = (Topic) o;
|
||||||
|
|
||||||
|
if (topic != null ? !topic.equals(topic1.topic) : topic1.topic != null) return false;
|
||||||
|
return partition != null ? partition.equals(topic1.partition) : topic1.partition == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = topic != null ? topic.hashCode() : 0;
|
||||||
|
result = 31 * result + (partition != null ? partition.hashCode() : 0);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,11 +140,19 @@ public class KafkaProperties {
|
|||||||
this.bufferMemory = bufferMemory;
|
this.bufferMemory = bufferMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Topic> getTopics() {
|
public int getCanalBatchSize() {
|
||||||
return topics;
|
return canalBatchSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTopics(List<Topic> topics) {
|
public void setCanalBatchSize(int canalBatchSize) {
|
||||||
this.topics = topics;
|
this.canalBatchSize = canalBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CanalDestination> getCanalDestinations() {
|
||||||
|
return canalDestinations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCanalDestinations(List<CanalDestination> canalDestinations) {
|
||||||
|
this.canalDestinations = canalDestinations;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,16 @@ retries: 0
|
|||||||
batchSize: 16384
|
batchSize: 16384
|
||||||
lingerMs: 1
|
lingerMs: 1
|
||||||
bufferMemory: 33554432
|
bufferMemory: 33554432
|
||||||
|
# canal的批次大小,单位 k
|
||||||
|
canalBatchSize: 5
|
||||||
|
|
||||||
topics:
|
canalDestinations:
|
||||||
- topic: example
|
- canalDestination: example
|
||||||
|
topic: example
|
||||||
partition:
|
partition:
|
||||||
canalDestination: example
|
# 一个destination可以对应多个topic
|
||||||
# - topic: example2
|
# topics:
|
||||||
# partition:
|
# - topics: example
|
||||||
# canalDestination: example
|
# partition:
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user