跳到主要内容

MySQL 到 TiDB,TiDB 在云集财务的落地实践

作者:皮雪锋,原云集研发经理,TUG Ambassdor

丁凌风,云集业务研发 Leader,TUG Ambassdor

文章首发于 2020 年 6 月

一、背景介绍

1、业务背景

  • 财务业务上线: 公司在 15-17 年业务成爆发式增长,18 年初开始做财务系统的规划,起初日均生成的财务数据量在 10-20 万+,在小活动期间会翻 2-3 倍,大型活动翻 4-5 倍;
  • 技术选型: 事务需求加上技术栈积累选用的是 MySQL,根据财务商家结算维度做分表键,分 64 张表存储。18 年 4 月份预上线,5 月份正式投入财务结算使用;
  • 痛点: 18 年 Q4 季度开始,日均数据量上升到 40-50 万+,加上分表维度是按商家的维度,存在热点数据,MySQL 已经出现单表千万级数据量的超级大表;
  • 方案探索
  • 冷热分离: 本来提出过冷热数据分离的方案,但是由于是 18 年初新建的财务系统,其他地方根本没有完整的数据,仅此一份孤本既提供给结算业务又提供给报表业务,两边对数据的需求完全不一样,需冷热分离的数据维度不同,结算对已结算的数据可以做冷数据分离,而报表要以月度维度进行冷数据分离,导致冷热分离一直没有办法动工,除非做数据异构解耦两份数据;
  • 数据异构: 但是数据异构又会带来非常大的研发成本,每存在一种业务场景需要异构一份财务数据,维护多份数据、保证多份数据的数据一致性,都会带来非常多新的工作量,这都是高昂的维护、开发成本;
  • 诉求: 所以急需一个可以应对多变业务、处理大数据量、带有事务能力的解决方案。

2、发展到 19 年初时的 MySQL 架构

img

3、统计需求业务场景

img

在这样的背景之下,我们从社区上了解到分布式数据库的存在,进行了分布式数据库的尝试与调研。

4、数据库技术选型

基于这个业务背景下,考虑到当时公司一直用着阿里云的服务,我们首先选择的是阿里云的 HybridDB for MySQL (下文简称 HDB ),是同时支持海量数据在线事务( OLTP )和在线分析( OLAP )的 HTAP 关系型数据库。架构发展如下图所示:

img

经过两个月的线上使用 HDB ,解决了很多现有的业务场景,同时也遇到了很多新的问题:

  • HDB 的同步压力过大,不是单独 HDB 配套的同步服务,用的阿里公用的同步服务,导致数据同步压力过大延迟过高;
  • HDB 各种未知原因会漏同步 SQL ,寻求阿里解决都很积极,但最终无法定位到问题;
  • 二级分区键 update 会导致脏数据存在(阿里已经发补丁解决但是依旧有性能瓶颈)。

总之由于 HDB 的闭源性,导致很多问题无法跟踪定位,只能依赖阿里响应,虽然阿里的响应非常迅速,但是确有很多不便,同时公司在考虑切换到腾讯云。基于以上种种原因,我们的业务架构师建议我们尝试调研开源的分布式数据库项目 TiDB 。

二、测试对比(时间为 19 年 5 月)

1、报告探究目标

  1. 探测 TiDB 当前配置下的性能瓶颈;
  2. 对比 HDB、TiDB的 OLTP、OLAP 支持能力;
  3. 初步探究 TiDB 的适用场景;

2、服务器配置

img

通过阅读 TiDB 的开源文档。可以了解到,在 TiDB 架构中,TiDB 和 TiKV 均会影响 TiDB 的 OLAP 性能。 TiDB 采用的是 MPP 模式的架构(虽然在 MPP 模式下做了些优化,不过依然属于 MPP 模式)。

通过 HDB 计算资源的参数,可以了解到, HDB 是 MPP 和 DAG 混合架构的方式实现的 SQL 计算。

这一环节的对比,可以预测到 HDB 对于复杂 OLAP 能力会略优于 TiDB 。

3、分析

测试数据就不在文章中展示了,这里直接提出基于测试数据的分析结论。

工具压测数据分析

TiDB 自带工具场景压测,均为单表多线程的场景,分只读、只写、读写比等 5 种场景。

  1. 可以看到单表只读场景下,TiDB 当前配置的负载能力 29000 QPS ,2000 TPS ,为峰值性能。再增加线程并发 QPS、TPS 的提升并不大,反而降低了整体响应时间。
  2. 在读写比的场景下,TIDB 当前的峰值性能为 2w3 QPS、1300 tps 。
  3. 写场景的压测情况,和 DBA 了解后较为单一,表结构较为简单,并发冲突不大,参考意义有限。

各种业务查询场景分析

