当前位置: 首页 > news >正文

【新版 SeaTunnel Web 最佳实践 3】一批表怎么同步?MySQL 多表同步实战来了

大家好,我是乐峰呀。

上一篇文章里,我们用新版 SeaTunnel Web 跑通了一个最基础的场景:

MySQL 单表同步到 MySQL。

不用写 HOCON,不用手动配置 Source 和 Sink,只需要在页面上填几个表单、点几下按钮,就能把一张表从源库同步到目标库。

但真实业务里,数据同步很少只同步一张表。

更多时候,我们面对的是这样的问题:

一个业务库里有很多张表。

用户表要同步。
订单表要同步。
商品表要同步。
日志表也要同步。

如果每张表都单独建一个任务,单独配置一次字段映射,单独发布,单独运行,当然也能做。

但问题是:

表一多,配置就开始重复;任务一多,管理就开始混乱。

所以这一篇,我们继续往前走一步。

这次不再只同步一张表,而是演示一个更接近真实业务的场景:

MySQL 多表同步。

还是一样,不写配置,不手搓 HOCON。

通过 SeaTunnel Web 页面,把一批 MySQL 表一次性配置好,然后交给 SeaTunnel 执行。


一、为什么要做多表同步?

单表同步适合入门。

比如你只想把一张user_source表同步到目标库,流程很清楚:

选源端。
选目标端。
选源表。
配置目标表。
发布运行。

这个过程很适合第一次体验 SeaTunnel Web。

但到了真实业务里,场景会复杂一点。

比如一个订单系统,可能至少包含这些表:

user_source product_source order_source order_item_source

如果每张表都单独配置一个任务,会遇到几个很实际的问题。

第一,重复操作太多。

每张表都要选数据源、选表、配置目标表、发布、运行。表越多,重复动作越多。

第二,任务不好管理。

一个业务库里几十张表,如果全部拆成独立任务,后面查看运行状态、排查日志、调整配置都会比较分散。

第三,容易漏配。

比如用户表同步了,订单表同步了,但订单明细表忘了。等业务侧查数据的时候,才发现少了一张关键表。

第四,不适合批量场景。

很多时候我们想要的不是“同步某一张表”,而是“把这个库里的一批表同步过去”。

这就是多表同步的价值。

它不是为了让功能看起来更复杂,而是为了让真实业务里的批量同步更简单。

一句话:

当同步对象从一张表变成一批表时,配置和管理也应该继续保持清晰。


二、准备几张测试表

为了演示 MySQL 多表同步,我们先准备几张源表。

这里用一个简单的订单业务场景:

用户表、商品表、订单表、订单明细表。

CREATETABLEuser_source(idBIGINTPRIMARYKEY,usernameVARCHAR(64),emailVARCHAR(128),ageINT,create_timeDATETIME);CREATETABLEproduct_source(idBIGINTPRIMARYKEY,product_nameVARCHAR(128),categoryVARCHAR(64),priceDECIMAL(10,2),create_timeDATETIME);CREATETABLEorder_source(idBIGINTPRIMARYKEY,user_idBIGINT,order_noVARCHAR(64),total_amountDECIMAL(10,2),order_statusVARCHAR(32),create_timeDATETIME);CREATETABLEorder_item_source(idBIGINTPRIMARYKEY,order_idBIGINT,product_idBIGINT,quantityINT,amountDECIMAL(10,2),create_timeDATETIME);

然后给这几张表插入一些测试数据。

这里不一定要模拟特别复杂的业务关系,重点是让每张表都有数据,方便后面验证同步结果。

用户表插入 10 万条:

INSERTINTOuser_source(id,username,email,age,create_time)SELECTnASid,CONCAT('user_',n)ASusername,CONCAT('user_',n,'@example.com')ASemail,18+(n%50)ASage,DATE_ADD('2024-01-01 00:00:00',INTERVALnSECOND)AScreate_timeFROM(SELECTa.n+b.n*10+c.n*100+d.n*1000+e.n*10000+1ASnFROM(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)aCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)bCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)cCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)dCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)e)tWHEREn<=100000;

商品表插入 1 万条:

INSERTINTOproduct_source(id,product_name,category,price,create_time)SELECTnASid,CONCAT('product_',n)ASproduct_name,CONCAT('category_',n%20)AScategory,ROUND(10+(n%500)*1.5,2)ASprice,DATE_ADD('2024-01-01 00:00:00',INTERVALnSECOND)AScreate_timeFROM(SELECTa.n+b.n*10+c.n*100+d.n*1000+1ASnFROM(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)aCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)bCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)cCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)d)tWHEREn<=10000;

订单表插入 5 万条:

INSERTINTOorder_source(id,user_id,order_no,total_amount,order_status,create_time)SELECTnASid,1+(n%100000)ASuser_id,CONCAT('ORDER_',LPAD(n,8,'0'))ASorder_no,ROUND(50+(n%1000)*2.3,2)AStotal_amount,CASEn%4WHEN0THEN'CREATED'WHEN1THEN'PAID'WHEN2THEN'SHIPPED'ELSE'FINISHED'ENDASorder_status,DATE_ADD('2024-02-01 00:00:00',INTERVALnSECOND)AScreate_timeFROM(SELECTa.n+b.n*10+c.n*100+d.n*1000+e.n*10000+1ASnFROM(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)aCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)bCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)cCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)dCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)e)tWHEREn<=50000;

订单明细表插入 10 万条:

INSERTINTOorder_item_source(id,order_id,product_id,quantity,amount,create_time)SELECTnASid,1+(n%50000)ASorder_id,1+(n%10000)ASproduct_id,1+(n%5)ASquantity,ROUND((1+(n%5))*(10+(n%500)*1.5),2)ASamount,DATE_ADD('2024-02-01 00:00:00',INTERVALnSECOND)AScreate_timeFROM(SELECTa.n+b.n*10+c.n*100+d.n*1000+e.n*10000+1ASnFROM(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)aCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)bCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)cCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)dCROSSJOIN(SELECT0nUNIONALLSELECT1UNIONALLSELECT2UNIONALLSELECT3UNIONALLSELECT4UNIONALLSELECT5UNIONALLSELECT6UNIONALLSELECT7UNIONALLSELECT8UNIONALLSELECT9)e)tWHEREn<=100000;

插入完成后,可以检查一下每张表的数据量:

SELECTCOUNT(*)FROMuser_source;SELECTCOUNT(*)FROMproduct_source;SELECTCOUNT(*)FROMorder_source;SELECTCOUNT(*)FROMorder_item_source;

到这里,我们就准备好了一个比较完整的多表同步测试场景。


三、新建 MySQL 数据源

打开 SeaTunnel Web,进入数据源管理。

这里需要创建 MySQL 数据源。

如果源库和目标库是同一个 MySQL,可以创建一个数据源,然后在任务里复用。

如果源库和目标库是两个不同的 MySQL,就分别创建两个数据源:

mysql_source mysql_sink

主要填写这些信息:

数据源名称 数据库类型 JDBC 地址 用户名 密码 数据库名称

填完之后,不要急着进入下一步。

建议先点击测试连接,确认 SeaTunnel Web 能正常连上 MySQL。

这一步很重要。

因为很多同步任务失败,并不是同步逻辑的问题,而是基础连接没有打通。

比如:

数据库地址写错。
账号密码不对。
数据库权限不足。
服务器网络不通。
目标库端口没有开放。

这些问题提前测出来,比任务运行失败后再排查要省事很多。


四、新建 Zeta 服务

数据源准备好之后,还需要配置 SeaTunnel 的执行服务。

这里使用的是 Zeta 引擎。

在 SeaTunnel Web 中新建 Zeta 服务,填写对应的服务地址和端口。

可以简单理解为:

SeaTunnel Web 负责任务配置和管理,Zeta 负责真正执行任务。

所以只配置数据源还不够。

Web 端还需要能正常连接到 Zeta 服务,才能把任务提交出去。

配置完成后,同样建议做一次连通性测试。

如果 Zeta 服务不通,后面任务配置得再完整,也无法真正执行。


五、选择多表同步模式

接下来进入同步任务页面,创建一个新的同步任务。

这次我们选择的不是单表同步,而是:

MySQL 多表同步。

多表同步和单表同步最大的区别是:

单表同步只配置一组源表和目标表。

多表同步可以一次配置多组表映射。

比如这次我们要同步的是:

user_source product_source order_source order_item_source

也就是说,一个任务里可以包含多张表的同步关系。

对于用户来说,操作上还是选数据源、选表、确认配置。

但底层 SeaTunnel Web 会根据这些选择生成对应的 SeaTunnel 配置。

你不需要手写 Source。
不需要手写 Sink。
也不需要自己拼 HOCON。


六、做一次连通性检查

多表同步比单表同步更容易出错。

因为表多了,字段多了,链路也更长了。

一张表没问题,不代表所有表都没问题。

所以在正式发布之前,建议先做一次连通性检查。

至少确认这几件事:

源端 MySQL 是否可以连接 目标端 MySQL 是否可以连接 Zeta 服务是否可以连接

这一步看起来很简单,但实际非常有用。

因为多表同步一旦跑起来,如果基础连接不稳定,排查起来会比单表更麻烦。

提前把连接问题排掉,后面会顺很多。


七、选择需要同步的表

连通性确认没问题后,就可以选择需要同步的表了。

这一步是多表同步的核心。

