TiDB 在平安核心系统的引入及应用

2019-05-29 10:37:07 +08:00
 PingCAP

作者:何志勇 本文转载自公众号「平安科技数据库产品团队」。

2019 年 5 月 9 日,平安科技数据库产品资深工程师何志勇在第十届数据库技术大会 DTCC 上分享了《 TiDB 在平安核心系统的引入及应用》,通过对 TiDB 进行 POC 测试,详细解析如何选择适用于金融行业级别的开源分布式数据库,以及平安“财神节”活动中引入 TiDB 的全流程应用实践案例分享。本文根据演讲内容整理。

<center>何志勇 平安科技数据库产品团队 资深工程师</center>

一、TiDB 引入的 POC 测试

作为一名运维人员,引入一个新的数据库产品前必须要明确几点:

所以在我们引入前从以下六个方面分别对 TiDB 进行测试验证,其中功能与架构、配置与管理、备份与恢复都是针对我们运维管理,SQL 特性、基准测试、应用场景测试则是应对业务需求和业务场景的。

1. 功能与架构

TiDB 事务隔级别为 SI,支持 Spark 生态,支持动态扩容,跨数据中心部署。

这是 TiDB 官网最新的架构图:

从左至右看,可以通过 MySQL 或 MySQL 客户端接入 TiDB,TiDB 有 TiDB、PD、TiKV 三个组件,组件之间功能相互独立,需独立部署,分别负责计算、调度、存储功能;同时又相互协作,共同完成用户请求处理。在 TiKV 层各节点是使用 Raft 协议保证节点间数据的一致性,同时它还提供 Spark 接口供大数据分析。

从上往下看,可通过 Data Miaration 工具从 MySQL 迁移到 TiDB,同时提供备份恢复功能、内部性能监控监测及诊断、支持容器化部署。

TiDB 从架构及生态上基本上具备了传统数据库应有的功能。

2. SQL 特性

兼容 mysql 语法,2.0 版本不支持窗口函数、分区表、视图、trigger 等。

3. 配置与管理

支持在线 DDL,2.0 只支持串行的 DDL、不支持并发,在优化器上支持 RBO 与 CBO,能对单会话进行管理,可以支持复杂的 SQL。

4. 备份与恢复

备份恢复工具均为开源,支持多线程备份恢复,当前版本不支持物理备份,loader 恢复时间偏长。

5. 基准测试

TiDB 在单条 SQL 的性能较好,高并发场景下性能较稳定,但 DML 事务大小有限制。

6. 应用场景测试

支持标量子查询,能支持非常复杂的查询,查询引擎可朔性强。

这个应用场景是我们的产险的实际分析场景,表数据量不大但是 SQL 较为复杂,是典型的星型查询。在 Oracle 用了 134 秒,但是 TiDB 用了 50 分钟,我们觉得很诧异,与 TiDB 的同事咨询后,他们通过现场支持我们优化底层代码后 34 秒可以跑出来。

二、“财神节”活动中 TiDB 的应用实战

“财神节”是中国平安综合性年度线上金融狂欢节。2019 年平安集团“财神节”活动于 1 月 8 日正式启动,涉及寿险、产险、银行、养老险、健康险、普惠、证券、基金、健康互联、陆金所、壹钱包、互娱、不动产等多个领域,活动参与的 BU 数量与推广的力度是历年之最。单日成交额超过 1000 亿,在单日交易额破千亿背后是几百个后台数据库实例的运维保障。

我们看下活动业务场景的特点:

平安在用的开源数据库有很多,那在这么多数据库中,我们选择什么数据库呢?

综合对比考量最终我们选择 TiDB,在选择的同时也面临着挑战:

TiDB 还处于生产落地阶段,一类系统尚未使用过 TiDB,没有大规模应用运维经验

基于以上挑战,我们在 9 台 PC 服务器上做了验证测试,测试工具是 jmeter,TiKV 节点数我们是逐步增加的,具体的测试过程如下:

总结一下,就是:

上线时我们做了以下两方面改善:

1. 优化表的定义与索引

表定义:不使用自增长列(自增长的 rowid )作为主键,避免大量 INSERT 时把数据集中写入单个 Region,造成写入热点。

索引:使用有实际含义的列作为主键,同时减少表不必要的索引,以加快写入的速度。

2. 对表的 region 进行强制分裂

查找表对应的 region:curl http://$tidb_ip:$status_port /tables/$schema/$table_name/regions

使用 pd-ctl 工具 split 对应表的 region:operator add split-region $region_id

打散表的隐式 id,打散表的数据分布:alter table $table_name shard_row_id_bits=6;

我们使用了 25 台机器,后面还临时准备了 10 台机器去应对高并发的不时之需。

在使用过程中遇到如下问题:

( 1 ) 2.0.10 版本下 in 不能下推到表过渡问题

大家看到我们两个相同的表结构,同时写入一些数据,在两个表进行关联的时候,发现过滤条件 t1.id=1 时,上面那个执行计划可以下推到两个表进行过滤,两个表可以完全精准的把数据取出来,但是下面把等号后改成 in 的时候,对 t2 表进行全表扫描,如果 t2 表数据量很大时就会很慢,这是 TiDB 的一个 bug,解决方案就是不要用 in,在 2.1 版本修复了这个 bug。

( 2 ) 2.0.10 下时区设置导致客户端不能连

我们在跑命令的时候没有问题,并且结果是可以的,但是跑完后就断掉了,从后台看也是有问题的,重启 TiDB 组件也不行,后来找到代码我们发现这是一个 bug。

原因:这个 bug 会在你连接时 check 这个时区,导致用户不能连接。

解决办法:我们找研发同事重新编译一个 tidb-server 登入服务器,把时区设置为正确的,然后使用最初的 TiDB 组件登录,2.1 版本后这个 bug 修复。

( 3 ) Spring 框架下 TiDB 事务

这个问题是比较重要的问题,有个产品需要生成一个唯一的保单号,业务是批量生成的,当时在 TiDB 中我们建了一个表,表中只有一条数据,但是我们发现会有重复保单号出来。

原因:TiDB 使用乐观事务模型,在高并发执行 Update 语句对同一条记录更新时,不同事务拿的版本值可能是相同的,由于不同事务只有在提交时,才会检查冲突,而不是像 Oracle、MySQL、PG 那样,使用锁机制来实现对一记录的串行化更改。

解决办法:Spring 开发框架下,对事务的管理是使用注解式的,无法捕获到 TiDB commit 时的返回状态。因此需要将 spring 注解式事务改成编程式事务,并对 commit 状态进行捕获,根据状态来决定是重试机制,具体步骤:

1851 次点击
所在节点    推广
2 条回复
brust
2019-05-29 16:23:13 +08:00
tidb 是不是可以看做是自动分布式的 mysql
csl1995
2019-05-29 18:28:00 +08:00
@brust 可以,只是需要固态硬盘

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/568664

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX