腾讯金融级数据库TDSQL的架构与应用

腾讯云金融级数据库CDB for TDSQL (Cloud DataBase for Tecent Distribute
SQL)是一个适用于OLTP场景且与MySQL 5.5 、5.6兼容的分布式关系型数据库。

其前身是腾讯计费平台部为托管公司的虚拟账户,如QB、Q点、包月服务、游戏的二级账户等数据而打造的高性能数据库集群。在支持各大业务实时在线交易顺畅进行的同时,保证在各种灾难场景下数据的一致性、可用性。目前已经承载了包括webank、米大师等多家金融领域的主要业务数据。下面主要介绍TDSQL的核心架构和应用场景。

金融领域数据库的挑战:

数据高一致性:

对金融业务来讲,数据的强一致(Consistency)尤为重要,因为如果出现数据丢失,就意味着交易的丢失,这会给组织或用户带来直接的金钱方面损失,也有损企业商誉和信。因此,数据的一致性是DBA应该最需要考虑的问题之一。然而,传统数据库如果不使用共享存储的情况下很难做到主库出问题时数据不丢失。即使采用一些强同步的方案进行改造,也会造成数据库性能的下降,无法满足业务高并发需求。

服务高可用性:

随着业务需求的不断提高,搭建一个数据库高可用环境已经成为很多企业迫切的需求。确保企业中的计算资源持续可用性是DBA的主要目标之一。如果支持应用程序的数据库不可用,不仅会带来大量投诉或用户流失,也会给组织带来金钱方面的损失,损失信誉和商。高可用性和减少停机时间是数据库系统的目标,在诸如订单、支付等需要24*7无障碍运行的金融业务环境中尤其如此。

高并发和益伸缩性:

互联网金融的到来让金融服务向高效率、碎片化、低成本的方向快速转化。数据体量不断膨胀的同时,对业务请求的响应时间要求也愈加苛刻。在保证前两点的前提下,不断提升系统容量和吞吐率,保证毫秒级请求响应时长也是一个必不可少的能力。

投资和回报:

当前企业信息化的投入越发理性,决定企业信息系统构成的除了基础架构,通常还包括企业 的预算模型。对于或大或小的业务系统,在保证高一致性和高可用性的同时,也必须要考虑到企业预算和成本。商业数据库基于许可的采购模式,势必会导致建设成本高昂,难以扩展,且需要大量的资源来配置和维护。事实上,为维持可用、稳定的生产环境甚至非生产环境,企业需要不断地投入建设和管理费用,最终导致企业为数据库资源投入巨额成本。


腾讯云金融级云数据库解决方案

简介

CDB for TDSQL的诞生经历了十余年:

此处输入图片的描述

2002年,基于运营商SP业务,腾讯数据库团队开始对 MySQL进行改造;
2004年,腾讯互联网增值业务开始爆发,业务量的爆炸给数据库层带来了巨大扩容压力,这就开始引入分库表机制来解决难题;
2008年,腾讯游戏、QQ空间、财付通等各类业务再次爆发,为提高可用性,减少故障带来的损失和投诉,腾讯数据库团队全力解决一致性这个问题,引入多种机制保障主备数据的一致性,并提供数据自动恢复的能力。
2010年,基于正在火热的互联网支付业务超高可用性、超高并发和极短响应需求,腾讯数据库团队启动高一致(分布式)集群存储项目,最终达成了完全自动化的,在数据底层实现跨IDC的强同步、跨城容灾、切换一致性保障、数据自动分片、集群管理等能力。
2012年,腾讯内部正式给这款产品命名为TDSQL(Tecent Distribute SQL),且为了提高扩展性和开放性,将MariaDB作为数据库引擎的基础。在后续两年时间,陆续支撑米大师(Midas)、微众银行(WeBank)等多个兄弟业务的上线,并针对银行场景的数据关系模型设计了关系紧密的数据聚合,同时将跨节点的分布式架构转换扩展到单机架构,有效的覆盖了大中小多层次的用户。
2015年,TDSQL正式进驻腾讯云,并更名为腾讯云金融级数据库CDB for TDSQL,开始面向腾讯之外的企业提供金融级云数据库服务。

架构

此处输入图片的描述

系统由三个模块组成:Scheduler、Agent、网关,三个模块的信息交换都是通过ZooKeeper完成,极大简化了各个节点之间的通信机制。

先说下Set这个逻辑概念:由一主多从多个节点构成,每个节点包含一个Mysql实例和一个Agent实例,是承载数据存储和服务的底层物理数据库。一个或多个set可以通过网关形成一个逻辑数据库。

