主要内容:
本次分享将介绍目前数据迁移、数据同步、数据消费,多IDC架构中数据复制技术所面临问题及现有的产品和方案,并分享新开源的能在异构数据存储之间提供高性能和强大复制功能的DTLE相关技术内容。
更多c/c++ Linux服务器高阶知识、电子书籍、视频等等请后台私信【架构】获取
知识点有C/C++,Linux,golang技术,Nginx,ZeroMQ, MySQL ,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等。


提纲:
1. MySQL Replication
2. DTLE核心场景
3. DTLE设计原则
4. DTLE相关介绍(架构/集群机制/ 拓扑结构 /技术栈/功能/限制)
今天主要是对DTLE的一些技术架构,跟大家分享。
1. MySQL Replication
MySQL如此受欢迎,其原因和MySQL原生支持了 Replication密不可分。基于replication能力社区也是玩出了各种拓扑架构。
1.1 MySQL Replication架构

这张图对DBA们应该并不陌生,左边是MySQL主实例,右边是My SQL 从实例,数据变更记录在binlog中。主实例的Dump 线程 ,将binlog 事件通过网络推送给从实例。
从实例的IO线程将接收到事件写入本地relay log,SQL线程读取relay log bing进行回放执行,这是MySQL Replication的基本流程。
既然MySQL已经有了数据同步能力,那为何还要做DTLE呢?
1.2 MySQL Replication的限制

筛选功能不足
MySQL Replication只能在库表级别做筛选,无法在行级别进行筛选。
· 数据落地,开销较大
MySQL Replication需要日志或数据落地,这会产生存储空间的开销。
· 灵活性较弱
无法支持较为复杂的复制拓扑结构,以及在跨网络边界不同数据中心场景的。
· 应用场景多为高可用
MySQL replication更多以高可用、读写分离应用场景为主,利用开源工具实现Master failover以及读写分离架构。
2. DTLE的核心场景
MySQL Replication主要应用在数据全同步的场景。而对于DTLE主要解决以下场景:

异地多活
异地多活的场景通常建立在网络环境不佳的条件下,我们通过数据压缩、加密、限速等方法,保障复制的可靠性、安全性、效率。解锁跨网络边际、双向同步等能力,在业务配合下,实现异地多活的。
· 数据汇聚分发
数据的汇聚和分发,需要支持到库、表、行这几个级别。比如:在业务垂直分库场景下可将前端多个分库实例汇总到实例中进行统计分析。数据行按不同条件分发到下游节点,条件可以是简单的where条件,也可是简单函数表达式等。
· 数据订阅
数据订阅的场景是对MySQL binlog日志进行解析,将增量变化实时同步给Kafka消息队列,其他系统通过kafka订阅需要的数据。
· 在线数据迁移
在线数据迁移,要简化MySQL到MySQL或其他DB到MySQL的迁移过程,减少停机时间,目前还只支持MySQL间的迁移。首先抽取全量的数据,并获取增量起始的快照点,当全量回放完毕后,从增量起始点开始同步增量数据。
这对MySQL 分布式 架构的数据分片扩容特别有帮助,一般我们将先预分片好的物理分片放在相同MySQL实例中,当数据量增长超过实例处理能力时,就需要讲分片迁移到新的实例节点,迁移过程肯定希望尽量平滑不影响业务。 DTLE可以配合我们之前开源分布式中间件DBLE,进行在线扩容。
· 云间同步
公有云RDS用户会有一些上下云和云间迁移同步的需求,我们测试了几家云厂商, 针对云厂商自研的RDS for MySQL的特点,实现不同云厂商的RDS之间进行数据同步 。
3. DTLE设计原则
以上是DTLE主要的应用场景。软件设计DTLE力求两个基本原则: 易用性与可靠性。
易用性
作为软件的使用者和开发者,我们 特别重视产品的使用体验,上手简单,易于部署 是必须的,没有复杂的部署条件要求,没有外部依赖,安装配置步骤越简单越好,尽可能符合使用者的操作习惯。
可靠性
可靠性也必不可少, 我们将DTLE的设计采用分布式的架构,具备抗单点风险和故障切换的能力 。元数据信息保存在分布式一致性KV存储中,如果某工作节点或进程挂了,工作任务会转移至其他进程继续之前的断点处理数据同步,不影响服务连续性。
4. DTLE相关介绍