select one 场景:

  • HDB:由于一直是采用阿里推荐的全索引的方式建立的,未测试非索引条件。通过数据可以看到亿级的数据量对 HDB 的性能影响并不大;
  • TiDB:测试了主键索引、非主键索引、非索引三种情况,在几个数据量级的情况下,有索引的查询条件对亿级的数据量也没有压力。但是对非索引条件从少数据量级的查询场景就能看到很大的的性能差距。

select range 场景:

  • HDB:未测试非索引条件,可以看到我专门挑了相同条件不同响应数据量的范围查询来测,因为猜测 HDB 的查询和响应能力很快的,但是他是一次性返回的,所以整个响应时间和数据量的大小有很大的关系;
  • TiDB:
  • 在百万级别的数据场景下,即使是非索引列的条件响应时间也在秒级,虽然和索引列差距巨大,但也展示了 TiDB 分布式数据库的优势,同级别的数据 MySQL 下的非索引列查询时间达到了 20 秒;
  • 可以看到同数据量的表,稍大数据量返回的场景,性能上比 HDB 快了非常多, OLTP 场景的查询性能上 TiDB 更为优秀。

select limit 场景

  • HDB:对分页的支持非常不友好,即使数据量少,也会严重地影响 HDB 的响应时间,甚至不如原先的不带分页的 SQL;
  • TiDB: TiDB 对分页查询的支持非常快,带索引条件的查询,对于千万级数据表的响应时间依旧维持在毫秒级。

Count 场景

  • HDB:count 的表现在 HDB 基本没见到瓶颈,亿级的数据量也是毫秒级的响应时间;
  • TiDB:count 的表现在 TiDB 和条件是否为索引列关系很大,同时表数量过大的话,全表的 count 也在千万级的数据量上,性能有非常大的降低。

TiDB order by 场景

  • 从上面数据可以看到对于 order by 条件的查询,对比同条件下不带 orde by 的查询有约 8% 左右的性能损失。

OLAP 场景

  • 跑的是当前线上的月结 SQL,报表 SQL,有一定的复杂度但是复杂度不算太高,没有嵌套子查询和 join,可以看到这个场景下 TiDB 和 HDB 性能方面不相伯仲。

4、HDB 对比 TiDB 总结

HDB VS TiDB

  • HDB 底层为行列混合,count 和 sum 等计算更为高效,亿级数据量也是毫秒级的响应时间,而 TiDB 行式存储对于过 5000W 级别的数据量开始出现明显的性能瓶颈;
  • TiDB 对于简单的 OLTP 查询 (select one、select range、limit) 支持能力更强,而 HDB 由于列式存储最终返回数据需要做一层数据聚合的动作,在 OLTP 的业务查询场景的表现下弱于 TiDB。

MPP & DAG(HDB) vs MPP(TiDB)

  • HDB 采用的 MPP & DAG 的混合架构,在更加复杂的 OLAP 查询中,表现优于 TiDB。不过 TiDB 也已经满足了 80% 的 OLAP 查询场景,同时提供了 TiSpark 组件针对剩下非常复杂的 OLAP 查询场景

5、测试结果 TiDB 适用场景

在线 OLTP +少量的 OLAP

TiDB 分 Region(区域)存储数据,连续的一个 Key 范围存储在一个 Region 内, Region又存储在节点上,又有组件保证每个节点上的区域数量差不多。该设计目的:

  • 数据存储均匀、方便水平扩容,扩节点时有组件会自动调度节点过去;
  • 负载均衡,不至于像 key hash 那样,会有数据偏移;
  • 热点数据负载均衡,通过 PD 会自动调度分配热点 Leader 数量。

三、上线过程

初步测试结果中发现,HDB 和 TiDB 都是满足我们业务需求的,但是鉴于公司计划在 19 年 8 月进行阿里云到腾讯云的迁移计划,所以 HDB 迁移到 TiDB 是势在必行的操作了。

1、MySQL 数据同步/迁移

同步方案

  1. 在原来使用 HDB 的时候,考虑风险因素,为了保证线上稳定不受影响,我们只利用 HDB 做了 OLTP 查询+ OLAP 业务,没有在上面操作 insert、update,保持着增量同步任务把 HDB 作为 MySQL 查询从库的方式来使用。并且阿里云有配套完整的数据迁移工具,直接界面化操作即可完成整个数据的全量同步+实时同步,接入业务的成本非常低。
  2. 这次切换 TiDB,也打算使用同样的方式低风险的接入,将 MySQL 上的源数据同步到 TiDB 上以查询从库的方式先应用到业务。

问题

但是由于 TiDB 并非阿里云这种商业支持的,数据同步需要自己想办法,在 TiBD 官网可以发现几种数据同步的方案,但是经过本人和 DBA 的测试,几个方案各有各的缺点,暂时没有办法支持我们这种全量+实时多表同步到单表的操作。