Scheduler作为集群的管理调度中心,主要功能包括:

  • 管理set,提供创建、删除set、set内节点替换等工作 所有的DDL操作统一下发和调度
  • 监控set内各个节点的存活状态,当set内主节点故障,发起高一致性主备切换流程
  • 监控各个set的CPU、磁盘容量、各个表的资源消耗情况,必要的时候自动发起扩容流程
  • Scheduler自身的容灾通过ZooKeeper的选举机制完成,保证中心控制节点无单点。

Agent模块负责监控本机MySQL实例的运行情况,主要功能包括:

  • 用短连接的方式周期性访问本机的MySQL实例,检测是否可读、可写,若发生异常,会将异常信息上报到ZooKeeper,最终会由上面描述的Scheduler模块检测到这个异常情况,从而发起容灾切换;
  • 检测主备复制的执行情况,会定期上报主备复制的延时和延迟的事务数,若发生了主备切换,自动向新主机重建主备,因此MySQL的主备不需要DBA干预,对于新增的实例会自动采用xtrabackup通过主机自动重建数据;
  • 检测MySQL实例的CPU利用率和各个表的请求量、数据量、CPU利用率,上报到ZooKeeper,ZooKeeper通过全局的资源情况抉择如何扩容、缩容;
  • 监控是否有下发到自身的扩容任务,如有则会执行扩容流程;
  • 监控是否要发生容灾切换,并按计划执行主备切换流程。

网关基于MySQL Proxy开发,在网络层、连接管理、SQL解析、路由等方面做了大量优化,主要特点和功能如下:

  • 解析SQL,将识别出的DDL语句直接存到ZooKeeper,让Scheduler来统一调度;
  • Watch ZooKeeper的路由信息,拉取最新的路由表保存到本地文件和内存;
  • 将SQL请求路由到对应的set,支持读写分离;
  • 对接入的IP、用户名、密码进行鉴权;
  • 记录完整的SQL执行信息,与秒级监控平台对接完成实时的SQL请求的时耗,成功率等指标监控分析;
  • count、distinct、sum、avg、max、min、order by、group by等聚合类SQL一般需要访问后端的多个set,网关会分析结果并做合并再返回,暂不支持跨set join和分布式事务;
  • 网关无状态,既支持与业务部署到一起,也可以独立部署(可通过TGW或者LVS做容灾)。

分表逻辑

在TDSQL中,每个表(逻辑表)可能会拆分成多个子表(建表的时候通过在建表语句中嵌入注释的方式提供一个shard字段名,最多会拆分出多个子表),每个子表在MySQL上都是一个真实的物理表,这里称为一个shard,分布在某个set中,因此一张表的数据可能会按这样的方式分布在多个Set中,如下图:

此处输入图片的描述

每个SQL请求到达网关之后,网关会做词法和语法解析,重点会解析出shard字段,如果带了shard字段就可以直接查询路由表并发送到某个具体的set中。计费的OLTP类业务99%的请求都会带上shard字段;如果某笔请求没有shard字段,查询路由之后会将请求发送到所有的shard对应的set中,并对所有返回的结果做一些聚合运算。

分片方式比较

TABLE SHARD:

此处输入图片的描述

GROUP SHARD特点:逻辑A、B、C表中具有同样的shard id的数据分布到同个set中。

目前TDSQL在腾讯云上暂时只支持单SET模式,GROUP SHARD模式也会很快上线。


容灾机制

对于TDSQL来说,我们希望容灾做到自动切换,自动恢复,主备一致性(保证业务提交的事务在切换过程不丢失),跨IDC容灾。

对于TDSQL来说,我们希望容灾做到自动切换,自动恢复,主备一致性(保证业务提交的事务在切换过程不丢失),跨IDC容灾。

对比下MYSQL的一些方案:

  • MySQL异步复制:

    在MySQL发展的早期,就提供了异步复制的技术,只要写的压力不是特别大,在网络条件较好的情况下,发生主备切换基本上能将影响控制到秒级别,因此吸引了很多开发者的关注和使用。但这套方案提供的一致性保证,对于计费或者金融行业是不够的。

  • MySQL半同步复制:

    到了MySQL 5.5版本的时候,Google提供了一个半同步半异步的插件,确保必须收到一个备机的应答才让事务在主机中提交;当备机应答超时的情况下,强同步就会自动退化成异步模式(这也是半同步半异步名字的由来);

下图是二者的比较:

此处输入图片的描述