DTLE (Data-Transformation-le) 是爱可生10月24日在“程序员节”贡献开源社区的 CDC 工具 ,主要具备以下特点:
• 多种数据传输模式 :支持链路压缩,支持同构传输和异构传输,支持跨网络边际的传输
• 多种数据处理理模式 :支持库/表/行级别 数据过滤
• 多种数据通道模式 :支持多对多的数据传输、支持回环传输
• 多种源/目标端 :支持MySQL – MySQL的数据传输,支持MySQL – Kafka的数据传输
• 集群模式部署
• 提供可靠的元数据存储
• 可进行自动任务分配
• 支持自动故障转移
4.1 DTLE架构

DTLE架构上包含两种角色的进程,Agent角色与Manager角色 。Manager角色主要负责元数据信息存储,任务的接收和分发,Agent节点健康状态检测、故障转移。Agent主要负责数据读取,binlog解析,数据筛选、压缩、传输、回放等。
用户通过http协议访问Manager发布job,job是以json格式的配置项,里面定义了源数据库实例,目标数据库实例,需要复制的schema或table对象,数据的筛选条件等信息,任务提交后manager会分配给可用的agent进程,agent根据任务配置连接数据库实例,开始全量或增量的数据同步。
4.2 DTLE的集群机制

DTLE 的manager节点可以部署多个冗余节点,节点之间的元数据信息同步和故障切换都是利用Raft分布式一致性协议来保障的。
woker节点接收来自Manager发来的任务请求,并实时上报自己的状态。当Manager的Leader节点发现worker无响应时,会通知可用的agent继续执行同步任务。
4.3 DTLE的拓扑结构

DTLE支持的多种拓扑结构,最简单的1对1同步,n对1的汇聚同步模式,1对n的数据分发同步模式。

在跨数据中心的场景,虚线框内是两个不同的数据中心, DTLE部署在不同的数据中心,DTLE负责本数据中心的数据读取或回放,DTLE将数据压缩后通过网络发送到对端,减少了对带宽的利用,适用于窄带宽的网络环境下 。
在跨数据中心有多个实例之间需要数据同步,如果通过MySQL Replication需要建立多条链路通道,而通过DTLE可以在数据中心间建立一条通道同步多个实例的数据,网络策略配置更简单,也避免了MySQL服务对外暴露。
跨数据中心的双向同步能力,可以应用在数据中心双活的场景,但数据层自身还无法做冲突检测,需要在应用层来保障数据不会冲突。
4.4 DTLE技术栈
在DTLE的开发过程中我们借助了一些优秀的开源组件,来支撑起整个架构。

我们选用的 开发语言是Golang ,它的好处是开发效率高,性能有保障,部署也方便,build后的二进制文件自带运行时环境,完全不需要担心软件依赖问题。
网上有许多优秀的Golang开源项目,Hashicorp公司就是其中一家以分布式应用见长的开源软件公司,他们开发了很多优秀的DevOps 基础设施组件,包括Vagrant、Packer 、 Terraform 、Serf 、Consul , Vault 和 Nomad 等,我们使用了部分组件来构建DTLE。
nomad是一个集群管理器和调度器 ,我们利用它来构建基础架构,解决的任务调度和集群管理的问题,在此基础上我们开发所需的任务模板。
consul是一个分布式KV存储 ,nomad也集成了consul,我们用它来做manager元数据信息存储。
serf是基于gossip协议的节点状态检测组件 ,能够快速检测到故障节点并踢出集群,主要用来解决agent节点的failover,如果某个agent节点不可用,这个节点就会被移出集群。
NATS是一款开源的轻量级消息系统组件 ,我们在agent之间的数据传递使用了NATS。
以上是DTLE采用的开源组件。如果之前对这些组件有所了解,可以帮助理解DTLE的架构原理。
4.5 DTLE功能