比如我们选择这几张表:

user_source product_source order_source order_item_source

选择表的时候,建议重点确认三件事。

第一,表有没有选全。

比如订单相关数据,通常不只是订单主表,还会有订单明细表。

第二,目标表名是否符合预期。

有些场景会保持同名同步,有些场景会把源表同步到新的目标表。

比如:

user_source -> user_target product_source -> product_target order_source -> order_target order_item_source -> order_item_target

第三,目标表是否需要自动创建。

如果目标库里还没有这些表,可以使用自动建表能力。

如果目标表已经存在,就要注意字段结构是否兼容。

多表同步最怕的不是配置慢,而是漏选、错选、字段不一致。

所以这一步多看一眼,后面少排很多坑。


八、查看生成的 HOCON 配置

虽然这篇文章的重点是“不写配置”,但我还是建议发布前看一眼生成出来的 HOCON。

尤其是多表同步。

因为多表同步背后的配置会比单表更复杂。

你可以重点确认几个地方:

job.mode 是否为 BATCH source 中是否包含需要同步的源表 sink 中是否包含对应的目标表 plugin_output 和 plugin_input 是否正确对应

你不需要手写这些内容。

但看一眼会更放心。

因为你可以确认每张源表和目标表是否对应正确。

这也是 SeaTunnel Web 比较重要的一点:

降低配置门槛,但不隐藏关键细节。

新手可以通过页面把任务跑起来。

熟悉 SeaTunnel 的用户,也可以查看底层配置,确认任务是否符合预期。


九、配置调度

多表同步任务配置完成后,可以根据实际场景配置调度。

比如:

每天凌晨同步一次 每小时同步一次 每 10 分钟同步一次 手动运行一次

如果只是测试,可以先不配置复杂调度,直接手动运行。

如果是正式业务任务,就建议配置一个清晰的调度策略。

多表同步通常更适合周期性执行。

比如每天凌晨把业务库里的一批表同步到分析库,给报表、数据分析、数据服务使用。

这样就不用每次手动点运行。

任务发布后,系统可以按照调度策略自动执行。


十、发布任务

任务配置完成后,下一步就是发布。

发布可以理解为:

把当前任务配置固定成一个可以执行的版本。

这一步在多表同步里尤其重要。

因为多表任务的配置项更多。

你可能会调整表映射。
可能会修改目标表名。
可能会修改自动建表策略。
可能会调整并行度。
也可能会增加或删除某些同步表。

如果没有发布版本的概念,后面很容易搞不清楚:

当前运行的是哪一版配置?
刚刚修改的内容有没有生效?
线上任务是不是用了旧配置?

通过发布机制,任务配置和运行版本会更清晰。


十一、点击运行

任务发布后,就可以点击运行了。

这一步还是很简单。

不需要登录服务器。
不需要执行命令。
不需要手动上传配置。
不需要自己调用 SeaTunnel 脚本。

SeaTunnel Web 会把任务提交给 Zeta 服务,由 Zeta 负责执行真正的数据同步。

运行后,你可以看到任务实例状态变化。

比如:

INITIALIZING RUNNING FINISHED FAILED CANCELED

如果任务正常完成,就可以进入下一步查看日志和结果。

如果任务失败,也不用慌,先看日志。


十二、查看运行日志

多表同步任务运行后,日志非常重要。

因为多表同步失败时,不一定是所有表都有问题。

有时候只是其中一张表字段不兼容。
有时候只是某张目标表没有权限。
有时候只是某个字段类型转换失败。
有时候只是某个查询 SQL 异常。

所以不要只看任务状态。

建议点进运行实例,查看完整日志。

重点关注这些信息:

任务是否成功提交到 Zeta 每个 Source 是否正常读取 每个 Sink 是否正常写入 是否有字段类型异常 是否有目标表创建失败 是否有数据库连接异常 是否有权限异常

日志不是给机器看的,是给人排查问题看的。

SeaTunnel Web 把运行日志放在页面里,就是为了让用户不用再到服务器上到处找文件。

任务失败了,直接在页面里看原因。

这比只显示一个“失败”状态要有用得多。


十三、验证目标表数据

最后一步,回到目标 MySQL,检查同步结果。

分别查看几张目标表的数据量:

SELECTCOUNT(*)FROMuser_target;SELECTCOUNT(*)FROMproduct_target;SELECTCOUNT(*)FROMorder_target;SELECTCOUNT(*)FROMorder_item_target;

如果和源表数据量一致,说明多表同步基本完成。

也可以抽查几条数据:

SELECT*FROMuser_targetLIMIT10;SELECT*FROMproduct_targetLIMIT10;SELECT*FROMorder_targetLIMIT10;SELECT*FROMorder_item_targetLIMIT10;

重点看几个地方:

