精卫&DRC原理

ATAATA总结语雀文档

Binlog

mysql binlog日志是记录数据库变更记录的二进制日志,主要用于主从同步、增量备份。
关于binlog,主要理解row、statement、mixed三种模式的区别:

Statement模式

在Statement模式下,binlog记录的是对数据库执行的SQL语句

# 开启binlog
SET SQL_LOG_BIN=1;

# 创建表
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(50)
);

# 插入数据
INSERT INTO users (id, name) VALUES (1, 'Alice');

# 更新数据
UPDATE users SET name = 'Bob' WHERE id = 1;

在binlog中记录的内容类似于以下SQL语句:

BEGIN;
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(50)
);
COMMIT;

BEGIN;
INSERT INTO users (id, name) VALUES (1, 'Alice');
COMMIT;

BEGIN;
UPDATE users SET name = 'Bob' WHERE id = 1;
COMMIT;

减少日志量,对于一些函数,可能导致数据不一致

Row模式

在Row模式下,binlog记录的是每一行数据的变更情况,即从什么变成什么

# 开启binlog
SET SQL_LOG_BIN=1;

# 创建表
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(50)
);

# 插入数据
INSERT INTO users (id, name) VALUES (1, 'Alice');

# 更新数据
UPDATE users SET name = 'Bob' WHERE id = 1;

# at 12345
#191231 10:00:00 server id 1  end_log_pos 1234  Xid = 123456789
# Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1577797200;
BEGIN
/*!*/;
# at 12345
#191231 10:00:00 server id 1  end_log_pos 1234  Xid = 123456789
# Query thread_id=1 exec_time=0 error_code=0
# use `test`;
# SET TIMESTAMP=1577797200;
# CREATE TABLE `users` (
#   `id` int(11) NOT NULL,
#   `name` varchar(50) DEFAULT NULL,
#   PRIMARY KEY (`id`)
# ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

# at 12345
#191231 10:00:00 server id 1  end_log_pos 1234  Xid = 123456789
# Query thread_id=1 exec_time=0 error_code=0
# use `test`;
# SET TIMESTAMP=1577797200;
# INSERT INTO `users` (`id`, `name`) VALUES (1, 'Alice')

# at 12345
#191231 10:00:00 server id 1  end_log_pos 1234  Xid = 123456789
# Query thread_id=1 exec_time=0 error_code=0
# use `test`;
# SET TIMESTAMP=1577797200;
# UPDATE `users` SET `name`='Bob' WHERE `id`=1

记录详细,日志文件冗长,适合对一致性要求较严格,不在乎存储空间的情况

Mixed模式

Mixed模式是Statement模式和Row模式的混合使用,MySQL会根据具体的情况来决定使用哪种模式。示例与Statement模式和Row模式相同

可以通过修改MySQL配置文件(my.cnf)中的binlog_format参数来指定binlog的模式。例如,设置为ROW表示使用Row模式,设置为STATEMENT表示使用Statement模式。

需要根据具体的需求和场景选择合适的binlog模式,不同的模式在数据恢复、数据同步等方面有不同的优劣势。

综合性能较好,使用statement还是有可能有不一致的情况

主从复制

因为数据的写所消耗时间相比读要长很多,同数据库同时操作会影响读的效率,为了保证读写效率,db层以“主写从读”的方式作均衡

a .首先由slave启动“start slave”命令根据之前“change master”命令指定的数据创建一个IO线程与指定的master建立长连接,并告知其开始复制的binlog文件和复制起始位置,每隔既定的时间发送复制请求;

b. master数据库发现有slave的io线程链接上时,会为其单独创建一个log dump线程,用于相应slave的io请求从上一次复制结束位置(没有就用io指定起始位置)开始复制当前最新数据给slave的io线程(此时上锁),io线程将接收到的数据写入salve中中继日志relay log文件中;

c. slave中的sql线程检测到中继日志文件发生更新后,会立即对其新增内容按照内容的binlog level进行解析,然后在数据库内执行,完成主从复制。

DRC Strore

DRC(Data Replication Center) 数据复制中心,是阿里巴巴数据库技术团队自主研发的实时数据流基础设施。DRC提供了实时数据库数据记录变更的订阅服务,以及同构和异构数据库之间实时同步的服务。

由于有很多系统都需要获得实时的增量数据,但是存在以下两个无法回避的问题:

  1. DB类型有很多种,MySQL、HBase、Oracle、OceanBase 等等,如果一个系统需要数据,就可能需要与各种不同的DB进行交互, 非常麻烦。
  2. 如果所有的系统都是直接连上DB,会对DB造成非常压力。导致DB服务性能下降。

