mysql canal cdc_debezium关于cdc的使用(上)

简介

debezium是一个为了捕获数据变更(cdc)的开源的分布式平台。启动并指向数据库,当其他应用对此数据库执行inserts、updates、delete操作时,此应用快速得到响应。debezium是持久化和快速响应的,因此你的应用可以快速响应且不会丢失任意一条事件。debezium记录是数据库表的行级别的变更事件。同时debezium是构建在kafka之上的,同时与kafka深度耦合,所以提供kafka connector来使用,debezium sink。支持的数据库有mysql、MongoDB、PostgreSQL、Oracle、SQL server。本篇以mysql作为数据源来实现功能,监听msyql的binlog,还需要修改。当前版本是0.9.5.Final,0.10版本正在开发中。

配置

本篇文章主要使用Embedding形式监听事件,并同步更新到数据库。

下篇主要使用kafka connector来同步更新到数据库。

mysql需要如下开启binlog。但是如果使用的是debezium/mysql镜像,自动已经配置好了。

log-bin=mysql-bin #添加这一行就ok

binlog-format=ROW #选择row模式

server_id=1 #配置mysql replaction需要定义,不能和canal的slaveId重复

Tutorial

先来一个效果,主要是配置kafka connector来获取debezium事件记录。需要3个服务,zookeeper、kakfa和debezium connector。这里使用docker来启动的,所以需要先按照docker。

启动zookeeper

docker run -it --rm --name zookeeper -p 2181:2181 -p 2888:2888 -p 3888:3888 debezium/zookeeper:0.9

启动kafka

docker run -it --rm --name kafka -p 9092:9092 --link zookeeper:zookeeper debezium/kafka:0.9

启动mysql

docker run -it --rm --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=debezium -e MYSQL_USER=mysqluser -e MYSQL_PASSWORD=mysqlpw debezium/example-mysql:0.9

启动kafka connect

docker run -it --rm --name connect -p 8083:8083 -e GROUP_ID=1 -e CONFIG_STORAGE_TOPIC=my_connect_configs -e OFFSET_STORAGE_TOPIC=my_connect_offsets -e STATUS_STORAGE_TOPIC=my_connect_statuses --link zookeeper:zookeeper --link kafka:kafka --link mysql:mysql debezium/connect:0.9

通过connect的http请求创建debezium connector

curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json" localhost:8083/connectors/ -d '{ "name": "inventory-connector", "config": { "connector.class": "io.debezium.connector.mysql.MySqlConnector", "tasks.max": "1", "database.hostname": "mysql", "database.port": "3306", "database.user": "debezium", "database.password": "dbz", "database.server.id": "184054", "database.server.name": "dbserver1", "database.whitelist": "inventory", "database.history.kafka.bootstrap.servers": "kafka:9092", "database.history.kafka.topic": "dbhistory.inventory" } }'

mysql客户端操作

通过invertory数据库了的任一表的数据

创建监听可以查看debezium事件记录

docker run -it --name watcher --rm --link zookeeper:zookeeper --link kafka:kafka debezium/kafka:0.9 watch-topic -a -k dbserver1.inventory.customers

内嵌式

这里主要使用内嵌式的方式获取cdc事件而不需要使用kafka,直接消费debezium事件流。场景是在某一个mysql数据库里的table发生变更,把变更同步到另一mysql数据库。本次使用的是监听inventory数据库并将数据同步到inventory_back。

debezium配置

connector.class=io.debezium.connector.mysql.MySqlConnector

offset.storage=org.apache.kafka.connect.storage.FileOffsetBackingStore

offset.storage.file.filename=offset.dat

offset.flush.interval.ms=60000

name=debezium-kafka-source

database.hostname=localhost

database.port=3306

database.user=debezium

database.password=dbz

#database.dbname=inventory

database.whitelist=inventory

#database.whitelist=inventory,inventory_back

server.id=184054

database.server.name=dbserver1

#transforms=unwrap

#transforms.unwrap.type=io.debezium.transforms.UnwrapFromEnvelope

#transforms.unwrap.drop.tombstones=false

database.history=io.debezium.relational.history.FileDatabaseHistory

database.history.file.filename=dbhistory.dat

属性和convert配置

@Slf4j

@Configuration

public class DebeziumEmbeddedAutoConfiguration {

@Bean

public Properties embeddedProperties() {

Properties propConfig = new Properties();

try(InputStream propsInputStream = getClass().getClassLoader().getResourceAsStream("config.properties")) {

propConfig.load(propsInputStream);

} catch (IOException e) {

log.error("Couldn't load properties", e);

}

PropertyLoader.loadEnvironmentValues(propConfig);

return propConfig;

}

@Bean

public io.debezium.config.Configuration embeddedConfig(Properties embeddedProperties) {

return io.debezium.config.Configuration.from(embeddedProperties);

}

@Bean

public JsonConverter keyConverter(io.debezium.config.Configuration embeddedConfig) {

JsonConverter converter = new JsonConverter();

converter.configure(embeddedConfig.asMap(), true);

return converter;

}

@Bean

public JsonConverter valueConverter(io.debezium.config.Configuration embeddedConfig) {

JsonConverter converter = new JsonConverter();

converter.configure(embeddedConfig.asMap(), false);

return converter;

}

}

同步DDL和DML

这里主要是利用CommandLineRunner特性,启动debezium的EmbeddedEngine引擎,获取到cdc事件后由handleRecord处理DDL和DML,需要去解析cdc的事件SourceRecord的key和value。

@Slf4j

@Order(2)

@Component

public class DebeziumEmbeddedRunner implements CommandLineRunner {

@Autowired

private io.debezium.config.Configuration embeddedConfig;

@Autowired

private JdbcTemplate jdbcTemplate;

@Autowired

private NamedParameterJdbcTemplate namedTemplate;

@Autowired

private JsonConverter keyConverter;

@Autowired

private JsonConverter valueConverter;

@Override

public void run(String... args) throws Exception {

EmbeddedEngine engine = EmbeddedEngine.create()

.using(embeddedConfig)

.using(this.getClass().getClassLoader())

.using(Clock.SYSTEM)

.notifying(this::handleRecord)

.build();

ExecutorService executor = Executors.newSingleThreadExecutor();

executor.execute(engine);

shutdownHook(engine);

awaitTermination(executor);

}

/**

* For every record this method will be invoked.

*/

private void handleRecord(SourceRecord record) {

logRecord(record);

Struct payload = (Struct) record.value();

if (Objects.isNull(payload)) {

return;

}

String table = Optional.o

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值