「TEG+ 系列」破局者 - 腾讯金融级数据库 TDSQL
**背景**
金融行业的数据库市场,尤其是银行的核心交易系统,一直是 Oracle、DB2 这类传统商业数据库的天下,但是:
2014 年,微众银行选用 TDSQL 作为其核心交易系统的数据库解决方案;
2015 年,腾讯金融云正式推出 TDSQL 数据库解决方案,在公有云以及私有云上投入商用,覆盖包括银行、保险、互联网金融、物联网等多个行业领域。
这标志着 TDSQL 已经开始进入这个领域,虽然目前,金融、传统行业的核心数据库依然是 Oracle、DB2 们占主导,但是 TDSQL 对外开放仅两年,已经为 40 个金融政企机构提供数据库服务,部署 Set 数已达 800+(一个 Set 由一主两备三个数据库结点组成),算是开了一个好头。
**选择 TDSQL?**
首先是金融行业自身受到了互联网行业的冲击。例如目前中国网民的两大节日:阿里巴巴的“11.11 剁手节”,微信的“春节红包节”,给银行的支付系统,尤其是快捷支付系统,带来了很大冲击,原有的 IOE 架构面领比较大的挑战。此外,金融行业内部也开始思考,如何通过云计算、大数据等技术,提供更为普惠的金融服务,提升金融行业的服务效率。这些都使得基于 TDSQL 的分布式互联网架构来代替集中式的 IOE 架构成为可能。
其次,在诸多数据库产品以及内外竞争对手之中,TDSQL 有着其自身明显的优势:十年在计费及支付行业的使用,在数据的安全性,可用性等方面有大量的实战积累,填了不少的坑。计费平台部从 2007 年开始,探索数据库的高可用、高一致性,着力研究如何为计费支付应用提供 7*24 的高可用服务,系统经历三代更迭。
**1)**7*24 容灾机制,是一套基于黑名单机制的主备容灾切换机制,牺牲极少数用户的可用性,确保系统的数据高一致性。
**2)**厚德(HOLD)KV 存储,是第一代容灾机制的延续,主要是将黑名单等容灾机制下沉到存储系统,彻底将容灾与业务逻辑解耦,业务开发人员不再需要关心容灾。同时引入集群管理机制,及自动扩容技术,在请求量及时耗要求特别高的场景下,目前依然大量使用,目前部署节点数达 400+。
**3)**TDSQL,2012 年开始,团队开始思考如何将我们在数据库容灾切换、数据高一致性等方面的经验输出出去,于是就有了 TDSQL,其可以说对计费前几代存储系统的整合之作:使用 MySQL 作为底层数据节点,把厚德(HOLD)中验证过的集群架构直接移植过来,将金融场景下最关注的一致性保障和水平伸缩等关键特性,都直接融入底层架构中。这样能完美兼容 MySQL 协议,降低原有基于数据库的业务系统的割接难度。
**最后**,当然也有硬件行业的快速发展的契机,尤其是 SSD 在公司的大规模使用,使得 TDSQL 的云化成为可能。
**前期的挑战?**
**第一阶段是 2014 年**,微众接入之初。在此之前,TDSQL 并没有为公司外部客户提供过服务,其产品化是一个比较初级的阶段,虽然有十年计费使用经验作为背书,但是双方团队依然有一个信任的磨合期。
关于 TDSQL 服务承诺的信任?TDSQL 承诺在任意单点故障情况下,RPO 为 0,RTO 为 40 秒,但是并没有其他第三方机构针对 TDSQL 出过类似数据。对此,双方测试团队坐在一起,耗时 1 个月,构造 100+测试用例,在高并发场景下,模拟各种异常情况,以确保能符合 TDSQL 的服务承诺。
关于数据库及应用架构的设计?因为双方实际生产环境的网络架构不一样,导致双方前期在数据库及应用架构部署上,有较大的分歧,对此,双方架构师团队也是经过频繁的多层次的交流,最后在综合成本及系统安全性之间做好平衡,分阶段设计出不同架构体系。
**第二个阶段是在 2015 年**,TDSQL 正式为金融云提供服务后,较多的外部客户接入进来,带来了新的一些新的挑战。
**TDSQL 能否适应更为复杂的场景?**之前 TDSQL 更多的使用于 OLTP 场景,尤其是大量高并发的短事务场景,为了提升吞吐量,并解决 MySQL 的连接数限制问题,引入的数据库线程池功能,而这个功能在某些场景下有些不适用,例如在同时有大量复杂 SQL(耗时至少几秒以上的 SQL)并发时,系统吞吐量急剧降低。而云上大量接入进来的金融客户业务开发团队,却依然将 TDSQL 当作 Oracle 来用,这导致问题凸显,对此团队深入 MySQL 内核,做了大量优化,例如对线程池的优先级队列进行优化,有效解决复杂 SQL 高并发带来的吞吐量降低问题。
传统思维与互联网思维的冲突?团队与大量传统金融行业的 IT 人员交流之后发现,双方在如何使用分布式数据库等方面,依然有比较大的分歧,例如传统行业的业务系统极为依赖数据库,基本上一条 SQL 用 A4 纸都打印不完,大量使用存储过程,而互联网行业则将大量的逻辑放在应用层,数据层尽可能的轻量化、服务化。类似的冲突,可能不是一时半会能统一的,在不同的场景下,可能需要作出不同的选择与权衡。TDSQL 需要向 Oracle 学习,联合各个上下游服务提供商或集成商,尽量为客户提供一套完整的分布式解决方案。
**TDSQL 的解决之道**
下面将从核心架构、内核优化、部署方案、周边配套、产品化等方面来分析一下,TDSQL 是如何适应金融行业需求的。
**1、核心架构**
在一致性方面,利用 MySQL binlog 的严格有序性以及强同步复制机制,再结合 Raft 协议思想(Raft 协议核心两点就是 Leader 选举、日志复制),我们最终实现了 TDSQL 的强一致性以及数据零丢失。
**强同步机制:**基于 MySQL 半同步复制优化,对于进入集群的每笔更新操作,都将发到对应 Set(每一个 Set 包含 3 个 MySQL 实例:一主两备)的主机上,主机会将 binlog 发往两个备机,且收到其中任一一个备机应答后(仅仅是备机收到了 binlog,但可能还没有执行这个 binlog),然后才本地提交,并返回给客户端应答,这就能确保数据零丢失。
可用性:在这种强同步机制下,建议是存 3 个数据副本,且分别分布在 3 个 IDC,这样在任一 IDC 故障情况下,剩下两个 IDC 依然能够提供服务。如果仅存 2 个副本,在某中一个副本故障情况下,系统将会降级为只读服务。
**Leader 选举:**MySQL 节点本身无法直接参与选举,于是我们由 Scheduler 模块来负责这个事,如果主机发生故障,Scheduler 会从两个备机中,选择一个数据较新的备机(因为 MySQL binlog 是严格有序的,所以谁同步主机 binlog 的偏移量更大,谁的数据就更新。当然也可以基于 GTID 来判断)提升为主机。
**自动扩容:**目前 TDSQL 有两个分支版本,一个是 No-Sharding 版本,一个是 Group-Sharding 版本,NS 版本不支持自动扩容,GS 版本支持自动扩容,但是该版本对 SQL 有一定的限制。
Group-Sharding 虽然不支持跨节点事务和 Join,但是在一个 Group 内,可以支持 Join 和事务。举个例子,假设有两张表:用户信息表与用户账户表,我们可以将这两张表组成一个逻辑 Group,且这两张表都按用户 ID 字段 Sharding,后续 Group 内任意一张表需要 Re-Sharding 时,该组内所有表都同时进行 Re-Sharding(相当于按 Group 进行 Sharding),这样单个用户相关数据一定会落在一个 Shard 上(即同一个 MySQL 实例),于是在单个用户条件下,这些表之间是可以做 Join 和关联的。
**2、内核优化**
TDSQL 在数据库内核这块的优化,主要集中在数据复制、性能、安全性等方面。
强同步机制。TDSQL 针对金融场景的强同步机制,有效解决了 MySQL 原生半同步机制的问题:性能降低以及超时退化为异步。目前 TDSQL 在强同步模式下,系统的并发量(TPS/QPS)与异步模式已无差别,基本能做到性能无损失。
性能优化。
1)我们对 MariaDB/Percona 的线程池调度算法进行了优化,改进当系统处于重负载时,查询和更新请求在线程组间分布不均衡等极端情况。并且能够更好地利用计算资源,减少无谓的线程切换,减少请求在队列中的等待时间,及时处理请求。
2)组提交(Group Commit)的异步化。工作线程在其会话状态进入组提交队列后,不再阻塞等待组提交的 Leader 线程完成提交,而是直接返回处理下一个请求。
3)InnoDB Buffer Pool 使用优化。例如全表扫描时,避免占满 InnoDBBuffer Pool,而是只取一块来使用。
4)InnoDB 在 MySQL 组提交期间避免与组提交有 mutex 冲突的活动,例如 InnoDB Purge,降低冲突,以提升性能。
类似的性能优化的点,还有不少,可能在某些场景下,单个点效果不明显,但是集合起来看,目前性能指标整体是不错的。目前 TDSQL 在云上 TS85 机型下(24 核、512G 内存、6T 磁盘),用 sysbench 测试,纯写入操作能到 10 万 TPS,纯查询操作能到 40 万 QPS。
此外,我们长期关注 MySQL 的三个分支版本:Oracle MySQL、MariaDB、Percona,对于社区的新特性,也会定期的合入。
**3、部署方案**
基于成本因素考虑,不同的客户,甚至说同一客户在不同阶段,会有不同的网络架构,例如一些客户前期可能做不到两地三中心,后期也不会像腾讯那样,拥有那么多数据中心。所以 TDSQL 可以针对客户不同的网络架构,在保障一致性及数据不丢的情况下,在可用性上做出权衡,做到灵活部署。目前常见的两种部署方案包括:
**两地三中心,ZK 分布在两地的三个中心内。**
1)主 IDC 故障不会丢数据,自动切换到备 IDC,此时蜕化成单个 IDC 的强同步,存在风险。
2)仅仅主机故障,在对比两个同城备节点及一个同城 Watcher 节点后,切换到数据最新的节点,优先选择同 IDC 的 Watcher 节点,尽可能减少跨 IDC 切换。
3)备 IDC 故障,通过另外一个城市的 ZK 能自动做出选举:
a、备 IDC 确实故障,自动提升主 IDC 的 Watcher 节点为 Slave,由主提供服务
b、主备网络不通,与 a)一样的处理方式
**两地四中心,适应性最强,但是对机房数量要求也高一些。**
1)同城三中心集群化部署,简化同步策略,运营简单,数据可用性、一致性高;
2)单中心故障不影响数据服务;
3)深圳生产集群三中心多活;
4)整个城市故障可以人工切换;
**4、周边配套**
给一个已经相对成熟的行业去推一款新型数据库,如果仅仅提供数据库底层是远远不够的,其配套设施、可维护性、透明性等对于客户来说至关重要,因为这决定了他们能否及时发现问题,针对问题能快速的做出变更及应对。所以 TDSQL 私有云版本,提供完善的周边配套体系,例如:
1)冷备系统。基于 HDFS 或其他分布式文件系统,可以做到自动备份,一键恢复。
2)消息队列。基于 Kafka 定制的 Binlog 订阅服务。基于该消息队列,TDSQL 还提供了 SQL 审计、多源同步(相同表结构的数据合并到一张表)等服务。
3)资源管理。基于 cgroup 的对 TDSQL 实例进行编排,提高机器资源利用率。
4)OSS。对 TDSQL 的所有操作,例如扩容、备份、恢复、手动切换、申请(修改/删除)实例等操作,均提供统一的 HTTP 接口,可以有效自动化,降低人肉运维的风险。
5)数据采集。TDSQL 所有的内部运营状态或数据,都能实时采集到,业务可以基于这些数据做定制分析或者构建运营监控平台。
6)监控平台。业务可以基于数据采集模块采集到的所有数据,对接自建的监控系统,亦可直接使用 TDSQL 自带的监控系统(需单独部署)。
7)管理平台。基于以上模块,TDSQL 自带运营管理平台(内部平台代号赤兔),DBA 基本上可以通过该管理台进行所有常规的运营操作,不再需要登录后台。
以上这些模块可以自由组合,没有强依赖关系,对于 TDSQL 的推广极为有力,因为纯接口方式,松耦合对于 TDSQL 对接客户的自建系统,例如监控平台等极为方便。
**5、产品化即云化**
诸多案例来看,TDSQL 及互联网架构完全有能力支撑金融核心业务。而其低成本、高弹性以及开放的架构又恰好能弥补传统 IOE 架构的不足。
看起来,TDSQL 就是去 IOE 的银弹。但是,事实真的如此吗?
大家都知道,互联网分布式架构的底层基础是开放的硬件和开源的软件,初始获取成本会比较低。但是,要用于生产的话,还需要进行大量的、持续的优化和改进,而且对运维团队的能力要求也比较高。如果企业想直接迁入分布式架构上,势必需要组建一个技术团队来搞定这些问题,这就相当于将原来 IOE 架构下投在软硬件上的成本转投到人力上。在 IT 系统规模较小时,完全没有优势,甚至是得不偿失的。这也是“去 IOE”喊了这么久,实质性进展却比较小的一个原因。
但是,云计算的出现改变了这一切。在云计算架构下,这些本来要招一帮牛人才能搞得定的事情,现在已经有一帮甚至更牛、更专业的人帮你搞定了。你要做的,只是“申请、使用”,就这么简单!
所以,TDSQL 不是去 IOE 的良药,TDSQL on Cloud 才是。目前与腾讯金融云团队,除了巩固 TDSQL 在金融公有云这块的优势,还在积极探索私有云业务(银行一般都是私有云部署),这对我们系统的可用性、文档全备性、周边配套完整性等提出了更高的要求,这也是我们未来的投入方向之一。
评论