点亮Star!https://github.com/apache/seatunnel
来源 | 数仓生态圈
概述
当有多个数据库中的一张表具有类似的数据,例如有多个不同的系统来源,数据插入不同数据库中的表。此时,若需要把这些表数据汇总成一张表进行统计分析,会面临一个棘手问题:由于多张表具有相同的主键,直接汇总到一起会出现主键重复。而 Apache SeaTunnel 就能巧妙应对这一挑战。本篇文章将详细阐述 Apache SeaTunnel 是如何解决此问题的。
设计思想
本方案旨在将分布在两个独立MySQL数据库(datasource1和datasource2)中的test表,实时、准确地同步汇总到第三个数据库(datasource3)的test表中。为实现实时同步与数据修改的捕获,采用基于MySQL二进制日志(Binlog)的变更数据捕获(CDC)技术。为解决源表自增主键ID可能重复的问题,目标表将引入"数据来源"字段,并与原ID组成联合主键,确保数据的唯一性与可追溯性。
工具准备
1、Mysql5.7
2、SeaTunnel2.3.12
MySQL配置检查
Mysql是否开启binlog
mysql> show variables where variable_name in ('log_bin', 'binlog_format', 'binlog_row_image', 'gtid_mode', 'enforce_gtid_consistency');+--------------------------+-------+| Variable_name | Value |+--------------------------+-------+| binlog_format | ROW || binlog_row_image | FULL || enforce_gtid_consistency | OFF || gtid_mode | OFF || log_bin | ON |+--------------------------+-------+
如果log_bin的值不是ON, 配置Mysql配置文件mysql.cnf。
log-bin=mysql-binserver-id=1binlog_format=ROWbinlog_checksum=NONE
重启Mysql服务
SeaTunnel配置
1、安装连接器
${SEATUNNEL_HOME}/config/plugin_config文件,增加connector-cdc-mysqlconnector-jdbc
安装连接器
sh bin/install-plugin.sh
2、安装 MySQL 驱动
我是用的是mysql-connector-java-8.0.28.jar
把jar包放到${SEATUNNEL_HOME}/lib/目录下
准备数据
CREATE DATABASE source1CHARACTER SET utf8mb4;CREATE DATABASE source2CHARACTER SET utf8mb4;CREATE DATABASE source3CHARACTER SET utf8mb4;use source1;CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) CHARACTER SET utf8mb4, PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 ;
insert into test values(1,'张三');insert into test values(2,'李四');
use source2;CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) CHARACTER SET utf8mb4, PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 ;
insert into test values(1,'王五');insert into test values(2,'赵六');
use source3;CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) CHARACTER SET utf8mb4, `sources` varchar(50) CHARACTER SET utf8mb4, PRIMARY KEY (`id`, `sources`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 ;
准备脚本
env { parallelism = 2 job.mode = "STREAMING" checkpoint.interval = 20000}
source { MySQL-CDC { plugin_output = "source_data1" url = "jdbc:mysql://10.0.12.100:3306/source1" username = "root" password = "root" table-names = ["source1.test"] startup.mode = initial } MySQL-CDC { plugin_output = "source_data2" url = "jdbc:mysql://10.0.12.100:3306/source2" username = "root" password = "root" table-names = ["source2.test"] startup.mode = initial }}transform { Sql { plugin_input = "source_data1" plugin_output = "result1" query = "SELECT *, 'source1' AS sources FROM source_data1" } Sql { plugin_input = "source_data2" plugin_output = "result2" query = "SELECT *, 'source2' AS sources FROM source_data2" }}sink { Jdbc { plugin_input = ["result1","result2"] url = "jdbc:mysql://10.0.12.100:3306/source3" driver = "com.mysql.cj.jdbc.Driver" username = "root" password = "root" database = "source3" table = "test" generate_sink_sql = true primary_keys = ["id","sources"] }}
这里使用了一个配置来同步2个库,当然也可以配置成2个任务进行同步。
这里使用2个source,一个source_data1,一个source_data2。
transform也使用2个Sql,进行处理对应的2个
source。这里写成固定值来读取sources。
sink对应上面的2个Sql,输出表test,这里设置主键用于修改。
这里目标表需要手动创建,否则提示下面错误
BLOB/TEXT column 'sources' used in key specification without a key length
测试
1、启动
bin/seatunnel.sh --config job/mysql_mysql.conf -m local
2、查看数据
mysql> select * from test;+----+--------+---------+| id | name | sources |+----+--------+---------+| 1 | 张三 | source1 || 1 | 王五 | source2 || 2 | 李四 | source1 || 2 | 赵六 | source2 |+----+--------+---------+
3、修改数据
use source1;insert into test values(3,'钱七');update test set name='张三1' where id=1;use source2;delete from test where id=1;
4、查询数据
mysql> select * from test;+----+---------+---------+| id | name | sources |+----+---------+---------+| 1 | 张三1 | source1 || 2 | 李四 | source1 || 2 | 赵六 | source2 || 3 | 钱七 | source1 |+----+---------+---------+
总结
以上操作就是把2个库中的表数据同步到另一个库中的一张表的所有过程,我有看到其他文章可以自动创建输出表,但一直没有测试出来,有测试出来的朋友可以留言相告。