本文摘自TDSQL白皮书
概述:
1. TDSQL支持OLTP与OLAP,是分布式云平台数据库
2. 架构上是MySQL的主从组成SET,数据通过建表时指定分片健,水平拆分到不同SET。SQL Engine用于SQL解析并把请求路由到相应SET. 集群功能由ZooKeeper完成
3. 提供了虚拟VIP,节点可自动完成故障恢复及VIP切换
4. 支持分布式事务,可以二阶段提交,可以进行跨节点JOIN.
5. 提供了自动化运维平台
一、 架构
1. 分片(Sharding):由数据库节点组(SET)和SQL引擎层(SQL Engine)和支撑系统组成一主多从数据库;
2. SQL引擎层(SQL Engine)功能:账号鉴权、管理连接、SQL解析、分配路由的SQL Engine模块;SQL Engine建议独立部署在高性能CPU及SSD的物理机中。SQL Engine也是采用分布式架构设计,提供并行负载和高可用容灾能力
3. 调度集群(Scheduler): 帮助 DBA 或者数据库用户自动调度和运行各种类型的作业(如数据库备份、收集监控、生成各种报表或者执行业务流程等等),通过时间窗口**指定的资源计划,完成数据库在资源管理和作业调度上的各种复杂需求,Oracle也用DBMS_SCHEDULER支持类似的能力。
4. 决策集群(ZooKeeper): 在TDSQL中,它的主要功能是配置维护、选举决策、路由同步等,ZooKeeper支撑数据库节点组(分片)的创建、删除、替换等工作,集群部署要求大于等于3组且跨机房部署。
5. TDSpark节点:基于Spark扩展的计算节点,采用只读的方式与SET连接,以JDBC的方式获取数据。
6. 赤兔运营平台(chitu):基于TDSQL定制开发的一套自动运维平台,提供了两套:
1)赤兔运营平台:从管理员视角,提供TDSQL的全部运维功能,可管理TDSQL集群的物理资源、调度决策系统、备份与恢复系统、可用区管理、实例管理、智能性能分析与监控告警、主要工具等,主要用于腾讯内部或企业IT运维团队使用。
2)云数据库管理系统:从租户视角,提供TDSQL实例的运维功能,可管理TDSQL数据库实例,包括实例申请与退还、系统监控与告警、备份与恢复、性能优化等,主要用于云的客户或业务团队使用。
二、 多租户的云数据库
TDSQL是基于“云”的数据库,这使得TDSQL可以多租户申请实例,实现租户共享同一堆栈的软硬件资源的能力。为每个租户配置一个实例,利用统一资源调度与迁移,能够很好的实现架构扩展,并且能够解决峰值平衡的问题。
虚拟化让多个租户的业务共享物理设备性能,而传统隔离方案严格限制了每个租户实例的性能大小。这种限制方案很公平,但没有考虑到业务特点:大多数业务仅在一天(一月)的少数时刻有较大的业务压力: 该业务日 CPU 平均使用率仅 30%,而一天中仅存在7次业务压力较大,CPU使用率在80%~100%。虽然云能够基于弹性扩容,然而普通的弹性方案在这种突发性的压力面前,仍然无能为力——可能当您反应过来,您的业务峰值已过;最终,您还得基于业务峰值配置实例,浪费实例性能。
闲时超用技术,即在绝对保证每个实例预分配性能下限的基础上,允许实例使用超过预分配的性能。举个例子:假定 A 实例承载新闻业务,B 实例是承载游戏业务,A、B 实例被分配到一台物理设备中,A可以在B的空闲时间,抢占(有限的,并发全部)一部分空闲性能。当然,A、B同时面对峰值时,系统会确保A、B两实例底线的性能需求。
三、 强同步复制(MAR)
MySQL数据库复制包括异步复制、半同步复制两种。这两种复制技术的主要问题是,节点故障时,有可能导致数据丢失或错乱。而且,这类复制技术以串行复制为主,性能相对比较低。
腾讯自主研发了的基于 MySQL 协议的并行多线程强同步复制方案(Multi-thread Asynchronous Replication,MAR),在应用发起请求时,只有当从节点(Slave)节点返回成功信息后,主节点(Master)节点才向应用应答请求成功;这样就可以确保主从节点数据完全一致。
说明:使用“强同步”复制时,如果主库与备库自建网络中断或备库出现问题,主库也会被锁住(hang),而此时如果只有一个主库或一个备库,那么是无法做高可用方案的。(因为单一服务器服务,如果故障则直接导致部分数据完全丢失,不符合金融级数据安全要求。)因此,TDSQL在强同步技术的基础上,提供强同步可退化的方案,方案原理类似于半同步,但实现方案与google的半同步技术不同。
四、 自动故障转移与恢复
1. 网络进行实时的数据复制。本地为主机,远程为从机,首先访问本地的节点,若本地实例发生故障或访问不可达,则访问远程从机。
2. 支持故障自动转移,集群自动成员控制,故障节点自动从集群中移除;如果是实例级的主从切换,换后VIP(虚拟IP)不变;基于强同步复制策略下,主从切换将保证主从数据完全一致,可满足金融级数据一致性要求。
3. 支持故障自动恢复,承载分片的物理节点故障,调度系统自动尝试恢复节点(自动重启),如果原节点无法恢复,将在30分钟内自动申请新资源,并通过备份重建节点,并将节点自动加入集群,已确保实例长期来保持完整的高可用架构。
4. 每个节点都包含完整的数据副本,可以根据DBA需求切换;
5. 支持免切设置,即可以设置在某一特殊时期,不处理故障转移。
五、 数据REBALANCE
TDSQL的整个迁移过程采用迁移存量数据、迁移增量数据、数据检验、再追增量、切换路由、清理六个步骤循环迭代进行。
1. 控制台点击扩容A分片后,系统计算需要搬迁的数据,并开始配置G节点;
2. G节点配置完成后,将A节点需要迁移的数据(通过从机)同步到G节点;
3. 数据完全同步后,AG开始互相校验数据(存在1~几十秒的只读),但整个实例不会停止运行;
4. 调度通知SQL Engine切换路由,完成后将A/G节点置位正常状态,A进入慢速删除状态
六、 四种读写分离方案
TDSQL默认支持读写分离能力,由SQL Engine集群(SQL Engine)自动分配到低负载从机上,以支撑大型应用程序的读取流量:
1. 仅需要在创建帐号时,标记为只读帐号,系统将根据只读策略向将读请求发往从机;只读策略可以根据主从延迟等维度进行灵活配置。
2. 您可以在编程过程中,通过注释/*slave*/,系统将把该条语句发往从机
3。 全局自动读写分离:您可以开启全局自动读写分离,该配置会自动将SQL中的读请求发向从机,且能识别事务、存储过程中的读语法并灵活处理。当然如果从机延迟较大,全局自动读写分离并不具备策略。
4。 可以自建或申请只读实例,只读实例是专用于读请求的一种实例,不参与高可用切换
七、热点更新(感觉是应用层来减少数据层的锁等待)
在“秒杀”和“限时抢购”等这样的场景下,大量的用户在极短的时间内请求大量商品。而体现在 MySQL 数据库中,同一商品在数据库里肯定是一行存储,所以会有大量的线程来竞争 InnoDB 行锁,当并发度越高时等待的线程也会越多,TPS 会下降RT会上升,数据库的吞吐量会严重受到影响。这会导致什么问题呢?
1)单个热点商品会影响整个数据库的性能,即1个商品做秒杀,影响整个平台性能和稳定性。
2)数据不一致,如100个库存结果卖出去101个
业内的通常采用引入多层架构,如热点缓存 cache,热点库等方案。当然,这一类方案维护成本略高,且如果cache被击穿,则容易带来雪崩问题。
TDSQL的解决方法:
在SQL层,通过一个全局Hash表存储有INSERT/UPDATE请求的热点对象,其大小与热点对象上限相等。INSERT/UPDATE请求到达时,先查找Hash表中有无对应的热点对象,有就获取lock,会被阻塞;没有该热点对象,那么创建该热点对象,如果热点对象达到上限,那么返回错误,如果创建成功,那么持有lock并添加到Hash表。成功获取到热点对象lock,可以继续执行 INSERT/UPDATE,否则等待 lock 被释放和系统调度到该线程。INSERT/UPDATE返回后,释放热点对象lock,使得后续线程可以执行,如果后续线程不再INSERT/UPDATE改热点对象,将其从Hash 表移除(如下图)
八、 SQL防火墙(用于配合WAF等一起使用)
SQL防火墙是对用户发送的SQL进行语法解析,过滤非法的SQL的一种安全能力。其与SQL Engine配合,可以对用户预先定义的一些非法SQL进行判断,从而对非法SQL进行过滤、阻断,有效的预防SQL注入或一些恶意非法攻击。
九、 慢速删除
当用户执行drop table或者alter table ... drop partition 时,数据库不是立刻删除表空间文件,而是将这些文件重命名并且在后台逐步缩小这些文件并最终删除。慢速删除可避免一次性删除巨大的表空间文件给服务器的文件系统带来突增的IO负载,导致系统出现波动
十、 分布式数据库
无需用户手动去配置分表逻辑,无需用户额外去部署管理中间件,只需要在建表是指定分表关键字即可。分片也是找表上某列做shardkey,再按日期/范围/HASH分(这类特点都是使用shardkey检索的SQL效率会高)
如果一个查询 SQL 语句的数据涉及到多个分表,此时 SQL 会被路由到多个分表执行,TDSQL 会将各个分表返回的数据按照原始 SQL 语义进行合并,并将最终结果返回给用户:
TDSQL为用户提供了三种类似的表:分表,广播表及单表:
1. 分表:每个分片都有一部分数据,所有分片构成了完整的数据
2. 广播表: 每个SET都有完整的数据
3. 单表:即无需拆分的表,又叫普通表,目前单表都放在第一个物理分片(set)中
业务拆分应确保某些复杂的业务逻辑运算,聚合到一个物理分片内。下面的一些典型应用场景都有明确的业务逻辑主体,可用于拆分键:
1. 面向用户的互联网应用,都是围绕用户维度来做各种操作,那么业务逻辑主体就是用户,可使用用户对应的字段作为拆分键;
2. 电商应用或O2O应用,都是围绕卖家/买家维度来进行各种操作,那么业务逻辑主体就是卖家/买家,可使用卖家/买家对应的字段作为拆分键;但请注意,某些情况下几个超大卖家占到绝大多数交易额,这种情况会导致某几个分片的负载和压力明显高于其他分片,我们会在后面章节予以说明。
3. 游戏类的应用,是围绕玩家维度来做各种操作,那么业务逻辑主体就是玩家,可使用玩家对应的字段作为拆分键;
4. 物联网方面的应用,则是基于物联信息进行操作,那么业务逻辑主体就是传感器/SIM 卡,可使用传感器、独立设备、SIM卡的 IMEI作为对应的字段作为拆分键;
5. 税务/工商类的应用,主要是基于纳税人/法人的信息来开展前台业务,那么业务逻辑主体就是纳税人/法人,可使用纳税人/法人对应的字段作为拆分键;
TDSQL规定了拆分键设定的技术限制:
1. Shardkey需要是主键以及所有唯一索引的一部分;
2. shardkey字段的类型必须是int,bigint,smallint/char/varchar
3. shardkey字段的值不应该有中文,SQL Engine不会转换字符集,所以不同字符集可能会路由到不同的分区
4. 不要update shardkey字段的值
分布式事务
TDSQL 通过多种优化,提供了高于开源 XA(分布式事务简称)的性能
TDSQL业内少数几个支持分布式JOIN,分布式JOIN 分为可下推和不可下推:
1. 可下推JOIN,是指可在存储层直接JOIN的情况,通常包括:
1)同纬度(拆分建)的JOIN:两张表采用相同的拆分键,如:SELECT * FROM user JOIN user_order ON user.user_id=user_order.user_id;由于user与user_order 均已user_id为拆分键,因此同一用户(user_id)的记录位于同一分片上,JOIN直 接由底层出错了完成。此时性能最高。
2)分表与广播表的JOIN:由于所有分片中都存在一个完整的广播表副本,因此分表与广播表的JOIN也可下推到存储层执行。
2. 不可下推的JOIN,是指需要由存储层和SQL Engine共同完成的JOIN,通常包括:
单表与分表的JOIN,分表与分表且不同字段的JOIN等。腾讯云优化不可下推的分布式JOIN,并采用如下的过程执行(如下图)。
十一、 RocksDB引擎
RocksDB是由Facebook开源的一套基于LSM的KV存储系统,通常适用于写量超大业务场景,例如物联网,电商订单等场景。目前RocksDB已在TDSQL的分布式实例和关系型实例中支持,您可以在创建实例是选择RocksDB。使用RocksDB后,您也可以在建表时显示指定InnoDB或XtraDB引擎。
RocksDB强大的写性能优异性主要来自于LSM Tree算法。LSM Tree 是一种将随机写合并为顺序写的算法(如下图),数据以 KV 值有序存储,随机写入数据库时,先以树状结构(tree)组织更新在内存中;由于每一个数据的 KV 值是全局有序的,随着写入的增加,内存的 tree 不断变大(丰富其树状枝丫),当一定程度后,相同层级的 tree 值发出与磁盘的 tree 合并操作。一次性批量写入已经组织好的有序数据,即将随机写入,通过LSM组织为顺序写入。这样就大大的提高了写入效率和并发。
十二、 分析型实例TDSpark
MySQL无法有效应对高计算强度的OLAP业务需求,通常需要借助ETL工具将数据同步到OLAP类数据库中。而TDSpark深度整合了Spark Catalyst引擎,并集成腾讯自研的且MySQL协议的SQL Engine,利用TDSQL关系型实例或分布式实例现有数据,(通过从机)直接拉取到Spark引擎中进行计算。从数据集群的角度看,TDSpark可以让您直接在同一个平台进行事务和分析两种工作,简化了系统架构和运维
系统架构
1. OLAP SQL Engine:
专门用于接收并处理客户端发来的OLAP类型的SQL。SQL Engine不与后端数据库相连,而是与运行在Spark集群集群上的Handle-sever交互。在获取到客户端发来的请求后,将 SQL 语句以JSON的形式发送至Handle-sever进行处理,并等待Handle-sever的响应。
2. Handle-server:
负责接收OLAP SQL Engine发来的JSON协议的请求,并给出响应。在接收到OLAP SQL Engine的请求后,对JSON串进行解析,得到SQL语句,同时对SQL进行语法解析得到库表名,并封装成独立的Spark job提交到Spark集群进行计算,待Spark得到结果后,将结果集转换成 mysql协议并返回给SQL Engine。
Spark集群在执行job的过程中,需要连接后端OLTP类实例(关系型或分布式实例)的SQL Engine,以JDBC的方式获取数据,在连接后端OLTP类实例的SQL Engine时,采用只读账户,从从机获取数据,从而降低对主机性能的影响。
而Spark集群的资源管理由独立的Spark-manager进程完成。Spark-manager负责Spark集群工作节点的购买,资源回收,集群扩容等工作。多租户下,同一组机器资源Spark的部署方式如下图所示,每个模块之间资源隔离。
Spark集群采用standalone方式部署,便于集群的扩容。当需要对集群扩容时,只需要
增加一个 worker 节点并指向 master,同时将 Handle-server 以 client 方式提交至集群即
可。当集群需要缩容时,直接停止需要裁撤掉的worker即可
十三、 全套服务
部署架构和软件模块如下简图,其中浅黄底必须安装,浅蓝色为为可选配模块。
1. SQL Engine/DB:可以混合部署在同一物理机中,也可分离部署;此模块对CPU和磁盘性能要求较高,建议采用较高配置的CPU和SSD存储,并考虑高可用2台起部署。
2. 赤兔运营系统:可部署在虚拟机或物理机中,建议为1/3/5等基数台部署。
3. 负载均衡模块:提供虚拟IP,数据库负载;目前支持LVS、腾讯云网关TGW、腾讯私有网络VPC等开源或商用负载;
说明:如果不安装负载均衡模块,业务可以通过访问SQL Engine的IP和端口访问数据库,并通过连接池管理与多个SQL Engine的连接。
4. 云数据库管理系统:云数据库管理系统需与腾讯专有云 TCE合并安装。用于提供类似于集团云、行业云、政务云等场景下的租户端使用。
说明: 云数据库管理系统的部署依赖于赤兔运营系统。
5. 数据备份系统:目前可以支持分布式文件存储系统 HDFS,腾讯云对象存储 COS,网络存储NAS等。
说明:如果不安装数据备份模块,将影响数据库备份、恢复与回档、备份与日志下载等功能。
6. OLAP扩展:指分析型数据库扩展,通常需要3台物理机起。
说明:OLAP的部署依赖于SQL Engine/DB模块的部署。
7. 支撑组件:指数据库审计、数据同步等其他功能,若不安装不影响数据库核心功能。具体需求请咨询腾讯相关工作人员