DTLE的回放是支持binlog回放和SQL回放 。binlog回放不需要对binlog事件进行转换,可以直接在MySQL中回放,精度高,但无法做数据转换或筛选。SQL回放是直接把binlog事件解析成SQL文本,可以进行数据的转换和筛选。
我们模仿了MySQL MTS并行回放机制,基于MySQL 5.7的逻辑时钟模式,提高并行回放的效率。
自动建表,在数据迁移的场景下,目标端不需要事先建立表结构,只需要定义好job需要同步的对象,DTLE会自动建表并同步存量数据。
DTLE的全部功能总结:
· 集群式架构部署,支持故障转移
· binlog回放、SQL回放
· 仿MySQL MTS机制并行回放
· 支持增量断点续传
· 全量&增量同步
· 库级、表级、行级筛选
· 链路压缩、跨网络边际
· 自动建表
· 支持DDL
4.6 DTLE限制
· 仅支持 MySQL 5.6/5.7 版本
· 仅支持 InnoDB 引擎
· 仅支持以下字符集: latin1、latin2、gbk、utf8、utf8mb4、binary
· 仅支持binlog_format=row和binlog_row_image=full
· 源端和目标端lower_case_table_names配置必须保持⼀一致
· 必须开启 GTID
· 不支持 Trigger
· 仅支持MySQL认证方式 mysql_native_password, 暂不支持其他类型的default_authentication_plugin
5. 同类对比
我们选取了其他同类的开源软件debezium、streamsets、otter、DTLE,一起横向对比了相关特性。

全量/增量
debezium是支持全量增量的,对于streamsets和otter他们并没有全量支持,只能做一些增量数据的支持, DTLE支持全量和增量 。
· 元数据全局一致性
元数据信息的全局一致性是指在做全量数据迁移时如何获得增量数据起始的一致性位点。debezium是通过全局读锁或者快照搜索实现的。streamsets和otter不支持全量,所以也不用考虑这个场景。
DTLE没有使用全局读锁,它在快照读的事务中读取存量数据,并在事务开启前后分别获取GTID 。如果前后两个GTID是相等的,意味着在这个事务开启之后即使没有新的更新,后续可以从此GTID做增量同步。如果说前后两个GTID不等,事务将回滚,再重复上述流程。
· 数据过滤
在数据过滤方面,debezium支持库级, streamsets支持行级,otter可以自定义, DTLE是库、表、行三个等级都支持 。
· 数据映射
数据映射上,debezium能够支持到表级的映射到普通表之间,原表、录入表可能不同的表之间可以进行数据映射。同样streamsets也是,otter也可以灵活自定义。DTLE当前不支持数据映射,还在Roadmap中。
· 事务性
在MySQL binlog中一个事务可能包含多个event,我们选择兼容在回放时保持其事务性。debezium可以做到源端的事物性,但不支持目标端的事务性。streamsets本身是没有事务性的,按event产生进行回放。otter不保持回放的事务性,为了提高入库的效率会进行合并操作。 DTLE其实目标端和源端都可以保证事务性 。
· GTID
DTLE会维护一份独立的GTID信息,主要来解决一些环形复制场景 。其他三者都是不维护GTID信息的。
· 源端类型
源端类型,debezium支持的数据类型比较多,包括MySQL、Mongo、 PostgreSQL 、Oracle这几种都支持。MySQL是基于binlog,mongo是基于 Oplog,其他几种PG,SQL sever应该是通过CDC的方式,而非基于日志方式。streamsets支持许多中数据源,不详细展开了,otter主要是MySQL。DTLE还只是支持MySQL一种数据库。
· 目标端类型
debezium仅限于Kafka作为目标端。streamsets支持很多的目标端,不再详细展开。otter支持 MySQL和Oracle,DTLE当前仅支持MySQL和Kafka。
· 部署方式
在部署方式上,debezium和streamsets都是单节点,otter是集群化的部署方式, DTLE支持单机和集群化部署 。