前言
Relaylog类似binarylog,是指一组包含数据库变更事件的文件,加上相关的index和mata文件,具体细节参考官方文档。在DM中针对某个上游开启relaylog后,相比不开启,有如下优势:
不开启relaylog时,每个subtask都会连接上游数据库拉取binlog数据,会对上游数据库造成较大压力,而开启后,只需创建一个连接拉取binlog数据到本地,各个subtask可读取本地的relaylog数据。
上游数据库对binlog一般会有一个失效时间,或者会主动purgebinlog,以清理空间。在不开启relaylog时,如果DM同步进度较为落后,一旦binlog被清理,会导致同步失败,只能重新进行全量迁移;开启relaylog后,binlog数据会被实时拉取并写入到本地,与当前同步进度无关,可有效避免前面的问题。
但在DM版本=v2.0.7中,开启relaylog后有如下问题:
数据同步延迟相比不开启relaylog有明显上升,下面的表格是一个单task的benchmark的测试结果,可看出平均latency有明显的增长。下表中以“.”开头的是延迟的百分位数据。
开启relay后CPU消耗增加。(由于latency的增长,在一些简单场景下(比如只有1个task)相比不开启relaylog,资源使用率反而是下降的。但当task增多时,开启relay的CPU消耗就增加了)。
由于以上问题,在新的版本中,我们对DM的relaylog做了一些性能优化。
当前relay实现
在开始介绍具体的优化之前,首先简单介绍下当前DM中relay的实现,详细实现,详情可参阅DM源码阅读系列文章(六)relaylog的实现,本文在此不做过多描述。
当前relay模块可以分为两个部分,relaywriter和relayreader部分,其结构如下所示:
Relaywriter
relaywriter依次做了下述3个事情:
使用binlogreader从上游MySQL/MariaDB读取binlogevent;
将读取到的binlogevent使用binlogtransformer进行转换;将转换后的binlogevent使用binlogwriter以relaylogfile的形式存储在本地的relaydirectory中。Relayreader
开启relay后,Syncer会通过relayreader获取binlogevent,relayreader主要是做了如下工作:
读取realydirectory中的binlog文件,发送给syncer;
当读取到文件尾时,定时(目前是每隔ms)检查当前binlog文件大小和meta文件内容是否存在变化,如果改变则继续读取(binlog文件变化)或者切换到新的文件(meta文件变化)。
从上面的介绍可以看出,relayreader跟relaywriter是相互独立的,彼此通过relaydirectory中的binlog、meta和index文件进行交互。
测试环境说明
在开始介绍优化内容前,先介绍下优化时使用的环境情况
上游为MySQL,版本为5.7.35-log;
下游为单实例的TiDB,版本为5.7.25-TiDB-v5.2.1;DM使用了1个master和1个workerLatency基准测试版本为-10-14号的master分支(