微信搜索[阿丸笔记] , 关注 Java/MySQL / 中间件各系列原创实战笔记, 干货满满.
2020 年下半年的主要任务, 就是从 0 到 1 搭建了数据传输服务平台产品. 平稳上线后, 基本达到预期, 实现了最初的产品规划目标.
这里做个复盘, 记录下从 0 到 1 的过程, 包括:
产品设计
整体技术架构
核心模块的技术选型, 原理与改造适配
总结与展望
1. 什么是数据传输服务
数据传输服务 DTS(Data Transmission System)的目标是支持 RDBMS,NoSQL,OLAP 等数据源间的数据交互, 集数据迁移 / 订阅 / 同步于一体, 帮助构建安全, 可扩展, 高可用的数据架构.
当然, 目前我们的核心存储还是以 MySQL 为主, 因此, 自研的数据传输服务的首要数据源是 MySQL.
为什么不直接采用公有云产品呢, 比如阿里云 DTS?
主要原因是为了能更好地对接内部其他系统, 支持许多内部系统数据迁移 / 同步的自动化流程需求. 同时, 业内相关开源技术非常丰富且成熟, 有很多现成的轮子可以使用, 可以大大降低云服务使用成本.
2. 产品设计
对于 DTS 的最强烈需求来源, 是正在推进的多云架构, 需要能够构建多云数据库镜像. 同时, 我们又深入调研了其他业务需求, 得到了众多用户场景.
包括但不限于:
数据库多云同步
分库分表数据同步
ES 索引构建
压测数据, 线下导入 / 同步
缓存刷新, Local cache/Redis cache 等刷新
业务数据变更订阅
CQRS 模式实现
这些场景经过归纳整理, 得到了 DTS 的三大产品功能模块.
数据订阅模块: 支持 ES 索引构建 , 缓存刷新, 业务数据变更订阅, CQRS 模式实现
数据迁移模块: 支持数据库多云同步, 分库分表数据同步, 压测数据, 线下导入
数据同步模块: 支持数据库多云同步, 分库分表数据同步, 压测数据, 线下导入 / 同步
3. 整体技术架构
整个 DTS 系统分为三个 逻辑层次, 交互层, 控制层, 引擎层.
3.1 交互层
交互层就是用户可见的前台 DTS 产品, 是用户视角的 DTS 系统.
1)产品模块
系统中包含了数据订阅产品模块, 数据迁移产品模块, 数据同步产品模块.
用户通过与各个产品模块交互, 直接获取对应产品模块任务信息, 实现对模块任务的管理, 包括创建, 启动, 停止, 释放, 任务监控信息等.
2)通用服务
交互层除了产品模块之外, 用户能够感知到的交互能力还包括了用户管理, 权限管理, 变更管理, 基本任务信息管理等 通用服务能力.
这些通用服务能力可以来自于其他内部系统, 也可以是独立设计的.
最重要的是, 这些通用服务可以复用于 DTS 未来的产品扩展, 包括 Redis 的数据同步, HBase 数据同步.
3)核心设计
正如一开始提到, 虽然目前我们以 MySQL 为主, 但是未来肯定会扩展到其他数据源的数据迁移与同步.
因此交互层的核心实现采用 模板模式 , 实现了基础任务的创建, 启动, 停止, 释放, 审核, 鉴权等流程.
将基础任务流程中的特定动作, 如启动引擎任务, 停止引擎任务等具体实现放在各个模块的实现类中进行实现.
实现了 DTS 模块化设计和极高的可扩展性, 为未来接入其他 迁移 / 同步引擎(Redis/Hbase) 打下基础.
3.2 控制层
控制层是面向管理员的操作平台.
这一层主要面向运维视角, 实现对引擎层的监控, 启停, 扩容等能力.
对比交互层产品模块, 这一层次的控制台会有更复杂的任务控制选项, 同时, 也会具备很多运维层面的操作, 比如引擎层的服务器管理能力等.
Canal,otter 等开源产品都已经自带了相关控制台, 可以直接使用.
3.3 引擎层
引擎层是整个系统的核心部分, 目前的架构设计下, 引擎层的引擎都是支持扩展, 支持替换的.
目前全部采用开源项目, 包括:
数据迁移引擎采用 Datax:https://github.com/alibaba/DataX
数据订阅引擎采用 canal: https://github.com/alibaba/canal
数据同步引擎采用 otter: https://github.com/alibaba/otter
对于生产环境使用的项目, 必须做好配套的监控告警措施, 保证线上的稳定性.
otter/canal 都有现成的监控指标, 我们需要将 同步延迟 等关键指标进行采集, 并设置合理的告警阈值.
同时, 对于一些没有现成的监控指标, 比如 任务存活状态 等, 我们可以通过 巡检 进行定时检查, 避免由于同步任务挂起而影响上层业务.
4. 数据订阅模块
4.1 技术选型
数据订阅实际上就是一种 CDC(Change Data Capture)工具, 目前开源产品中比较成熟的有 Canal,DataX,DataBus,Debezium 等.
整体而言, Canal,DataX,Debezium 的使用人数多, 社区活跃, 框架也比较成熟. 在满足应用场景的前提下, 优先选择, 代价适中.
DataX 支持丰富, 使用简单, 但延迟较大(依赖获取频率), 只需要手写规则文件, 对复杂同步自定义性不强.
Debezium 虽然比 Canal 支持更多类型的数据源, 但是我们实际上只需要 MySQL, 并不需要 PostgreSQL 这些的支持.
而 Canal 有几点特性我们非常需要, 让我们决定使用 Canal 作为数据订阅引擎:
对阿里云 RDS 有特殊定制优化, 可以自动下载备份到 oss 的 binlog 文件然后指定位点开始同步
有非常友好的控制台
支持投递到 Rocketmq
新版本的 Canal-Adapter 可以支持多种客户端消费, 包括 MySQL,es 等
4.2 基本原理
数据订阅的原理基本一样, 都是基于 MySQL 的主从复制原理实现.
MySQL 的主从复制分成三步:
master 将改变记录到二进制日志 (binary log) 中(这些记录叫做二进制日志事件, binary log events, 可以通过 show binlog events 进行查看);
slave 将 master 的 binary log events 拷贝到它的中继日志(relay log);
slave 重做中继日志中的事件, 将改变反映它自己的数据.
Canal 就是模拟了这个过程.
Canal 模拟 MySQL slave 的交互协议, 伪装自己为 MySQL slave , 向 MySQL master 发送 dump 协议;
MySQL master 收到 dump 请求, 开始推送 binary log 给 slave (即 canal );
Canal 解析 binary log 对象(原始为 byte 流);
4.3 部署架构
核心组件:
zookeeper: 使用已有的 zookeeper 集群, 实现订阅任务的 HA
canal-admin: 数据订阅的控制层的控制台, 管理 canal-server 上的订阅任务状态与配置
canal-server: 用于运行数据订阅任务, 抓取数据库 binlog, 投递到 MQ 或者下游 client.
4.4 使用方式
Canal 支持 TCP 直接消费, MQ 消费两种模式.
为了支持多个下游消费, 减少上游数据库订阅压力, 我们使用了 MQ 消费模式.
将数据库订阅 binlog 投递到 Rocketmq, 下游用户可以利用 Rocketmq 的 Consumer Group, 多次, 重复消费对应数据, 实现业务接耦, 缓存一致性等场景.
4.5 改造适配
1)控制台 API 封装
由于 canal-admin 的技术栈还是比较新的, 有比较成熟的分层结构和独立的 rpc 接口, 因此, 在 DTS 服务中, 包装相关 canal-admin 的接口, 即可实现产品化的前台接口逻辑.
2)云原生改造
计划中, 改造为 k8s 部署, 支持快速扩缩容
5. 数据迁移模块
5.1 技术选型
跟数据订阅不同, MySQL 的数据迁移五花八门, 实现原理也都各不相同.
综合来看, 我们选择了 DataX 作为数据迁移引擎.
5.2 基本原理
DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具 / 平台, 实现包括 MySQL,Oracle,SqlServer,Postgre,HDFS,Hive,ADS,HBase,TableStore(OTS),MaxCompute(ODPS),DRDS 等各种异构数据源之间高效的数据同步功能.
我们主要使用了 MySQL 的数据同步, 它的实现原理比较简单, 就是通过
select * from table;
获取全量数据, 然后写入到目标库中.
当然, 这里利用了 JDBC 的流式查询, 避免 OOM. 同时, datax 也支持自定义限速.
5.3 部署架构与使用方式
Datax 的使用方式比较简单, 通过配置任务 JSON, 执行脚本即可.
由于数据迁移使用不多, 且基本是一次性使用, 所以暂时是直接部署在 DTS 的服务中, 通过 Java 的 Process 类进行相关处理.
创建 Datax 所需的 conf 文件, 并返回地址
使用 Runtime.getRuntime().exec()执行 Datax 的 python 脚本
根据返回的 Process 对象, 处理成功 / 失败, 执行输出日志等
后面会考虑进一步迭代, 采用独立服务器部署 Datax, 然后通过自定义 Java 服务或者使用 Saltstack 实现远程调用脚本.
6. 数据同步模块
6.1 技术选型
数据同步的方案主要有三种
综合实施性, 技术成熟度, 双向同步需求的考虑, 我们选择了 otter 作为数据同步引擎.
6.2 基本原理
基于 Canal 开源产品, 获取数据库增量日志数据. Canal 原理参考 数据订阅 的基本原理.
典型管理系统架构, manager(web 管理)+node(工作节点).
6.3 部署架构
核心组件:
zookeeper: 解决分布式状态调度的, 允许多 node 节点之间协同工作
manager: 运行时推送同步配置到 node 节点
node: 内嵌 canal, 负责 binlog 订阅, 并把事件同步到目标数据库; 同时, 将同步状态反馈到 manager 上
6.4 改造适配
1)控制台 API 封装
由于 otter-admin 的技术栈比较旧, 采用 webx 框架实现, 没有前后端分离.
因此, 需要根据已有代码, 重新封装独立的 rpc 接口, 然后才能对接到 DTS 服务中, 包装相关 otter-admin 的接口, 实现产品化的前台接口逻辑.
2)云原生改造
改造为 k8s 部署, 支持快速扩缩容, 具体可以参考我上一篇文章 拥抱云原生, 如何将开源项目用 k8s 部署?
7. 总结与展望
从产品设计, 技术调研, 架构设计到最后研发上线, 历时半年左右. 最终功夫不负有心人, 项目顺利上线, 通过前台产品的简单交互与审核, 就能秒级快速创建 DTS 任务.
目前已经支持数十个 DTS 任务(包括数据订阅, 数据迁移, 数据同步), 落地了多云数据库镜像, ES 索引构建, 数据实时同步, 业务数据订阅等多个业务场景.
未来, 还需要做进一步的技术迭代, 包括:
1)扩展数据传输引擎
目前已经在尝试接入 Redis-shake 做 Redis 的迁移与同步.
后面还会继续尝试 HBase-replication 的接入, 做 HBase 相关的任务迁移与同步.
这些都可以通过复用 通用服务能力 和 模版流程, 实现快速接入.
2)增加调度模块
后续还需要增加任务调度模块, 主要实现两方面的能力:
根据实例负载进行任务的调度, 保证资源的合理使用
根据业务特性, 重要程度做任务调度, 保证资源隔离
3)完成云原生化改造
目前只有 otter 引擎实现了 k8s 部署, 后面还需要对 canal-server,Datax 实现 k8s 部署, 满足快速扩缩容, 提高资源使用率.
如果有任何疑问或者建议, 欢迎评论或者私信我哦~
都看到最后了, 原创不易, 点个关注, 点个赞吧~
文章持续更新, 可以微信搜索「阿丸笔记 」第一时间阅读, 回复[笔记] 获取 Canal,MySQL,HBase,JAVA 实战笔记, 回复[资料] 获取一线大厂面试资料.
知识碎片重新梳理, 构建 Java 知识图谱: https://github.com/saigu/JavaKnowledgeGraph (历史文章查阅非常方便)
来源: https://www.cnblogs.com/awan-note/p/14234114.html