半同步复制可保障一致性,但是:

  1. 超时后蜕化成异步,金融场景不合适
  2. 跨IDC的情况下性能不容乐观

此处输入图片的描述

半同步性能不好的原因分析:

此处输入图片的描述

不管是模型一还是模型二,每次执行SQL,都要先写binlog,然后往从机同步binlog,等待从机应答,然后再返回给client应答。虽然是多个线程,但执行流是同步的,CPU利用不起来。


TDSQL的线程异步化改造

此处输入图片的描述

  • 上半部分:任务执行到写binlog为止,然后将会话保存到session中,接着执行下一轮循环去处理其他请求了,这样就避免让线程阻塞等待应答了;
  • 然后:MySQL自身负责主备同步的dump线程会将binlog立即发送出去,备机的IO线程收到binlog并写入到relay log之后,再通过UDP给主机一个应答;
  • 在主机上,开一组线程来处理应答,收到应答之后找到对应的会话,执行下半部分的commit,send应答,绑定到epoll等操作。绑定到epoll之后这个连接又可以被其他线程检测到并执行了。

效果:

此处输入图片的描述


数据高可用性保障机制

主备自动切换

此处输入图片的描述

上面的强同步还有点小缺陷:比如主机用kill -9杀掉,那么可能写了binlog但没有来得及发送到远端,此时当然也不会返回给业务成功,备机上不存在这笔数据,但主机起来之后会多出来这笔事务。我们的做法是对新增的事务根据row格式的binlog做闪回,当然回退不了的比如drop table之类的,就直接提醒运维手工确认是保留还是清除数据库,然后会由Xtrabakcup机制自动从新的备机全量拉取数据重构。

灵活的主备配置

通常为了保证可用性,TDSQL最少要求一主二从分布在3个IDC的部署方式,保证任意一个IDC挂掉都不影响系统的可用性和数据一致性。2个IDC同时挂掉,系统还可以提供只读服务。当然业务可以根据自身需要增加更多的从节点,同时可以选择性的将读请求分到从机,进一步提高系统的可用性和处理能力。甚至可以选择增加异地的灾备节点(通常采用异步的方式),提供跨城容灾的能力。


TDSQL应用

目前TDSQL已经在腾讯云官网对外开放售卖;

完善的帐号和权限管理:

为了更好的控制风险,TDSQL默认不提供超级用户,也无法直接通过SQL语句进行帐号和权限管理。响应的,在WEB管理页面,有非常方便的管理模块:

此处输入图片的描述

上图是帐号列表,点击左上按钮可以新建用户,指定用户名和主机,主机支持%这样的匹配方式,点击克隆帐号可以完全复制当前帐号的权限来新建一个帐号。

点击修改权限,如下图:

此处输入图片的描述

可以看到,通过左边的导航栏,提供了完全兼容mysql管理方式的图形化界面,权限管理可以细化到列级。(图中因为是系统表,所以只提供SELECT权限的授权)。

支持批量设置参数

高效便捷的数据库参数设置:

此处输入图片的描述

支持查看参数修改历史记录:

此处输入图片的描述

慢查询分析

下图是按时间段列出的不同慢查询(抽象后的)的列表:

下图是某条慢查询(抽象后的)详细统计数据:

此处输入图片的描述

操作日志,记录60天内所有相关管理操作记录:

此处输入图片的描述


TDSQL的未来规划

  1. SQL审计:满足客户的信息安全需求,进一步提高数据安全性;

  2. SQL加密:提供文件级别的加密保护,就算丢了硬盘也不怕;

  3. 支持GROUP SHARD的分布式方案;

  4. 用户SQL性能分析和故障诊断工具;


  • tdsql 是如何量化优化的query,带来的性能提升?

    答: tdsql基于mariadb,如果是单set版本,你可以认为就是一个mariadb。如果是shard版本,则在网关层面做了解析shard id,分发sql,聚合结果等操作。主要是解决分布式的问题。性能上主要在主从同步上做了线程异步话改造。query解析层面并没有针对性能做太多工作。

  • tdsql怎么支持前端应用性能线性扩容?

    答:TDSQL在网关层做sql进行分析,路由,聚合。底层set可以线性扩展。系统整体容量和吞吐量也会线性提高。

  • 采用shard,与MySQL cluster有什么区别?

    答:shard的方式与cluster没有本质区别,分布式采用shard的方式,提供自动缩容、扩容的弹性管理方式。业界方案其实差别不大。但高可用方面,业界有主从同步和多主的方式。TDSQL采用前者,且在保证强一致性的前提下对性能做了优化。