介绍一款数据准实时复制(CDC)中间件 `Debezium`

440 阅读6分钟

 一. 简介

文章开头先介绍一下什么是CDC。数据准实时复制(CDC)是目前行内实时数据需求大量使用的技术。常用的中间件有Canal、Debezium、Flink CDC等

下面我们做一下对比

image.png image.png

各有优缺点吧,本主要介绍一下Debezium中间件。

二. Debezium是什么

Debezium是一个为变更数据捕获(CDC)提供低延迟数据流平台的开源项目。Debezium是一个将来自现有数据库的信息转换为事件流的分布式平台,使应用程序能够检测并立即响应数据库中的行级更改。

Debezium构建在Apache Kafka之上,并提供了一组Kafka Connect兼容的连接器。每个连接器都与特定的数据库管理系统(DBMS)一起工作。连接器通过检测发生的变化来记录DBMS中数据变化的历史,并将每个变化事件的记录流式传输到Kafka Topic。然后,消费应用程序可以从Kafka主题中读取结果事件记录。通过利用Kafka可靠的流媒体平台,Debezium使应用程序能够正确和完整地消费数据库中发生的更改。即使您的应用程序意外停止或失去连接,它也不会错过停机期间发生的事件。应用程序重新启动后,它将从停止的位置继续从主题读取。

注:本文只讨论Debezium构建在kafka之上。

三. Kafka Connect架构

最常见的是通过Apache kafka connect部署Debezium。Kafka Connect是一个框架和运行时,用于实现和操作:

  • 源连接器,如Debezium,将记录发送到Kafka
  • 接收连接器,将记录从Kafka主题传播到其他系统

下图显示了基于Debezium的变更数据捕获管道的架构:

image.png

如图所示,部署了用于MySQL和PostgresSQL的Debezium连接器来捕获对这两种数据库的更改。每个Debezium连接器建立一个到其源数据库的连接:

  • MySQL连接器使用一个客户端库来访问binlog。
  • PostgreSQL连接器从逻辑复制流中读取数据。

Kafka Connect作为Kafka代理之外的一个独立服务运行。

默认情况下,一个数据库表的更改被写入Kafka主题,其名称对应于表名。如果需要,您可以通过配置Debezium的主题路由转换来调整目标主题名称。例如,您可以:

  • 将记录路由到名称与表名不同的主题
  • 将多个表的更改事件记录流式传输到单个主题中

在Apache Kafka中更改事件记录后,Kafka Connect生态系统中的不同连接器可以将记录流式传输到其他系统和数据库,如Elasticsearch,数据仓库和分析系统,或缓存,如Infinispan。根据所选择的接收器连接器,您可能需要配置Debezium的新记录状态提取转换。这个Kafka Connect SMT从Debezium的change事件传播after结构到sink连接器。这将取代默认情况下传播的详细更改事件记录。

四. Debezium MySQL连接器

MySQL有一个二进制日志(binlog),它按照提交到数据库的顺序记录所有操作。这包括对表模式的更改以及对表中数据的更改。MySQL使用binlog进行复制和恢复。

Debezium MySQL连接器读取binlog,为行级INSERT、UPDATE和DELETE操作生成更改事件,并将更改事件发送给Kafka主题。客户端应用程序读取这些Kafka主题。

五. 环境构建

1.  MySQL数据库准备

yum install -y mysql-server mysql mysql-devel

需要开启binlog日志

新增mysql用户
CREATE USER 'dbz'@'%' IDENTIFIED BY '******';
 
GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'dbz' IDENTIFIED BY '******';

mysql开启binlog
server-id         = 1  #必须有
log_bin           = mysql-bin #log_bin的值是binlog文件序列的基本名称
binlog_format     = ROW    #必须是ROW
binlog_row_image  = FULL   #必须是FULL
expire_logs_days  = 10    #依据实际情况而定

2. JDK(11)安装部署

安装
yum install java-11-openjdk


执行以下命令来查看 JDK 11 的安装信息
yum list installed | grep java-11-openjdk


配置环境变量
vim /etc/profile

export JAVA_HOME=/usr/lib/jvm/jre-11-openjdk-11.0.6.10-4.ky10.ky10.aarch64 
export PATH=$JAVA_HOME/bin:$PATH


source /etc/profile


java -version

3.  Zookeeper(3.8)安装部署

 创建放zookeeper的目录

#创建目录

mkdir -p /usr/local/zookeeper

#赋予权限

chmod 777 /usr/local/zookeeper

 下载文件

https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.6.4/apache-zookeeper-3.6.4-bin.tar.gz

安装包并解压

#切换到创建的目录
cd /usr/local/zookeeper

#将下载的包放在该目录

#解压该目录
tar -zxvf apache-zookeeper-3.6.4-bin.tar.gz

#重命名
mv apache-zookeeper-3.6.4-bin zookeeper-3.6.4

修改配置文件

#进入配置文件目录
cd /usr/local/zookeeper/zookeeper-3.6.4/conf

#复制原有的配置文件并改名
cp zoo_sample.cfg zoo.cfg

#修改配置文件
vim zoo.cfg

