腾讯云分布式数据库 DCDB 架构解密

腾讯云分布式数据库是一个适用于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,开始面向腾讯之外的企业提供金融级云数据库服务。 2017年,腾讯云CDB for TDSQL更名为CDB for MariaDB,同时正式推出分布式数据库DCDB

架构:

系统由三个模块组成: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容灾。 MySQL异步复制: 在MySQL发展的早期,就提供了异步复制的技术,只要写的压力不是特别大,在网络条件较好的情况下,发生主备切换基本上能将影响控制到秒级别,因此吸引了很多开发者的关注和使用。但这套方案提供的一致性保证,对于计费或者金融行业是不够的。 MySQL半同步复制: 到了MySQL 5.5版本的时候,Google提供了一个半同步半异步的插件,确保必须收到一个备机的应答才让事务在主机中提交;当备机应答超时的情况下,强同步就会自动退化成异步模式(这也是半同步半异步名字的由来) 下图是二者的比较:

半同步复制可保障一致性,但是: 1.超时后蜕化成异步,金融场景不合适 2.跨IDC的情况下性能不容乐观

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

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

  • 上半部分:任务执行到写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同时挂掉,系统还可以提供只读服务。当然业务可以根据自身需要增加更多的从节点,同时可以选择性的将读请求分到从机,进一步提高系统的可用性和处理能力。甚至可以选择增加异地的灾备节点(通常采用异步的方式),提供跨城容灾的能力。

DCDB应用

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

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

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

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

支持批量设置参数

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

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

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

操作日志:

记录60天内所有相关管理操作记录

数据库审计:

管理员可以针对关心的敏感SQL操作,创建审计规则,然后绑定审计策略到TDSQL实例,系统会记录符合规则的SQL,供管理员查看

数据库同步:

支持创建TDSQL为源,TDSQL或PostgreSQL为目标的数据库同步任务,自动完成历史数据的传输,实时同步增量数据。

分布式数据库的未来规划

DCDB支持小表广播、分布式事务等 DCDB支持复杂查询

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

胡彬的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏后端技术探索

一步步构建大型网站

今天我们来谈谈一个网站一般是如何一步步来构建起系统架构的,虽然我们希望网站一开始就能有一个很好的架构,但马克思告诉我们事物是在发展中不断前进的,网站架构也...

762
来自专栏IT技术精选文摘

分布式系统一致性保障方案总结

引言 在互联网系统中,理想的情况下,肯定是希望系统能够同时满足“一致性”、“可用性”和“分区容忍性”。 但是基于熟悉的CAP定律也好,还是BASE理论, 我们知...

26310
来自专栏ThoughtWorks

浅谈微服务基建的逻辑 | 洞见

这篇文章主要目的是面向初接触微服务的朋友简单介绍微服务基础建设所需要的各个模块以及缘由。 起点 首先,我们得有一个“服务”。根据定义,我们可以把每个服务实例都视...

3495
来自专栏IT技术精选文摘

微服务简介

我们先来看看你为什么要考虑使用微服务。 构建单体应用 让我们假设你们要开始制定一个全新的出租车招标程序,旨在与Uber和Hailo进行竞争。经过一些初步会议和...

2365
来自专栏架构师之路

微信为啥这么省流量?

前言:“客户端上传时间戳”的玩法,你玩过么?一起聊聊时间戳的奇技淫巧! 缘起:无线时代,流量敏感。APP在登录后,往往要向服务器同步非常多的数据,很费流量,技术...

3469
来自专栏美团技术团队

【沙龙干货】RDS平台介绍

今天我就给大家讲一下我们这边做的数据库运维的自动化平台,他是怎么样子的。首先我会给大家简单介绍一下我们做平台的背景,以及平台的一些技术架构,以及针对我们DBA和...

4024
来自专栏Rainbond开源「容器云平台」

【微服务干货系列】微服务性能模式

1695
来自专栏编程一生

业务高速增长场景下的稳定性建设实战

1502
来自专栏王亚昌的专栏

SNS站点的数据存储方案

    今天看了篇文章,谈到SNS站点应用中的分库分表问题,这里我也谈谈我对SNS站点和应用数据存储的看法。

532
来自专栏EAWorld

【详解】为什么选择Spring Boot作为微服务的入门级微框架(PPT)

? 1. Spring Boot是什么,解决哪些问题 1) Spring Boot使编码变简单 2) Spring Boot使配置变简单...

3404

扫码关注云+社区