解决

经过调研探索之后,最终的解决方案是自研一份基于数据的同步工具 fmsdump,再加上开源项目 Otter 实现 MySQL-TiDB 的全量同步+增量同步。 Otter 的同步可以实现多表合并到同表并且自定义合并的规则,负载能力可以通过加机器进行扩容,加上可视化的界面操作,使用成本较低。

img

毕竟是通过数据写入的方式导入,没有把导入的并发线程调的很高, 5 个并发 10 个小时导入总量 4 亿的数据。上线接入的表,在两三天内接入完成。

四、上线结果

1、监控情况

img

img

img

2、上线效果

由于我们应用在财务场景,没有太多并发,主要观测日常业务和报表类 SQL 时系统的负载,发现除了在执行报表类 SQL 时会把系统负载打的比较高,日常指标还是比较稳定。解决了我们 MySQL 千万级单表查询瓶颈的问题,低成本地接入了更多的月报、年报等 OLAP 的业务。

3、数据规模

截止到文章撰写财务业务 TiDB 实例单表最大 3.8 亿数据、3 台TiKV,单机数据量 1.75T。

4、业务情况

截止到文章撰写已接入的有:

  1. 只读的财务结算 OLTP;
  2. 只读财务库存 OLTP;
  3. 财务月报、年报 OLAP;
  4. 读写的新类型结算业务(单表 5 千万数据量,预期增长月均 1000 万);
  5. 对账平台(新的 TiDB 实例集群,和业务 TiDB 隔离的,专门承接公司所有业务的数据对账,数据量已远超过财务业务 TiDB 实例);

五、后续计划

1、目前痛点

  1. 由于 MySQL 和 TiDB 的 DDL 并不是完全兼容,TiDB 没有办法像 MySQL 一样在一句 SQL 里进行多个字段的变更,所以导致 otter 的 DDL 同步会报错。我们尝试过用 DM 进行单表的同步,可以解决 DDL 的问题,但是在 12 月份爆发过一个由于 DM 同步表过多将 TiDB 连接池占满导致业务系统连接不上产生同步数据缺漏的问题;
  2. TiDB 目前的版本非行列混合存储,虽然相较于 MySQL 上跑 SQL 性能提升巨大,和之前我们使用 HDB 相比,在 OLAP 方面还是有比较多的瓶颈;
  3. 我们的支付团队之前使用的是 HDB 事务版,现在切换到腾讯云也调研使用 TiDB,但是在压测阶段一直压不到我们需求的并发性能。

2、解决探索

  1. DDL 的问题,由于我们 TiDB 作为主从使用主要是应用在 AP 场景,所以很多字段也不是全部都需要,我们目前放弃了 DM 同步,通过 otter 选择固定字段同步+跳过 DDL 同步,新增的字段暂时不接入了,在后期 AP 需求有需要的时候再将新字段维护进去;
  2. TiDB 的 AP 场景,在测试环境搭建了 TiSpark 进行尝试,但是发现对我们的提升并不大,主要还是底层存储模式的限制,行式存储导致每次需要提取所有的数据,在网络传输数据量这部分占了整个 SQL 大部分的时间,即使用 TiSpark 也没有办法解决,目前在等待 TiDB 3 月中旬的 GA 版本上 TiFlash 列式存储,看会不会有比较大的提高;
  3. 请教了 TiDB 的相关同学,TiDB 的同学积极的协助了我们排查,最终定位是存在的热点问题,但是尝试了 TiDB 同学提出的各种方法之后还是没有解决热点问题,支付的高并发场景一直压不上去,目前暂时还是用高配的 MySQL 分表+冷热分离来解决。

六、总结

经过长达一年的发展,从 MySQL 分表到 HDB 到 TiDB,让我们对分布式数据库有了更深刻的认识。在不断深入使用的过程中,也从 TiDB 的设计思路得到很多启发。同时也遇到了很多问题,期望 TiDB 团队能有更好的解决方案。

  • DM 同步工具:使用难度较高,DM 同步规则不够灵活多表合并规则不够灵活,实时同步任务多的情况 DM 会占满 TiDB 连接池;
  • DDL 语句:支持和 MySQL 一样的一个语句内多个变更;
  • 慢 SQL 日志:需要 DBA 命令行去查询底层文件导出;
  • 表信息:没有表数据量大小的统计信息,只能查看 TiKV 磁盘大小观测总体数据量。

TiDB 活跃的社区、丰富的文档以及积极配合解决问题的 TiDB 同学,非常看好 TiDB 未来的趋势。同时根据我们自身的规划,2020 年部门会有两个重点项目也启用 TiDB 做为底层的存储,深化更多的使用场景。