Arkgate源起
随着数据库、大数据生态的普遍应用和数据联动的重要性,MySQL数据库运维过程中关于数据同步需求不断增多,常见的需求有:
1.从源端分库分表的MySQL集群进行数据汇总,数据合并到一个MySQL集群中。
2.从源端MySQL同步数据到HBase或者ES等OLAP类型的存储引擎中。
3.从源端MySQL同步数据回流到Redis等缓存引擎中。
4.从源端的一种MySQL表结构按需同步数据到另外一种MySQL表结构中。
数据同步过程中往往要求数据同步时效性高,需要实时或者准实时的同步。满足时效性的同时还要兼顾各种数据同步的需求,相比的不易操控原生主从复制,想着有一个第三方的主从同步软件来实现数据同步的功能,它可以实现:
a.对数据库表的更新做异构化,当上层数据库表结构及存储方式不能满足应用需求时,可以自动完成数据转换、数据清洗及数据装载的功能,同步数据并持久化到另一种适合应用程序访问计算的表结构中。
b.针对一些统计业务,可以获取每天的增量数据同步到大数据系统中,例如存储到HBase中供数据部门进行数仓分析。数据同步软件充当桥梁,进行OLTP和OLAP系统隔离和数据联通,它实时地获取到源端MySQL最新的数据变化并同步到目标OLAP数据库中,这样就可以既利用到了专业OLAP数据库对数据的快速处理,又避免了长时间的数据同步对OLTP的影响,同时还保证了被分析数据的时效性。
c.当目的端同样是MySQL数据库时,亦可满足MySQL数据库异地同步、异地双活、跨云容灾的需求。
基于诸多数据同步的需求,诞生了这款数据整合利器-MySQL实时异构同步系统Arkgate。
Arkgate架构
Arkgate设计之初来源于MySQL的运维需求,在进行架构设计过程中也是想兼顾着Arkgate 100%兼容MySQL语法及对源端目的端完全透明的想法。
基于强大的MySQL Replication功能,对于源端MySQL数据库的变更,Arkgate模拟了MySQL从库的IO Thread,不断地Dump MySQL的Binlog Events,实时地将源端MySQL数据库的增量更新同步到目标OLAP数据库中,其架构图如下:
源端可支持MySQL所有分支版本,目的端数据库支持HBase、Elasticsearch、MySQL、Redis、TiDB、Kafka等诸多数据库,以解决不同人群及业务的需求。满足同构、异构数据源间数据迁移和实时同步的需求。考虑到多目的端适配、增量数据同步和断点续传的需求,Arkgate分为三大组件,一个是Arkgate 采集组件,一个是Arkgate存储组件,一个是Arkgate同步组件。
Arkgate采集组件作为一款MySQL的插件,用于模拟MySQL Slave采集源端的Binlog Events,插件方式安装方便且可兼容所有MySQL版本的Binlog格式,能复用官方多线程并发复制的功能,同时还支持多通道复制,一个插件可以为多个集群做数据同步。
Arkgate存储组件用于持久化存储源端数据的变更,简称Arkgate 数据中心,目前支持使用原生MySQL和ArkDB来作为Arkgate存储层,它负责持久化存储自Arkgate采集源端某一个时间点后的增量数据。
Arkgate同步组件用于数据同步,简称Arkgate Adapter,它只需要访问Arkgate存储组件的数据,便可以满足不同目的端数据同步的需求,当需要新增一类目的端数据源时,适配Adapter即可快速满足数据同步的需求。
Arkgate三大组件支持在一台机器混合部署。
架构图进一步演变为:
Arkgate实现方式和MySQL数据库主从是同一个道理,其Arkgate采集组件会伪装成一个从库,从源端MySQL主库上dump指定的binlog,Arkgate收到之后将其解析出来,直接在线转换成为一种更通用的Json数据格式存储到Arkgate数据中心中。
Arkgate采集层写入Arkgate 数据中心的方式支持本地和远程插入,本地插入是当Arkgate采集组件和Arkgate数据中心复用同一个MySQL时,如果两者独立部署则为远程插入。Arkgate采集层是做为Arkgate 数据中心的客户端进行数据插入的。
Arkgate数据中心的数据是可以对外提供服务的,开发只需关注datacenter数据库即可获取源端增量数据的更新,其存储方式为Json。
Arkgate Adapter解析Json数据并按需装载到目标数据库即可即可实现数据库的异构实时同步需求。
相比MySQL原生复制而言,Arkgate进行了同步数据持久化存储。那么性能会有损耗吗?当MySQL同步压力不大时,Arkgate同步会慢于原生MySQL复制。但当并发压力大吞吐量大时,Arkgate同步性能要远远优于原生MySQL复制。这是因为Arkgate除了支持多线程并行复制时还支持配置多个同步通道,在上述架构图中每一个复制都是一个单独并且完全独立的通道,通道由一个MySQL源端和一个目的端数据源共同确定。不同的通道可以对应同一个数据库实例,在每新建一个通道时需要给对应的通道起一个datacenter名字,通道名实质是一个数据库名字,配置多个通道时会在Arkgate数据中心创建多个数据库,Arkgate采集组件会将所有拿到的Binlog解析后存储到各自对应的datacenter中。同样Arkgate Adapter支持并行向目的端进行数据装载,大大提升数据同步的性能,保证数据同步实时性。
Arkgate同步原理
Arkgate同步流程
Arkgate数据同步流程简洁明了,它不会侵入线上源端和目的端,只需要在源端MySQL和支持的目的端数据库类型进行访问授权即可,其主要流程为:
1.在线MySQL , 提供源端MySQL实例或集群的访问信息,源端可以是RDS、自建数据库。需要在源端给Arkgate 采集组件进行用户授权。例如:
mysql>GRANT select,replication client,replication slave ON *.* TO 'arkgate'@'arkgate 服务器 IP' IDENTIFIED BY 'arkgate_test' ;
2.Arkgate采集,Arkgate部署完成后Arkgate即可模拟MySQL从库的IO Thread,不断地Dump MySQL的Binlog Events,实时地将源端MySQL数据库的增量更新在线转换为JSON数据格式存储到Arkgate数据中心。
3.Arkgate数据中心,可以是MySQL或ArkDB数据库实例,可以存储多个Arkgate通道的数据。考虑资源使用情况,支持Arkgate采集组件在Arkgate数据中心部署。
4.Arkgate Adapter,由go语言开发的数据装载程序,可以内置HBase、ES、MySQL、NewSQL的Adapter程序,实时往目标异构数据库消费Arkgate数据中心的数据,完成数据实时异构的数据转换、数据清洗及数据装载。
5.目标异构数据库,即需要数据实时同步的存储库。例如HBase、ES、ArkDB/MySQL/TiDB/Kafka/Redis等。需要在目的端给Arkgate Adapter进行用户授权。例如:
mysql>GRANT all on *.* to 'arkgate'@'arkgate adapter 服务器 IP' identified by 'arkgate_test';
Arkgate创建复制通道
Arkgate部署完成后,创建复制通道非常简单。登陆Arkgate采集层所在MySQL/ArkDB实例,手动部署流程如下:
mysql> set global arkgate_create_datacenter="arkgate_test";
# 此命令会创建一个名为arkgate_test的通道,它会在Arkgate datacenter创建arkgate_test库来存储该通道解析的Binlog数据
mysql> set global arkgate_replication_source ="arkgate_test:1";
# 此命令1表示原生mysql实例(默认值),2表示源为公有云
mysql> set global arkgate_json_full_image="arkgate_test:1";
#此命令用于控制是否同步表的默认值、comment等信息
mysql> set global arkgate_replication_member="arkgate_test:master:db1:127.0.0.1:3306";
#此命令需要指定复制的源端数据库, arkgate_test为创建的datacenter名称, master说明同步的是主库。其中,db1为同步实例名称,可以根据需要设置,后边的IP和port为源库ip,port信息
mysql> set global arkgate_replication_binlog_position="arkgate_test:mysql-bin.000001:154";
# 指定arkgate同步源端的binlog文件和position点
mysql> set arkgate_json_include_serverid="arkgate_test:1";
# 此命令用于双活场景时保存server_id信息
mysql> set global arkgate_replication_start = "arkgate_test:arkgate:arkgate_test";
# 此命令启动arkgate同步:arkgate_test为设置的datacenter通道名,然后是连接源库的账号密码
复制通道创建成功后,即可实时查看同步的状态:
mysql> select * from information_schema.arkgate_datacenter_full_list\G;
*************************** 1. row ***************************
Datacenter_Name: arkgate_test
Instance_Name: db1
Master_Host: 127.0.0.1
Master_Port: 3306
Binlog_File: mysql-bin.000001
Binlog_Pos: 154
Transfer_Running: Yes
Last_Error:
Stop_Time:
Transfer_Stage: transfer_wait_master_send
Seconds_Behind_Master: 0
Slave_Members:
Sql_Buffer_Size: 0 Bytes
Table_Cache_Elements: 0(0 Bytes)
Parallel_Workers: 5
Worker_Queue_Length: 10000
Events_Per_Second: 0
Trxs_Per_Second: 0
Master_Gtid_Mode: Yes
Checkpoint_Period: 50(ms)
1 row in set (0.02 sec)
Arkgate系统库表
创建通道后会在Arkgate采集层所在MySQL/ArkDB实例的information_schema 创建如下系统表:
mysql> use information_schema
Database changed
mysql> show tables like '%arkgate%';
+------------------------------------------+
| Tables_in_information_schema (%arkgate%) |
+------------------------------------------+
| arkgate_datacenter_threads |
| arkgate_datacenter_full_list |
| arkgate_fliter_list |
| arkgate_slave_list |
| arkgate_datacenter_list |
| arkgate_datacenter_options |
| arkgate_datacenter_tables |
+------------------------------------------+
7 rows in set (0.00 sec)
其库表简述如下(名称:说明):
arkgate主体插件
安装后可以通过show variables like "%arkgate%";命令看到所有包含的变量。
arkgate_datacenter_threads
information schema插件,这个插件主要是用来观察每一个通道下,同步binlog到datacenter的线程的状态。查询这个表可以查到所有通道的线程状态,可以通过增加where条件来查询某一个通道的信息。
arkgate_datacenter_full_list
information schema插件,这个插件是用来查看所有通道的详细信息的,包括复制状态,位置信息等,可以通过where条件指定通道名称查询具体某一个通道的信息。
arkgate_filter_list
information schema插件,这个插件是用来查看所有通道定义的白/黑名单的,即定义哪些库需要复制,哪些是不需要复制的。可以通过where条件指定通道名称查询具体某一个通道的信息。
arkgate_slave_list
information schema插件,这个插件是用来观察所有通道定义的从库状态信息,可以通过where条件指定通道名称查询具体某一个通道的信息。
arkgate_datacenter_list
information schema插件,这个插件是用来查看所有通道的简单状态的,包括是否正常复制及延迟时间,主要是为监控程序服务的。可以通过where条件指定通道名称查询具体某一个通道的信息。
arkgate_datacenter_options
information schema插件,这个插件是用来查看所有通道的独享配置变量信息的,可以通过where条件指定通道名称查询具体某一个通道的信息。
arkgate_datacenter_tables
information schema插件,这个插件是用来查看所有通道复制时,对具体某一个表的命中及分发状态,如果某一个表的binlog事件很多,那相应的引用计数就会很大,可以通过where条件指定通道名称查询具体某一个通道的信息。
同时会在Arkgate Datacenter所在的MySQL/ArkDB实例创建与通道同名的arkgate_test库来存储该通道解析的Binlog数据。
mysql> use arkgate_test
Database changed
mysql> show tables;
+----------------------------+
| Tables_in_arkgate_test |
+----------------------------+
| instances |
| master_positions |
| slave_positions |
| transfer_checkpoint |
| transfer_data |
| transfer_filter |
| transfer_meta |
| transfer_option |
| transfer_sequence |
+----------------------------+
9 rows in set (0.00 sec)
其库表简述如下(名称:说明):
instance
存储这个datacenter中要复制的主节点与从节点的配置信息。
master_positions
存储在复制过程中binlog以事务为单位的结束位置或者开始位置。
slave_positions
存储的是在instances表中所记录的所有slave节点。在master节点上分析到一个事务的结束位置时,会取一次slave的show master status;位置,这个信息会存储到这个表中。
transfer_data
存储将binlog转译之后的JSON数据,为源端增量同步数据。
transfer_checkpoint
存储最新的checkpoint位置信息。
transfer_filter
存储复制白名单及黑名单信息。
transfer_meta
存储复制过程中所有表的元数据信息。
transfer_option
存储复制一些配置参数
transfer_sequence
存储Arkgate维护的自增ID的表。
了解这些Arkgate的库表信息后,就可以进一步深入了解Arkgate同步原理及Arkgate如何适配源端、目的端数据库类型的操作流程。
Arkgate同步原理
至此大家都知道Arkgate采集层是伪装成源端MySQL的从库,通过实时订阅Binlog Events并把它解析转换为JSON格式的数据,然后通过HASH分发存储到Arkgate数据中心。
整个实时订阅过程是多线程并发处理的,那么存在一个问题是最新被处理的Binlog有可能是不完整的,存在空洞,因为线程通过操作系统内核调度时执行有先有后,最新执行的事务前面经常会存在还没有执行的事务,而此时最新的事务已经插入到datacenter中了,而没有执行的当然在datacenter中不会有,那么如果应用程序读的太快的话,就会导致有些数据读不到,因为应用程序已经认为读过的位置之前的事务都已经读取完毕了。那这样就导致了数据丢失的问题。
Arkgate 是通过transfer_checkpoint表来解决数据空洞的问题,transfer_checkpoint表结构如下:
mysql> show create table transfer_checkpoint\G;
*************************** 1. row ***************************
Table: transfer_checkpoint
Create Table: CREATE TABLE `transfer_checkpoint` (
`flag` int(11) NOT NULL COMMENT 'primary key placeholder',
`id` bigint(20) unsigned NOT NULL COMMENT 'eid',
`tid` bigint(20) unsigned NOT NULL COMMENT 'tid',
PRIMARY KEY (`flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='checkpoint sequence, before which are all avialable'
1 row in set (0.00 sec)
transfer_checkpoint表用来存储最新的checkpoint位置信息,只有一行数据,每一个列的具体意义如下:
flag: 数据写入时该字段数据恒为0即可。
id: 表示可安全读取的最大事件id。
tid:表示可安全读取的最大事务id。
transfer_checkpoint表只存储了两个id值,这两个id值就是对应transfer_data中的id值,在transfer_data表中,所有小于这两个id值的数据都是完整的,不会丢失数据,而大于这两个值的数据,则事务之间存在空洞的问题。这个表只会有一条记录。简单而言,在应用程序使用过程中,只要把这个表中的id值记录为当前可以读取的最大位置即可,可以保证数据安全。
而transfer_data表是用来真正的存储将Binlog转译之后的Json数据的,在给业务程序使用的时候,只需要不断轮循这个表中的数据,通过id范围来不断拉取新数据即可,当然id范围是不可以大于transfer_checkpoint表中的id值的。transfer_data表结构如下:
mysql> show create table transfer_data\G;
*************************** 1. row ***************************
Table: transfer_data
Create Table: CREATE TABLE `transfer_data` (
`id` bigint(20) unsigned NOT NULL COMMENT 'id but not auto increment',
`tid` bigint(20) unsigned NOT NULL COMMENT 'transaction id',
`dbname` varchar(64) DEFAULT NULL COMMENT 'dbname',
`tablename` varchar(64) DEFAULT NULL COMMENT 'tablename',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'the create time of event ',
`instance_name` varchar(64) DEFAULT NULL COMMENT 'the source instance of this event',
`binlog_hash` varchar(64) DEFAULT NULL COMMENT 'binlog_hash',
`optype` varchar(64) DEFAULT NULL COMMENT 'operation type, include insert, update...',
`data` longblob COMMENT 'binlog transfer data, format json',
PRIMARY KEY (`id`,`tid`),
UNIQUE KEY `uniq_binlog_hash` (`binlog_hash`),
KEY `idx_dbtablename` (`dbname`,`tablename`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='binlog transfer data'
1 row in set (0.00 sec)
这里只介绍关键的两个字段id和tid,字段值和transfer_checkpoint表关联,涉及到数据安全。
ID,这个列存储的是一个序号,是Arkgate自己维护的一个自增序号,每读一个Binlog事务,序号就加1,因为每一个事务是一个Binlog的原子单元,arkgate在存储时也是以事件为单位的。维护一个这样的ID,主要是为了与另一个列TID一起来做联合主键使用的,因为Binlog在文件中是有序的,而插入到transfer_data中之后(如果是并发插入的话),如果没有这个联合主键的话,很难保证实际的顺序,同时这也是为开发提供的一个自己维护的游标信息,在具体使用过程中,开发需要自己来维护这两个ID值,这样才能知道异构数据已经同步到什么位置了。
TID,这个值是与Binlog中的事务相关的,每次开始一个新事务,这个值就加1,也就是说,在transfer_data表中,不同数据中,如果TID的值相同的话,说明这些变更是同一个事务产生的,但是ID值肯定是不同的。
那么数据同步过程中如何感知源端DDL变更呢?transfer_meta这个表就是做这个事,它主要是用来存储在解析Binlog的过程中,出现的所有表的元数据信息,以Json格式存储。transfer_meta表结构如下:
mysql> show create table transfer_meta\G;
*************************** 1. row ***************************
Table: transfer_meta
Create Table: CREATE TABLE `transfer_meta` (
`dbname` varchar(64) NOT NULL COMMENT 'database name',
`tablename` varchar(64) NOT NULL COMMENT 'table name',
`version` bigint(20) NOT NULL COMMENT 'map to transfer_data column id',
`metadata` text COMMENT 'table struct',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'the load time of table',
PRIMARY KEY (`dbname`,`tablename`,`version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='transfer meta data '
1 row in set (0.00 sec)
列定义如下:
dbname,表示当前表所属的数据库名。
tablename,表名。
version,表示当前表结构的版本号,针对同一个表,在transfer_data中的id列的值,处于当前version和下一个version之间时,需要使用当前version的表结构。也就是说,根据transfer_data中的id值,找到大于这个id值的version中最小的那个,就是当前所需要的meta信息。
metadata,当前表结构的Json格式存储。
update_time,出现时间。
transfer_meta表的作用是将所有在复制时用到的表对象,分析之后转换为Json格式的表结构,方便上层应用程序对Json格式的Binlog中使用到的表有足够的了解,在应用程序每次读取datacenter中的数据时,遇到一个表时可以首先来这里获取表结构,这个表里面存储的表结果,是不断更新的,都是最新版本的表结构的Json存储。与transfer_data表中的optype列的meta值对应,如果值是meta时,说明有新的表出现了,或者这个表在被修改之后,又一次出现了。
Arkgate保证同步的数据安全后,Arkgate adapter只需要消费transfer_data表中的数据往目标数据库进行数据装载即可。
至此Arkgate同步原理告一段落,其同步流程如下图:
Arkgate适配
目前Arkgate源端只支持MySQL,目的端支持适配HBase、ES、ArkDB/MySQL/TiDB/Kafka/Redis等。如果基于Arkgate需要新增Arkgate的源端和目的端适配该如何处理呢?
新增源端适配-Oracle举例
如何同步Oracle数据非本文讨论重点,重点在于介绍支持Oracle同步的工具如何适配Arkgate。其实这里可以将Oracle同步的工具当做Arkgate datacenter的客户端,按照Arkgate自定义的数据格式进行数据写入即可,这样可以复用当前的Arkgate Adapter实现对多种类型目的端进行同步。
前面介绍transfer_data表时说过此表是真正存储同步源端的增量数据,其数据是转存储为JSON数据格式存在transfer_data表data字段中。那么从源端同步的数据按照如下的格式进行JSON数据适配即可完成源端数据库类型适配。
DML JSON格式
tranfer_data的data字段存放的是Json数据格式,里面的pk代表主键的索引下标,表示表的第几列为主键,"pk":[0]表示表的第一列为主键,"pk":[0,1]表示表的第一列和第二列为联合主键。
insert操作只有new数据。
update操作有new和old 数据。
delete操作只有old数据。
DDL JSON格式
Truncate操作的JSON内容如下,DATA列为空,没有任何数据
ALTERTABLE操作JSON内容如下
RENAME操作的JSON内容如下:
DDL操作,transfer_data都是optype=meta的记录。data数据表示操作后的表结构。
数据插入transfer_data时需要维护OPTYPE的类型,这个列存储当前事件的操作类型,目前包括INSERT、UPDATE、DELETE、TRUNCATE、ALTERTABLE、RENAME、CREATETABLE、META。其支持的类型来源是:
optype:
ddl: META,CREATEDB,CREATETABLE,ALTERTABLE,RENAME,TRUNCATE,DROPDB,DROPTABLE
dml: INSERT,UPDATE,DELETE
应用程序(例如Arkgate Adapter)需要哪一种变更,就处理哪一种,否则可以直接忽略或者不查即可,如果值是META时,说明有新的表出现了,或者这个表在被修改之后又一次出现了,此时就需要去arkgate_meta表中获取最新的meta信息。需要注意的是meta每次改表建表都会有, 所以meta后面不一定都是create table,只是提醒消费者,原表的表结构是什么样子,后面如果是alter table的话,就可以直接用了。或者提醒消费者表结构发生了变化,需要新载入一个表。
meta是一个逻辑上的东西,meta的主要作用是增量同步到目的库,当arkgate adapter发现目的库没有表结构时adapter会根据meta创建表结构。
新增目的端适配
新增目的端相比新增源端更简单明了,Arkgate adapter当作目的端的客户端进行数据同步即可,需要同步的数据来源于transfer_data表。
Arkgate运行要求
Arkgate使用过程中,对于源端MySQL和数据同步的内容如下要求:
1.要求源端MySQL必须记录Binlog并且设置binlog_format为ROW、binlog_row_image为FULL。其源端MySQL类型支持MySQL、ArkDB、PXC、MGR、MGC及公有云RDS,源端不同MySQL集群架构及分支版本都可以通过同一个Arkgate来做数据传输。
2.Arkgate需要源端所有数据库的查询权限。
3.源端需同步的表必须有主键和InnoDB存储引擎。
4.Arkgate只同步库表级别DDL和数据,不同步视图、触发器、存储过程和函数。
Arkgate功能介绍
库表聚合
Arkgate支持分库分表数据合并,库表合并逻辑丰富,支持的功能列表如下:
过滤同步
Arkgate支持字段过滤和DDL操作过滤同步,支持的功能列表如下:
数据压缩及加密
Arkgate支持数据压缩及加密。
1.Arkgate提供参数arkgate_compression_write用来控制Arkgate在向DataCenter写入数据时是否开启压缩功能,支持在线修改。已有通道需要stop复制通道再start 复制通道才能生效。
2.Arkgate支持使用官方MySQL SSL来完成数据传输加密。
数据冲突处理
Arkgate 中的 adpater程序支持数据冲突处理。数据冲突处理针对有主键或者唯一键的表,对于源端(src)的每个 DML 修改的行的主键或者唯一键字段都会和目的端(dst)做验证,如果两端数据不 一致,会在 conflict_log 表中记录源端、目的端信息、DML 操作类型和 SQL 语句、源端旧数据、源端新数据、目的端冲突数据、在目的端操作类型、回滚语句,并且给出执行建议。
数据冲突处理目前支持四种处理模式:
exec_mode =0 ,表示数据冲突时则目的端跳过冲突数据不做任何处理,冲突日志会记录每个冲突的数据并记录跳过的SQL语句。
exec_mode =1 ,表示数据冲突时则目的端会覆盖执行replace into来保证与源库数据保持一致,冲突日志会记录冲突数据并自动生成回滚语句。
exec_mode =2 ,表示自动化数据冲突处理且可以原生自动回调第三方程序接口(如客户已有系统接口)以实现自动处理冲突数据。
exec_mode=3,表示数据冲突则arkgate adapter自动退出,冲突日志会记录冲突数据。
重点说一下exec_mode=2的执行方式,Arkgate支持自动化数据冲突处理且可以原生自动回调第三方程序接口(如客户已有系统接口)以实现自动处理冲突数据。对接线上业务系统的数据逻辑来处理数据冲突,将抉择权上交给业务,通过业务定义的数据冲突处理逻辑来保证数据的最终一致性。当遇到满足冲突逻辑的数据时,统一返回给业务层进行数据处理,从业务角度来把控数据准确性,保证数据的最终一致性,实现异地双活中数据分类和校验逻辑。
Arkgate 加载由业务提供的数据冲突处理 API 后,当遇到满足冲突逻辑的数据时,Arkgate 统一返回给业务层进行数据处理,从业务角度来把控数据准确性,保证数据的最终一致性,整个数据冲突处理过程非阻塞。
通过加载 API 实现数据冲突处理的做法,也属于业内首创,即完美解决了数据库冲突,同时也对业务非常友好,提高了系统的灵活性。
异地双活
MySQL 数据实时异构同步系统的另一大核心功能 MySQL 数据库异地多活,以满足数据库跨数据中心、跨云、跨地域的多活需求。要求如下:
1.通过数据实时同步功能实现异地双活两 IDC 间 MySQL 数据库的数据传输和实时同步,输入源为 MySQL,输出源为 MySQL。传输过程中解决数据传输、数据回环、数据冲突检测和处理、数据最终一致性问题。
2.通过异地多活功能实现混合云间、跨 IDC 间的多活,可以直接进行流量切换,支持一致性读配置,支持跨云或跨 IDC 全链路服务监控。
除了已经介绍过的数据冲突处理外,数据延时优化和数据回环解决及数据一致性读是异地双活建设中必须要优化解决的问题。
数据延时优化
多活系统中的最大挑战是数据同步延时问题,光速是一定的,距离越远则网络传输的时间越长,常说的 1000 公里以上则换算为 30ms 的网络延迟(来回一次)。对于应用而言,单次后端交互的数据访问新增 30ms 延时是无法容忍的。
对于异地多活的系统而言,多点写入是最快解决由于距离产生数据延时问题的方法。由应用层进行业务单元化,例如单笔交易的所有操作都在距离最近的当前机房内完成,这样可以保证对于自己而言,访问的机房数据是最新的。例如业务按照某个维度将流量切分到各个业务单元。按业务单元分类的数据访问请求只能在同一个业务单元中单点写入进行,尽量保证业务单元内的所有业务请求都在自身单元内完成,减少跨地域的访问调用。
同时进行多线程并行同步,能够高效保证低延迟准实时的进行数据同步。
数据回环解决
多活系统中最受关注的点是数据如何破环,即自身的数据变更不会再次同步到自己重复执行。Arkgate 在数据同步传输过程中能够识别数据来源和管理数据复制的生命周期(arkgate内部维护的全局server_id),当属于自身 IDC 的数据流再次回传给自己时,忽略这部分数据变更,让数据变更生命周期化。
解决数据回环问题后,当两边的 IDC 同时进行数据变更,即可实现系统异地多活需求。
数据一致性读
Arkgate 的一致性读分为自定义一致性读和自路由一致性读。
1)自定义一致性读可以理解为是通过 Arkgate 多活组件数据库中间件提供的透明读写分离、权重分发、Hint 分发等特性来控制读写请求的路由策略,可以自定义将需要强一致性的读写请求放到实时写节点上进行强一致性读,此方式成为自定义一致性读。
2)自路由一致性读是 Arkgate 可以自身设置读请求在从节点多少延迟范围内进行一致性读,当读节点的请求超过设置的延迟阈值后,Arkgate 自动会将相关的读请求路由到写节点上,保证数据强一致性。当数据延迟降到可接受范围内,读写请求又可以自动化按需读写分离。
其中自定义一致性读是语句级别的,即可以在语句级别配置分发规则到指定的读写节点进行数据访问。自路由一致性读是表级别的,即可以配置某一张表当后端读写节点延迟过大时,该表的读写请求会统一分发到实时写节点,保证数据强一致性。
高可用切换
异地双活涉及到的组件有 Arkgate、ArkProxy、ArkSentinel 及 MySQL 高可用集群,后端 MySQL或公有云RDS 高可用集群切换根据架构不同有不同的切换方案,此处不做介绍,着重分析 Arkgate、ArkProxy、ArkSentinel 的高可用切换。
首先是 ArkSentinel,使用 5 节点的分布式哨兵集群,节点间自身互相高可用。当 ArkSentinel 发生故障,由于组件的轻量级,重新启动即可。ArkSentinel实时监控 ArkProxy、Arkgate 的运行状况,实现其系统监控、故障发现、故障自动切换等功能,加上 Arkproxy 和 Arkgate 的配置可持久化的特性,发生故障时,ArkSentinel 自动发起投票将可用的 Arkproxy、Arkgate 的从库提升为主库,完成故障转移的功能。
其次是 Arkproxy,Arkproxy 集群是使用 Master-Standby 两节点的高可用方 案,通过ArkSentinel监控节点进程的存活,使用 VIP 或 DNS 对外提供一个统一的入口。当 Arkproxy Master 节点出现故障时,由 ArkSentinel 将实时的配置信息、路由信息持久化到 Standby 节点,同时 ArkSentinel发起切换将 VIP 或DNS 绑定在 Standby 节点并提升为 Master,整个切换过程对前端应用基本透明,业务无感知。
最后是 Arkgate,Arkgate 数据同步的元数据信息是保存在 MySQL 高可用集群中的,当 Arkgate 节点故障停止后,重启 Arkgate 节点并访问元数据信息即可断点续传输之前的进度。当 Arkgate 节点不可恢复时,可以快速提升 Standby 的节点为 Master。
综上所述,整个跨云异地双活的架构图如下:
Arkgate核心特性
最后总结下Arkgate的核心特性:
实时
Arkgate将自己伪装成一个MySQL的从库,通过实时订阅Binlog Events并把它解析转换为JSON格式的数据,然后通过HASH分发存储到数据中心(MySQL数据库)。Arkgate的Adapter系统从数据中心将JSON格式的数据取出来,并行存储到目标数据库中。这个过程与MySQL主从复制类似,是准实时的复制,并且是并行处理的。
异构
在数据传输的过程中,Adapter系统可以方便地根据需要异构化数据,把重新组合的数据传输到目的端不同的存储系统中。 数据到目标数据库列的对应关系,实现了异构存储。
多通道
Arkgate可以实现多通道的数据复制,各个通道之间不会互相影响,这样不但可以节省资源,同时还可以把多个源数据库的数据同步到一个目的端,实现数据的归并。
并行
Arkgate通过独特的同步机制,实现了支持随机分发、按照表名分发的功能,将Binlog顺序存储的数据,巧妙地转换为并行处理机制,一方面保证了数据同步的实时性,另一方面提高了机器资源的使用率,节省资源,避免常见的MySQL Replication延迟问题。
插件式
Arkgate采集层是一款MySQL的插件,使用起来非常方便,安装之后即可使用。Arkgate会把复制过程中的相关状态存储在information schema的表里面,可以查看相关表获得相应信息,实现状态监控和报警。
数据完整性
Arkgate可以保证复制的数据完整性,在复制中断后自动识别Binlog的同步状态,找到正确的同步起点,它支持串行方式和并行方式。Arkgate还支持配置复制从节点,如果复制的主节点挂了,会自动切换到源数据库的从节点继续同步数据。如果源数据库集群中打开了GTID,可以保证目标数据库的数据完整性。
三重高可用
Arkgate在建立一个复制通道时,可以配置一个Master和多个Slave,这个Master和Slave可以不与MySQL集群中的Master和Slave对应,他只是相对于当前的Arkgate复制通道而言的。Master节点可以指定一个具体的位置,也可以不指定,不指定的时候,默认从当前最新show master status位置开始复制。而Slave节点则不需要指定。其三重高可用是指:
第一重高可用:复制启动之后,假如Master节点挂了,如果Slave还是可用的话,Arkgate会选择一个节点自动切换过去,并且保证数据的完整性。让后端的分析业务无感知。
第二重高可用:Arkgate本身无状态,所有复制相关的配置都存储在了JSON所在的MySQL数据库中,只需要在第一时间内启动Arkgate并开始复制即可。
第三重高可用:如果需要的话,后端数据中心可以采用现有MySQL高可用架构实现,实现数据中心的高可用。
数据过滤
Arkgate同步数据时,可以指定白名单和黑名单,显示指定要复制哪些库表,或者指定不复制哪些库表,可以通过like 字符串指定模糊字符串。如果指定了白名单,则黑名单被忽略。
参数配置
Arkgate有丰富的配置参数,支持多个通道相互独立的配置,做到独立管理,互不影响。同时参数存储在数据中心中,保证一次配置,永久有效。
跨云部署
Arkgate支持在私有云及各家公有云上混合部署,满足跨云备份、跨云灾备的需求。
异地多活
当配置目标数据库为MySQL时,数据的传输实际上就变为了MySQL到MySQL的数据复制了,这样就可以脱离自有的MySQL复制功能,而使用Arkgate来做数据复制。此方案的优点是Arkgate的传输过程更可控,数据所见即所得,不会出现主从复制中断重做数据的问题,让异地数据同步更可靠,在Adapter中也可以实现异地双活中数据分类和校验的逻辑来满足异地多活的需求。
Arkgate产品展望
异构数据同步系统Arkgate作为一款高度兼容数据库使用习惯的数据整合利器,已经对外提供试用。感兴趣的小伙伴可以访问 http://www.cloud-ark.com/#/Arkgate 获取试用版。
我们希望异构数据同步系统Arkgate能够解决业务上数据孤岛的问题,随心所欲进行数据整合,让一切变得简单!
感兴趣的小伙伴也可联系:xzwen96(微信),欢迎技术交流!