DRC主要解决的就是这两个问题,它具备多种数据库的日志解析能力,包括AliSQL,RDS,Oracle,OB,HBase等,DRC的下游只需要通过DRC client订阅到各种数据库的实时数据。

主要的作用:
1. 负责拉取数据库的增量binlog,统一提供增量数据
2. 连接多种数据源类型(如:mysql、oracle、hbase、oceanBase等),提供统一的增量数据格式
3. 减少大量应用直连db拉取binlog,减轻db压力

精卫原理

在精卫视角里,数据库、Tair、OpenSearch、MetaQ、ODPS、自定义等都只是不同功能的数据系统。所以抽象起来,精卫解决的是两个数据系统之间的数据复制(Replication)问题。

精卫是一个采用Single Leader模型的异步数据复制系统。这种方面临的问题主要有一致性如何保障、Leader不可用、复制延迟(Replication Lag)以及由此引发的多种不一致问题(如 read-after-write consistency, monotonic reads, consistent prefix reads 等)。

精卫的数据源(即Single Leader 复制模型中的Leader)只有数据库一种类型。目标端(即Single Leader复制模型中的Follower)包括数据库、OpenSearch、Tair、MetaQ、自定义等。数据复制包括现有数据(全量)和新增数据(增量)复制两部分。(全量复制可以形式化的证明其本质跟增量复制相同,所以这里只讲增量复制)

精卫使用的是binlog的Row格式,该格式按照时间顺序精确的记录了数据库中每张表结构每行数据的变更。表结构的变更称为DDL,数据的变更称为DML。精卫只同步DML记录,DML变更包括三种事件类型,即INSERT, UPDATE, DELETE。

在精卫视角里,可以简单把Binlog看成一个按照时间顺序由DML三种事件组成的消息队列,精卫数据同步的过程实际是消费这个队列的过程。


 

直连DRC

DRC(Data Replicate Center)。精卫client会直接从drc store中获取数据,链路较短,性能较好。数据链路是binlog-->drc store-->精卫服务。特点如下:

  • 这样数据链路最短,中间不经过metaq,不需要依赖拉drc store写metaq的上游服务,在单元化环境里面成本最低。
  • 连接多种数据源类型(如:mysql、oracle、hbase、oceanBase等),提供统一的增量数据格式。
  • 单元一键建站要求在很短的时间内做到一键建立新的单元环境,对精卫这里来说就是,需要把中心环境有单元化标签的服务的元信息一键复制到新单元里。对于直连drc store链路类型的服务,就可以做到一键复制到单元后即可启动运行,不存在服务的上下游依赖。

直连db binlog和直连drc store的区别就是精卫server拉取binlog的来源不同。精卫server根据用户配置的表映射,拉取binlog,通过过滤和记录装换,作用于目标。

精卫通道

也就是风云之前用的RC任务,目前精卫侧已下线

精卫通道主要引入了metaq,drc store将binlog写入metaq,client根据配置的topic订阅增量数据。数据暂存到metaq,将订阅压力由drc store转移至metaq,metaq具有强大的订阅分发功能,对于有很多订阅者的情况,使用精卫通道能很大程度减缓drc store压力,提高稳定性

引入了metaq后,必然有一个疑问,对于同一条记录的多次变更,如何保证有序性?
metaq有局部有序性,可以保证同一分区的有序性。drc store将数据写入metaq topic后,会根据散列字段来散列到分区,这样就可以保证同样散列字段值的一行记录的多次变更,被写入到metaq同一个分区,从而保证有序性。默认散列字段为主键。

精卫管道

精卫的基本组件为Extractor、Pipeline、Applier,每个组件都有多种选择,可以根据需要选择或者定制,提供很大的灵活性。

  1. Extractor(提取者):根据源端的类型不同,采用不同的抽取器来抽取数据。包括binlog直连提取器、drc提取器、mq消息提取器。
  2. PipeLine(管道):包括queue队列、filter过滤器(过滤出所需要的数据)、converter转换器(将binlog信息转化为精卫消息格式)。
  3. Applier(应用者):将精卫消息分发给目标应用,比如tair、db等。

设计特点

因为精卫使用的是异步复制方式,所以精卫提供的是数据最终一致性保障。

这个过程中会有很多潜在问题需要考虑,业务需要关注以下几个问题:

消费位点

消费位点是指精卫当前已经成功消费的Binlog队列的位置,位点是一个 'yyyy-MM-dd HH:mm:ss' 格式的时间戳

