做者:汽车之家技术学院-技术架构组git
SQL Server + .Net 是不少早期互联网企业的标配技术栈,虽然 TiDB 是兼容 MySQL 协议和生态的数据库,可是 TiDB 适用的业务场景是通用的。在开源新技术大行其道的今天,如何从 SQL Server 无缝迁移至 TiDB,汽车之家作了一个创新的示范。github
本文将从业务背景、迁移方案、同步、业务改造、上线效果、周边建设等多个角度,详细介绍了如何从 SQL Server 数据库迁移至 TiDB 数据库。相信不管你是架构师、业务开发、仍是 DBA,都会有不一样层面的收获。sql
汽车之家社区于 2005 年上线,做为汽车之家最老的业务之一,十四年来沉淀了亿级帖子、十亿级回复数据,目前天天有千万级 DAU、亿级的访问量,接口日均调用量 10 亿+ 次 。期间经历过架构升级重构、技术栈升级等,但其数据始终存放在 SQL Server 中。随着数据的不断递增,咱们在使用 SQL Server 数据库方面遇到了不少瓶颈,以致于咱们不得不寻找一个新的数据库替换方案。数据库
随着业务的不断扩大,汽车之家社区的访问量和发表量不断上涨,遇到的数据库问题也愈来愈多,下面列举两个必须很快解决掉的问题:安全
在 2018 年末的时候,公司专门成立了虚拟架构组来调研新的数据库来解决汽车之家社区遇到的问题。通过各类分析和测试,今年年初肯定方向为分布式数据库,一共调研了三款当前比较火的分布式数据库:TiDB(PingCAP),Ignite(ASF-TLP) 和 CockroachDB。通过无数次测试咱们最终选择了 TiDB,主要有如下几个缘由:服务器
<center>TiDB 的研发同窗到之家进行技术交流</center>架构
<center>咱们去 TiDB 进行系统的课程培训</center>并发
下面引用 TiDB 官方的一段描述:运维
TiDB 是一款定位于在线事务处理、在线分析处理(HTAP: Hybrid Transactional/Analytical Processing)的融合型数据库产品,实现了一键水平伸缩,强一致性的多副本数据安全,分布式事务,实时 OLAP 等重要特性。同时兼容 MySQL 协议和生态,迁移便捷,运维成本极低。
从中咱们不难发现,TiDB 切实解决了咱们在应用 SQL Server 时候的痛点:分布式
基于以上理论的支持,咱们进行了大量的功能测试、性能测试、异常测试、业务接入测试等。
OLAP 测试:50G TPC-H 测试,TiDB 相较 MySQL 有很大的速度优点:
TPC Benchmark™H(TPC-H) 是决策支持基准。 它由一套面向业务的临时查询和并发数据修改组成。 选择查询和填充数据库的数据具备普遍的行业范围相关性。 该基准测试说明了决策支持系统,该系统可检查大量数据,高度复杂地执行查询并为关键业务问题提供答案。
在真正的数据迁移以前,咱们还有一些实际问题须要解决:
下图是咱们整个迁移过程的架构图,包含 SQL Server 到 TiDB 的全量同步、增量同步,以及 TiDB 到 SQL Server 的反向同步过程。
如今,须要肯定的是整个项目的迁移流程,有了大的方向,在实施中目标会更明确一些。
以汽车之家社区的业务形态以及数据量级来看,动辄十多个小时的离线迁移是彻底不可能接受的,咱们只能在凌晨 1:00-3:00 这个时间窗口来完成迁移,且时间越短越好。
因此咱们选择在线迁移的方案,在线迁移稍微复杂一些,流程上有准备全量数据,而后实时同步增量数据,在数据同步跟上(延迟秒级别)以后,采用滚动升级的方式将应用的读流量切换到 TiDB 上。
观察应用正常运行,进行短暂停机和关停 SQL Server 写权限,确保没有数据再写入 SQL Server, 就能够将写流量指向 TiDB,至此迁移完毕。
整个迁移流程中,应用的读数据场景不受影响,写入场景受影响周期为停机(关写权限)到写流量指向 TiDB。
下图是咱们梳理出来的流程图,咱们在整个迁移的过程当中必须严格按这些流程执行。
下面咱们来详细介绍全量和增量同步的实施方案。
首先咱们要感谢如下两个开源项目,站在巨人的肩膀上使咱们节约了不少时间。
愚公是阿里巴巴推出的一款 Oracle 数据迁移同步工具,而做者 alswl 在此基础上实现了 SQL Server 数据源的支持。在此愚公的使用方法咱们再也不赘述,感兴趣的同窗请自行查看。
在认真拜读了大神的项目,并进行了相关测试后,发现它并不能 100% 知足咱们的需求。
Yugong 数据流是标准 ETL 流程,分别有 Extractor、 Translator、Applier 这三个大类来实现 ETL 过程。
首先讲 Extractor,愚公原有的配置方式是将须要导出的库表写在配置文件当中,这对于 1000+ 张表来讲,太不现实了。这里咱们增了一个新特性,在不配置须要导出的表名的状况下,将数据库中全部的用户表读出来,并经过一个新增的配置项进行正则匹配,以此决定哪些表须要进行数据同步。
#查询表 SELECT name FROM sys.databases WITH (nolock) WHERE state_desc = 'ONLINE' #查询开启CDC的表 SELECT name FROM %s.sys.tables t WITH (nolock) JOIN %s.[cdc].[change_tables] ct WITH (nolock) ON t.object_id = ct.source_object_id
其次,合库合表后,原有 SQL Server 中各个表的自增主键 ID 冲突,因此新增实现 RowDataMergeTranslator,其功能是,读取内存中的 RowData 而后进行转换,将从 SQL Server 中读取的行数据,丢弃其原有的主键列,转而使用 TiDB 生成。并根据配置文件决定哪些表须要实现这一特性。
record.removeColumnByName(config.getDiscardKey());
最后的 Applier 并未作改动,处理好的数据直接写入 TiDB。
自此合库合表的事情咱们解决了。
在实现这部分需求的时候,咱们应用了 SQL Server 的 CDC,并在增量同步的基础上增长了延迟验证数据正确性的功能。更多关于 CDC 的内容,这里再也不赘诉,你只须要知道它能获取到增量数据,参考 CDC官方文档。
须要注意的是,CDC 开启的时机须要在全量同步以前,保证 CDC 记录能够覆盖全量同步过程当中产生的增量数据。
根据以上的流程图能够看到,Producer 从 SQL Server 中读取 CDC 日志,并将其转化成一条包含表信息、列信息和行数据的消息,投递到 Kafka 中。下游的消费者在拉取到消息以后,把数据转化成兼容 MySQL 的 SQL 语句在 TiDB 中执行(这里也实现了合库合表),从而实现整个数据增量同步的过程。
这里还有另外一个消费者实现数据校验功能,它会延迟五秒消费同一队列,并经过提取主键(或索引)的方式从 TiDB 中查出该条已经写入的数据,将两侧的整行数据作比较(本实践中去除主键后比较),若是有问题会进行尝试从新写入,如出现异常则向相关人员发送报警。
在实现了这些并进入到测试阶段后,咱们发现了一个问题,1000+ 回复表,对应 1000+ CDC 日志表,一个 Producer 就须要开启 1000+ 线程。以设计的 5s 间隔去轮询这些表时,服务器 CPU 直接就跑满了,产生了大量线程等待,轮询 CDC 日志的及时性没法保证。经过分析业务和 DBA 查询得知,其实汽车之家社区天天产生的回复有 95% 都集中在最新的 5% 的帖子当中。换言之,咱们只有几十张表须要如此高频的去检索 CDC 日志,其余的表咱们经过增长轮询间隔、分批部署等方式,将这个问题解决了。
细心的同窗读到这里会发现,校验功能其实逻辑上并不严谨,若是说在五秒钟内上游数据产生了变动,就有可能会产生拿着新数据去校验老数据的问题。这里有两个解决方案:
以前咱们提到了,当项目切换到 TiDB 之后,须要预防其出现不可预估的问题,可以随时切回 SQL Server 才能保障万无一失。
TiDB Binlog 使得这件事情垂手可得。咱们使用官方提供的 Pump 和 Drainer 将 Binlog 抽取到 Kafka 之中,解析数据变动的内容,根据业务 ID 计算出数据在 SQL Server 中本来属于哪一个库哪一个表,而后进行数据同步。
<center>解析 Binlog (Protobuf 协议)</center>
<center>经过业务 ID 决定数据写到哪一个库表</center>
就业务的改造这一环节,因历史积淀,需修改的地方不少,分布于各个项目之中,咱们采起经过接口查找实现、搜索代码、DBA 帮助抓取 SQL 的方式,保证涵盖了 100% 的相关业务,只有这样才能保障上线后无端障。
与此同时,咱们针对每一条改造后的 SQL 都进行了优化,使能够精确的命中最优的索引,从而实现了在十亿级数据量下,TP 业务 99% 的响应时间在 12ms,99.9% 的响应时间在 62ms。
除以上迁移流程所涉及到的功能点之外,咱们还制定了一些开发规范和一些实用工具的研发,用以保障 TiDB 在汽车之家更好的应用。
TiSlowSQL 也是汽车之家运维组参加 Hackathon 项目,具体内容敬请期待后续文章!
汽车之家社区已于 9 月底正式上线分布式数据库 TiDB,目前运行稳定。在其余业务迁移完成以后,汽车之家社区的 SQL Server 服务会逐步下线。对于本次迁移的过程咱们作了如下几点总结:
由 SQL Server 迁移至 TiDB,从传统关系型到分布式 HTAP,从商业受权到开源社区,是汽车之家社区历史上一次重大的技术方向转型。
汽车之家有不少海量数据的应用场景,这一次从 SQL Server 到分布式数据库 TiDB 的迁移,为咱们之后其余业务迁移至 TiDB 打下了良好的基础,也与 TiDB 官方创建了良好的按期沟通机制。但愿 TiDB 官方一如既往的快速迭代,咱们也会和 TiDB 官方合做开发一些比较实用的功能。
关于 TiDB 使用上的疑惑或经验,能够登录 http://www.asktug.com 和你们一块儿交流~