字段是否完整 数据内容是否正确 时间字段是否正常 金额字段是否正常 目标表名是否正确

如果这些都没问题,就说明这次 MySQL 多表同步已经跑通了。


十四、从单表到多表,变化在哪里?

最后简单对比一下。

单表同步解决的是:

一张表怎么快速跑通。

它适合入门,链路短,问题也好排查。

多表同步解决的是:

一批表怎么统一配置、统一发布、统一运行。

它更接近真实业务,适合批量同步场景。

所以我建议刚开始体验 SeaTunnel Web 的同学,可以先从单表同步开始。

等单表跑通之后,再尝试多表同步。

这样理解会更顺。

你会很清楚地知道:

单表同步解决的是“能不能跑通”。
多表同步解决的是“能不能批量管理”。


总结一下

这次我们完成了一个更接近真实业务的同步场景:

MySQL 到 MySQL 多表同步。

完整流程包括:

  1. 准备多张 MySQL 测试表
  2. 插入测试数据
  3. 新建源端和目标端 MySQL 数据源
  4. 新建 Zeta 服务
  5. 选择多表同步模式
  6. 做连通性检查
  7. 选择需要同步的表
  8. 查看自动生成的 HOCON
  9. 配置调度
  10. 发布任务
  11. 点击运行
  12. 查看运行日志
  13. 验证目标表数据

整个过程的重点,不是证明 SeaTunnel 能不能同步多张表。

SeaTunnel 本身当然可以做数据同步。

真正的重点是:

当同步对象从一张表变成一批表时,SeaTunnel Web 能不能继续让这件事保持简单。

不用为每张表重复写配置。
不用手动拼复杂的 HOCON。
不用在命令行和服务器之间来回切换。
不用任务失败后到处找日志。

通过 SeaTunnel Web,把数据源、表选择、配置生成、任务发布、运行日志、结果验证这些步骤串起来,多表同步就会清晰很多。

一句话:

SeaTunnel 负责强大的同步能力,SeaTunnel Web 负责让这份能力更好上手。

Github 地址:

https://github.com/weifuwan/seatunnel-web

http://www.zskr.cn/news/1376294.html

相关文章:

  • 告别丑陋终端!在Windows Terminal里用WSL2和oh-my-zsh搭建高颜值命令行(附插件避坑清单)
  • 手把手教你修复WSL2下systemD的/proc挂载问题:nsenter报错深度解析
  • NBTest:为Jupyter Notebook打造机器学习回归测试与自动化断言框架
  • Python安装文档
  • Windows用户必看!终极免费的PDF处理工具Poppler快速安装指南
  • 终极游戏翻译解决方案:XUnity.AutoTranslator完整指南
  • 5分钟解锁QQ音乐加密格式:Mac用户的音乐自由解决方案
  • BepInEx 6.0深度解析:Unity插件框架的3大技术挑战与多运行时解决方案
  • AI写论文秘籍在此!4款实用AI论文写作工具,搞定期刊论文不愁!
  • Cloudflare四重验证机制与行为建模反爬原理深度解析
  • 黑龙江移远科技,是懂预算、懂场景、更懂服务的专业服务商
  • 本体从入门到实战-03.为什么AI需要一个本体层?
  • 3步解决洛雪音乐播放问题:六音音源修复完整指南
  • 可微卡尔曼滤波:融合场反演与机器学习的状态估计新范式
  • 机器学习如何赋能单体到微服务迁移:从算法原理到工程实践
  • SPTD:利用训练动态实现高效选择性预测,以单模型成本媲美深度集成
  • C51中断服务程序地址分配机制解析
  • Hermes-Agent安装全记录
  • ComfyUI-Manager深度解析:AI工作流扩展管理系统的架构设计与性能优化
  • 技术深度解析:RePKG项目架构与Wallpaper Engine资源逆向工程实践
  • 公共机构碳排放核算的政策背景以及我们应该如何做
  • 你的音乐不该被格式绑架:用QMCDecode一键解锁QQ音乐加密文件
  • 每日一Go-66、K8s 蓝绿发布 金丝雀发布实战:Service 切流量 + Ingress 灰度一次讲透
  • 书匠策AI|论文降重降AIGC,原来可以这么丝滑?官网www.shujiangce.com一键解锁!
  • 融合gws-PINNs与马尔可夫切换模型:反演跳跃系数PDE的混合框架
  • 5分钟实现Rhino到Blender转换:3dm文件导入完整教程
  • 手把手教你处理TT100K数据集:从COCO格式转换到YOLO格式的完整流程(附Python脚本)
  • 直流电机驱动控制电路
  • 3步突破微信网页版访问限制的智能解决方案
  • ncmdump音乐格式转换完整攻略:解锁网易云加密音频的终极方案