位点即已消费binlog的位置,drc store默认只会保存最近一天的binlog(可以找精卫的同学延迟保存时间),超过一天的binlog会自动清除。在任务的更多选项可以看到位点的设置。

Binlog队列长度

受存储成本限制,日常Binlog队列保存最近2小时的变更数据,线上为24小时。位点超过范围会报异常

失败重试

精卫任务在同步过程中发生任何异常,都会触发精卫的自动恢复机制。

任务维度——若任务在消息投递过程中发生异常,那么会无间隔连续重试3次,若仍然投递异常,那么整个任务退出;若任务在启动过程中发生异常,任务会直接退出。

集群维度——若一个任务因异常退出,或长时间无心跳,那么任务调度器会将任务调度到其他容器继续执行。

兜底方案——精卫会周期性巡检所有同步任务的位点延迟情况,当延迟超过业务设定的最大限度时,会发报警人工介入。

幂等消费

由于上面所说的精卫任务的失败重试可能触发重复消费,比如下图中步骤②成功但步骤③因磁盘满抛异常,此时精卫任务会停止从而触发自动恢复机制,那么这里就有可能重复投递消息。因此精卫要求目标数据系统有幂等能力,对于精卫负责写入的数据系统,精卫会保证写入的幂等,对于自主消费类任务,会要求业务代码消费是幂等的。

【幂等:f(f(x))=f(x)】

应用场景

Elasticsearch同步

通过精卫将数据同步到Elasticsearch,更新索引数据 。

数据同步

该种模式可以创建出基于数据库表的迁移和同步的服务,提供一站式的解决方案,支持异构目标和异构源,支持字段级别的映射,同步过程可以对数据做再次的过滤和加工 。

缓存同步

该种模式适用于接收数据库增量变更,由精卫去做Tair的缓存失效或更新缓存的逻辑 。

自主消费

该种模式适用于接收数据库增量变更,由使用者自己来实现消费逻辑 。

常见问题

哪些场景不适合用精卫?

对延迟非常敏感的场景不支持。精卫任务通常延迟会在1s以内,极端情况下会出现分钟级延迟,如果业务上绝对无法接受偶尔出现的较大延迟,那么这种情况不适合用精卫。极端情况有哪些?精卫任务所在容器出现问题(如物理机故障、容器假死、负载高)、大促、源库批量变更(常见有的批量导入、批量删除)等。

源表无pk和uk的场景不支持。精卫使用的binlog的row模式,在写入时基于pk或uk标记变更的唯一性,相关同步性能优化、消费幂等等逻辑都基于消息有pk或uk这一假设。

跨单元数据同步不支持。精卫数据同步仅支持单元内

那么如果增量服务挂起、暂停超过一天,位点丢失了怎么办?

  1. 位点丢失会报异常,具体描述为drc store连接不上或者拉取drc store的位点太老,首先要清除点位,回到对应任务的服务页面->更多->清除位点,确认之后再停用、启用一下任务即可。
  2. 对于由于点位变化导致的增量数据缺失,可以使用(限定时间时间范围)全量同步来完成。

全量同步增量同步如何衔接

数据库迁移时,原表还在使用,全量同步的过程中必然有增量数据产生,增量同步怎样衔接全量同步呢。首先要保证全量同步能在1天内完成,如果不能,需要通知精卫同学延长drc store时间,以免位点失效。当全量同步完成后,增量同步需要回溯位点到全量开始之前,然后开启增量同步即可。

  1. 如果全量和增量是一起创建的,那么全量同步完成后位点会自动回溯到全量开始时。这种情况不需要手工回溯位点,直接开始增量即可。
  2. 如果是单独设置的增量位点,需要手工回溯位点
  3. 重复同步会怎样,见下面问题 重复消费问题

如何进行消息回溯?

直连链路的任务,可以直接在精卫控制台上进行消息回溯。一般可以在任务详情页面,或者服务详情页面,找到:更多 > 消息回溯。 通道链路的任务,因为是回溯的metaq消息,所以需要到metaq控制台进行回溯操作。注意,metaq一些环境,可能取消了回溯操作的入口,原因是,回溯topic,会对相同metaq broker集群上的其他topic造成影响。这时,可以联系metaq同学,找他们帮忙操作。

重复消费问题

多次全量、增量回溯都会导致重复消费问题,此问题由数据库和业务方保证。如果表结构映射时有映射原表id或者唯一字段,则数据库会保证不会重复插入;否则,需要业务方自己做幂等。

 

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值