#内容如下:
# 数据文件夹
dataDir=/usr/local/zookeeper/zookeeper-3.6.4/data
    
# 日志文件夹
dataLogDir=/usr/local/zookeeper/zookeeper-3.6.4/logs

# 客户端访问 zookeeper 的端口号
clientPort=2181

#退出保存zoo.cfg
:wq

添加环境变量

#编辑环境变量文件
vim /etc/profile
#尾部添加如下内容
export ZOOKEEPER_HOME=/usr/local/zookeeper/zookeeper-3.6.4/
export PATH=$ZOOKEEPER_HOME/bin:$PATH
export PATH

#退出保存
:wq

#重新执行一下
source /etc/profile

zookeeper启动

#进入bin目录
cd /usr/local/zookeeper/zookeeper-3.6.4/bin

#启动服务
zkServer.sh start

ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/zookeeper-3.6.4/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

4 . Kafka安装部署

创建目录

mkdir -p /opt/kafka  #y用于存放kafka的解压包

mkdir -p /opt/kafka/kafka_data #用于存放kafka的数据

mkdir -p /opt/kafka/kafka_log #用于存放kafka的日志

kafka解压

tar -zxvf kafka_2.13-3.4.1.tgz

配置kafka服务

cd /opt/kafka/kafka_2.13-3.4.1/config

vim server.properties

#修改一下参数
broker.id=0
#端口号
port=9092   
#服务器IP地址,修改为自己的服务器IP
host.name=localhost
#日志存放路径,上面创建的目录
log.dirs=/opt/kafka/kafka_log
#zookeeper地址和端口,单机配置部署,localhost:2181
zookeeper.connect=localhost:2181

启动kafka

/opt/kafka/kafka_2.13-3.4.1/bin/kafka-server-start.sh -daemon /opt/kafka/kafka_2.13-3.4.1/config/server.properties

测试

生产者

cd /opt/kafka/kafka_2.13-3.4.1/bin

./kafka-console-producer.sh --broker-list localhost:9092 --topic mysql-test

消费者

cd /opt/kafka/kafka_2.13-3.4.1/bin

./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic mysql-test

5. MySQL连接器(2.4)安装部署

下载

目录
cd /usr/local/connect

下载 
wget https://repo1.maven.org/maven2/io/debezium/debezium-connector-mysql/2.4.1.Final/debezium-connector-mysql-2.4.1.Final-plugin.tar.gz
 
解压
tar -zxvf debezium-connector-mysql-2.4.1.Final-plugin.tar.gz 

修改连接器配置

bootstrap.servers=localhost:9092
group.id=connect-cluster
key.converter=org.apache.kafka.connect.json.JsonConverter
value.converter=org.apache.kafka.connect.json.JsonConverter
key.converter.schemas.enable=true
value.converter.schemas.enable=true
offset.storage.topic=connect-offsets
offset.storage.replication.factor=1
config.storage.topic=connect-configs
config.storage.replication.factor=1
status.storage.topic=connect-status
status.storage.replication.factor=1
offset.flush.interval.ms=10000
plugin.path=/usr/local/kafka-connect

启动连接器

bin/connect-distributed.sh -daemon config/connect-distributed.properties 

配置debezium MySQl connector,并通过json文件启动

{
        "name": "mysql-connector",
        "config": {
                "connector.class": "io.debezium.connector.mysql.MySqlConnector",
                "database.hostname": "127.0.0.1",
                "database.port": "3306",
                "database.server.id": "1",
                "database.user": "用户名",
                "database.password": "密码",
                "database.include.list": "表名",
                "topic.prefix": "mysql-test",
                "schema.history.internal.kafka.bootstrap.servers": "127.0.0.1:9092",
                "schema.history.internal.kafka.topic": "schemahistory.mysql-test",
                "include.schema.changes": "true"
        }
}

curl -H "Content-Type: application/json" -X POST -d "@/usr/local/source-mysql.json" http://127.0.0.1:8083/connectors/

{"name":"mysql-connector","config":{"connector.class":"io.debezium.connector.mysql.MySqlConnector","database.hostname":"127.0.0.1","database.port":"3306","database.server.id":"2023","database.user":"dbz","database.password":"dbz","database.include.list":"test","table.include.list":"test.t1","topic.prefix":"mysql-test","schema.history.internal.kafka.bootstrap.servers":"127.0.0.1:9092","schema.history.internal.kafka.topic":"schemahistory.mysql-test","include.schema.changes":"true","name":"mysql-connector"},"tasks":[],"type":"source"}

查询mysql连接器状态

curl http://192.3.65.195:8083/connectors
["mysql-connector"]

curl -H "Content-Type: application/json" -X GET http://192.3.65.195:8083/connectors/"mysql-connector"/status
{"name":"mysql-connector","connector":{"state":"RUNNING","worker_id":"192.3.65.195:8083"},"tasks":[{"id":0,"state":"RUNNING","worker_id":"192.3.65.195:8083"}],"type":"source"}

删除连接器

curl -i -X DELETE http://localhost:8083/connectors/mysql-connector

参考地址:

Debezium Documentation :: Debezium Documentation