Gravity 的测试调研 Gravity -> TiDB
作者: 张鱼小丸子 -PingCAP 原文来源:https://tidb.net/blog/dd46ed3f
参考文档:https://github.com/moiot/gravity/blob/master/docs/2.0/03-inputs.md
整体架构
Gravity 是一款数据复制组件,提供全量、增量数据同步,以及向消息队列发布数据更新。 使用场景
大数据总线:发送 MySQL Binlog,Mongo Oplog 的数据变更到 kafka 供下游消费
单向数据同步:MySQL –> MySQL 的全量、增量同步
双向数据同步:MySQL <–> MySQL 的双向增量同步,同步过程中可以防止循环复制
分库分表到合库的同步:MySQL 分库分表 –> 合库的同步,可以指定源表和目标表的对应关系
在线数据变换:同步过程中,可支持对进行数据变换
架构简介
单进程架构
单进程的 Gravity 采用基于插件的微内核架构,由各个插件围绕系统里的 core.Msg 结构实现输入到输出的整个流程。
各个插件有各自独立的配置选项。
如上图所示,系统总共由这几个插件组成:
Input 用来适配各种数据源,比如 MySQL 的 Binlog 并生成
core.MsgFilter 用来对 Input 所生成的数据流做数据变换操作,比如过滤某些数据,重命名某些列,对列加密
Output 用来将数据写入目标,比如 Kafka, MySQL,Output 写入目标时,使用 Router 所定义的路由规则
Scheduler 用来对 Input 生成的数据流调度,并使用 Output 写入目标;Scheduler 定义了当前系统支持的一致性特性( 当前默认的 Scheduler 支持同一行数据的修改有序 )
Matcher 用来匹配 Input 生成的数据。Filter 和 Router 使用 Matcher 匹配数据
基本功能测试
MySQL 环境准备
Gravity 对源端 MySQL 的要求如下:
开启 gtid 模式的 binlog
创建 drc 账户,并赋予 replication 相关权限,以及 drc 数据库的所有权限
MySQL 源端、目标端相应的表需要创建好
MySQL 配置项如下所示
[mysqld]
server_id=4
log_bin=mysql-bin
gtid-mode=ON
binlog_format=ROW
drc 账户权限如下所示
CREATE USER drc IDENTIFIED BY 'xxx' ;
GRANT SELECT , RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT, INSERT , UPDATE , DELETE ON *.* TO 'drc' @ '%' ;
GRANT ALL PRIVILEGES ON drc.* TO 'drc' @ '%' ;
上下游表结构创建
--source
CREATE TABLE ``test.test_source_table(
\`\`id int (11),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
--target
CREATE TABLE ``test.test_target_table(
\`\`id int (11),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
GO 环境配置
参考文档:配置好 Go 语言环境
wget https: //dl .google.com /go/go1 .11.4.linux-amd64. tar .gz
tar -C /usr/local -xzf go1.11.4.linux-amd64. tar .gz
mkdir -p usr /local/go/src/github .com /moiot/ && cd usr /local/go/src/github .com /moiot/
git clone https: //github .com /moiot/gravity .git
cd gravity && make
###
MySQL to MySQL
创建配置文件 mysql2mysql.toml
mysql2mysql.toml
同步测试
##源端表及表数据
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| _gravity |
| mysql |
| performance_schema |
| sys |
| test |
| wk |
+--------------------+
7 rows in set (0.00 sec)
mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+---------------------+
| Tables_in_test |
+---------------------+
| test_source_table_1 |
| test_source_table_2 |
+---------------------+
2 rows in set (0.00 sec)
mysql> select * from test_source_table_1;
+-----+------+------+
| id | name | age |
+-----+------+------+
| 1 | NULL | NULL |
| 2 | NULL | NULL |
| 3 | NULL | NULL |
| 4 | NULL | NULL |
| 6 | NULL | NULL |
| 9 | NULL | NULL |
| 33 | NULL | NULL |
| 333 | wk | 12 |
| 334 | wk | 12 |
| 354 | wk | 12 |
+-----+------+------+
10 rows in set (0.00 sec)
mysql> select * from test_source_table_2;
+-----+------+------+
| id | name | age |
+-----+------+------+
| 3 | NULL | NULL |
| 4 | NULL | NULL |
| 5 | NULL | NULL |
| 6 | NULL | NULL |
| 66 | NULL | NULL |
| 77 | GG | 18 |
| 81 | GG | 18 |
| 89 | GG | 18 |
| 166 | bb | 11 |
| 183 | bb | 11 |
+-----+------+------+
10 rows in set (0.00 sec)
mysql>
目标端效果
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql> use test ;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-------------------+
| Tables_in_test |
+-------------------+
| test_target_table |
+-------------------+
1 row in set (0.00 sec)
mysql> select * from test_target_table;
+-----+------+------+
| id | name | age |
+-----+------+------+
| 1 | NULL | NULL |
| 2 | NULL | NULL |
| 3 | NULL | NULL |
| 4 | NULL | NULL |
| 5 | NULL | NULL |
| 6 | NULL | NULL |
| 9 | NULL | NULL |
| 33 | NULL | NULL |
| 66 | NULL | NULL |
| 77 | GG | 18 |
| 81 | GG | 18 |
| 89 | GG | 18 |
| 166 | bb | 11 |
| 183 | bb | 11 |
| 333 | wk | 12 |
| 334 | wk | 12 |
+-----+------+------+
16 rows in set (0.00 sec)
mysql>
MySQL to TiDB
上游一库多表下游一库一表测试
配置文件
mysql2tidb2.toml
测试步骤
--上游表
mysql> show tables;
+ ---------------------+
| Tables_in_test |
+ ---------------------+
| test_source_table_1 |
| test_source_table_2 |
+ ---------------------+
2 rows in set (0.00 sec)
mysql> select * from test_source_table_1;
+ ------+---------+------+
| id | name | age |
+ ------+---------+------+
| 2019 | pingcap | 3 |
+ ------+---------+------+
1 row in set (0.00 sec)
mysql> select * from test_source_table_2;
+ -----+------+------+
| id | name | age |
+ -----+------+------+
| 77 | GG | 18 |
| 81 | GG | 18 |
| 89 | GG | 18 |
| 166 | bb | 11 |
| 183 | bb | 11 |
+ -----+------+------+
5 rows in set (0.01 sec)
--下游同步效果
mysql> select * from test_target_table;
+ ------+---------+------+
| id | name | age |
+ ------+---------+------+
| 77 | GG | 18 |
| 81 | GG | 18 |
| 89 | GG | 18 |
| 166 | bb | 11 |
| 183 | bb | 11 |
| 2019 | pingcap | 3 |
+ ------+---------+------+
6 rows in set (1.91 sec)
--上游delete
mysql> delete from test_source_table_2 where name = 'GG' or age= '11' ;
Query OK, 5 rows affected (0.00 sec)
mysql> select * from test_source_table_2;
Empty set (0.00 sec)
--下游效果
mysql> select * from test_target_table;
+ ------+---------+------+
| id | name | age |
+ ------+---------+------+
| 2019 | pingcap | 3 |
+ ------+---------+------+
1 row in set (0.10 sec)
--上游 insert 在 test_source_table_2 中插入 id=2019 的记录,模拟主键冲突
mysql> insert into test_source_table_2 values (2019, 'tidb' ,2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_source_table_2;
+ ------+------+------+
| id | name | age |
+ ------+------+------+
| 2019 | tidb | 2 |
+ ------+------+------+
1 row in set (0.00 sec)
mysql> select * from test_source_table_1;
+ ------+---------+------+
| id | name | age |
+ ------+---------+------+
| 2019 | pingcap | 3 |
+ ------+---------+------+
1 row in set (0.00 sec)
--下游效果
mysql> select * from test_target_table;
+ ------+------+------+
| id | name | age |
+ ------+------+------+
| 2019 | tidb | 2 |
+ ------+------+------+
1 row in set (0.31 sec)
-- 上游 update
mysql> update test_source_table_1 set age = 999 where name = 'pingcap' ;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_source_table_1;
+ ------+---------+------+
| id | name | age |
+ ------+---------+------+
| 2019 | pingcap | 999 |
+ ------+---------+------+
1 row in set (0.00 sec)
--下游结果
mysql> select * from test_target_table;
+ ------+---------+------+
| id | name | age |
+ ------+---------+------+
| 2019 | pingcap | 999 |
+ ------+---------+------+
1 row in set (0.05 sec)
-- 此时发现上游按照数据同样被 replace 了
多库多表同步
gravity 可以同时启动多个,多个同步进程指向下游同一个库
默认 gravity 启动会使用 8080 端口,如果启动多个进程,需要改动默认端口
bin/gravity -config mysql2tidbtwo.toml -http-addr “:9090”
mysql> select * from test_source_table_1;
+ ----+------+------+
| id | name | age |
+ ----+------+------+
| 0 | RAFT | 10 |
+ ----+------+------+
1 row in set (0.00 sec)
mysql> select * from test_source_table_2;
+ ----+------+------+
| id | name | age |
+ ----+------+------+
| 1 | TIKV | 2 |
+ ----+------+------+
1 row in set (0.01 sec)
--源库效果
mysql> select * from test_target_table;
+ ------+---------+------+
| id | name | age |
+ ------+---------+------+
| 0 | RAFT | 10 |
| 1 | TIKV | 2 |
| 2019 | pingcap | 999 |
+ ------+---------+------+
3 rows in set (7.50 sec)
其它功能测试
filter 模块功能测试遇到 bug,摩拜正在修复
测试结果
上下游同步成功 ,MySQL 到 TiDB 同步配置文件只需要修改对应 IP 和 port 就可以
可以完成一库多表的合并
同步之前需要在上下游创建好对应的 schema 以及表结构
DML 遇到主键冲突时会 replace
多库合并仅限于同一数据库实例不同 schema ,跨实例合表有问题
MySQL 到 TiDB 同步配置文件只需要修改对应 IP 和 port 就可以
对比 TiDB-DM
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/945001dc4b626f51dae5d08db】。文章转载请联系作者。













评论