首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度解析:腾讯云分布式数据库 DCDB

深度解析:腾讯云分布式数据库 DCDB

原创
作者头像
腾讯云数据库团队
修改2017-07-17 10:51:18
6.6K1
修改2017-07-17 10:51:18
举报

这些问题,腾讯全部遇到过

我们知道,集中式(单机)数据库在存储容量、并发性能、快速扩容等都会因业务增长而达到瓶颈。而在业务发展初期,团队很难准确预测数据库增长的速度和规模,只有靠拍脑袋确定规模进行设备选型:

  • 若达不到预期,会导致资源浪费;
  • 若超过预期,则会出现扩展难题;
  • 若成为行业领先,那么性能瓶颈又摆在了面前。
  • 还有集中式数据库一系列容灾、恢复、管理等一系列问题,都让人糟心。

多数情况下,互联网业务往往都会超出预期,随之而来的问题就令人头疼了。为解决上述问题,腾讯数据库团队曾经选择多种方向,也考察过商业数据库基于共享存储的体系架构(RAC)。我们发现,RAC架构无法通过增加计算节点来“线性的”提升数据库集群性能,因为共享存储的体系架构中多个节点对同一个数据块有对等访问权限,这就意味着所有数据都是全局资源,任何节点在操作数据时必须加锁以防止其它节点的干扰,为了协调节点间的访问,就必须通过密集的消息通信来传递资源锁。在传统企业IT(内部ERP、OA)等系统上,这样的问题并不明显;然而当其面对的是互联网海量处理应用是,这种资源锁机制严重限制了RAC架构的扩展能力。其次,从运营成本角度上讲,商业数据库高昂的授权费用、昂贵的硬件成本,都制约了业务的快速发展。因此,腾讯最终选择了分布式数据库方案。

时至今日,放眼互联网行业,排名靠前企业的核心业务都在使用分布式数据库,我们不禁要问,这其中有什么秘密?

分布式数据库为什么能解决容量、并发、扩展等难题

了解分布式数据库,需要先了解垂直切分(分库)、水平切分(分表)两种方案:

  • 垂直切分(通常也叫做“分库”)也就是按功能切分数据库,这种切分方法跟业务紧密相关,实施思路也比较直接,比如“京东JD”等电商平台,一个原有一个数据库实例,按功能切分为会员数据库、商品数据库、交易数据库、物流数据库等多个数据库实例,共同承担业务压力。有时候,垂直拆分并不能彻底解决压力问题,因为单台数据库服务器的负载和容量也是有限的,随着业务发展势必也会成为瓶颈,解决这些问题的常见方案就是水平切分了。
  • 水平切分(又叫做“分表”)是按照某种规则,将一个表的数据分散到多个物理独立的数据库服务器中,这些“独立”的数据库“分片”;多个分片组成一个逻辑完整的数据库实例。一般来说,分表的前提是分库。

水平拆分的方案,实际上是分布式数据库的基础原理,他的每个节点都参与计算和数据存储,而且每个节点都仅计算和存储一部分数据。因此,无论业务的规模如何增长,我们仅需要在分布式集群中不断的添加设备,用新设备去应对增长的计算和存储需要就够了。

腾讯云分布式数据库DCDB

腾讯云分布式数据库(DCDB)是部署在腾讯云上的一种,面向OLTP业务支持自动水平拆分(分表)的share nothing架构的分布式数据库。DCDB也是随着腾讯业务规模不断扩大而发展起来的,从2004年开始,腾讯部分业务就已经开始遇到单机数据库架构已经无法支撑,进而开始研究分布式架构,业务发展最终推动了数据库架构技术的不断革新,面对日益复杂的需求。截止到2017年,包括微信支付,腾讯充值,阅文集团等腾讯公司交易、转账等核心系统90%以上都使用了腾讯分布式数据库(DCDB)。

DCDB的前身是腾讯自研TDSQL,我们的设计理念是淡化复杂的拆分、扩展等逻辑,让开发者使用DCDB就像使用集中式单机数据库一样顺利

当前,DCDB已支持MySQL 5.7、5.6(基于Percona、MariaDB分支),未来计划进一步支持PostgreSQL引擎(基于腾讯自研PostgreSQL-XZ分布式引擎)等。

DCDB整个集群架构简图如下图,这种集群架构极大简化了各个节点之间的通信机制,也简化了对于硬件的需求,这就意味着即使是简单的x86服务器,也可以搭建出类似于小型机、共享存储等一样稳定可靠的数据库。

大多数情况下,可以用您熟悉的对象映射框架使用DCDB。对于分表,建议您尽量使用基础的SQL语句,因为这样能达到最佳性能,特别是几亿甚至几百亿条记录的情况下。这意味着,某些情况下,您可能需要一定的改造,才可以接入DCDB。

分布式数据库DCDB的分表方案

关系型数据库是一个二维模型,数据的切分通常就需要找到一个分表字段(shardkey)以确定拆分维度,再通过定义规则来实现数据库的拆分。业内的几种常见的分表规则如下:

  • 基于日期顺序(Time),如按年拆分,2015年一个分表,2016年一个分表。
  • 基于某字段划分范围(Range),如按用户ID划分,0~1000一个分表,1001~2000一个分表。
  • 基于某字段求模(HASH),将求模后的值,再按Range方式分散到不同库中。

无论是Time、Range都有个主要缺点就是可能导致严重数据倾斜,即多个物理节点(又叫做分片)之间负载和数据容量严重不均衡。在大部分数据库系统中,数据都有明显的冷热特征——显然当前的订单被访问的概率比半年前的订单要高的多(更热)——而采用Time分表或range分表,就意味大部分热数据将会被路由在少数几个分表中,而存储冷数据的设备性能却被浪费掉了。

因此,DCDB通常采用某个字段求模(HASH)的方案进行分表,而计算HASH的某个字段就叫做shardkey。因为HASH算法本身就能够基本保证数据相对均匀的分散在不同的物理设备中(某些特殊情况下除外,我们将在后续章节进行介绍)。

HASH的过程大致就是,当某条记录(SQL)请求时被发起时,DCDB 会理解 SQL 语句的含义,然后按照拆分键的值和执行策略将 SQL 路由到对应分表进行执行,如下图所示,先通过hash算法计算,再路由到各个节点上。

而如果一个查询 SQL 语句的数据涉及到多个分表,此时SQL会被路由到多个分表执行,DCDB 会将各个分表返回的数据按照原始 SQL 语义进行合并,并将最终结果返回给用户。

读取数据时(如果有明确shardkey值):

  1. 业务发送select请求中含有shardkey时,网关通过对shardkey进行hash
  2. 不同的hash值范围对应不同的分表
  3. 数据根据分表算法,将数据从对应的分表中取出

读取数据时(如果没有明确shardkey值):

  1. 业务发送select请求没有shardkey时,将请求发往所有分表
  2. 各个分表查询自身内容,发回Proxy;
  3. Proxy根据SQL规则,对数据进行聚合,再答复给网关

从上述原理来看,查询SQL中含有shardkey值比不含shardkey值效率将会更高。

如何选择拆分键

拆分键是在水平拆分过程中用于生成拆分规则的数据表字段,必须在建表时就指定好。DCDB建议拆分键要尽可能找到数据表中的数据在业务逻辑上的主体,并确定大部分(或核心的)数据库操作都是围绕这个主体的数据进行,然后可使用该主体对应的字段作为拆分键进行分表,该分表方案通常叫做groupshard(按组分表),如下图:

Groupshard方案,可以确保不同分表的某些关联数据和复杂的业务逻辑运算,可以聚合到一个物理分片内,进而减轻分布式数据库本身一些使用缺陷。例如,某电商平台订单表和用户表都是基于用户维度(UserID)拆分,平台就可以很容易的通过联合查询(不会存在跨节点join,或分布式事务)快速计算某个用户近期产生了多少订单。 下面的一些典型选择拆分键的应用场景:

  • 面向用户的互联网应用,都是围绕用户维度来做各种操作,那么业务逻辑主体就是用户,可使用用户对应的字段作为拆分键;
  • 电商应用或O2O应用,都是围绕卖家/买家维度来进行各种操作,那么业务逻辑主体就是卖家/买家,可使用卖家/买家对应的字段作为拆分键;但请注意,某些情况下几个超大卖家占到绝大多数交易额,这种情况会导致某几个分片的负载和压力明显高于其他分片,我们会在后面章节予以说明。
  • 游戏类的应用,是围绕玩家维度来做各种操作,那么业务逻辑主体就是玩家,可使用玩家对应的字段作为拆分键;
  • 物联网方面的应用,则是基于物联信息进行操作,那么业务逻辑主体就是传感器/SIM卡,可使用传感器、独立设备、SIM卡的IMEI作为对应的字段作为拆分键;
  • 税务/工商类/社保的应用,主要是基于纳税人/法人/居民的信息来开展前台业务,那么业务逻辑主体就是纳税人/法人,可使用纳税人/法人对应的字段作为拆分键。
  • 以此类推,其它类型的应用场景,大多也能找到合适的业务逻辑主体作为拆分键的选择。

拆分键的限制 为了提高语法解析效率,避免因为shardkey设置导致路由错误,DCDB规定了拆分键设定的技术限制(请参考腾讯云官方文档):

  1. 如存在主键或者唯一索引,则shardkey字段必须是主键以及所有唯一索引的一部分;
  2. shardkey字段的类型必须是int,bigint,smallint,char,varchar;
  3. shardkey字段的值尽量使用ascii码,网关不会转换字符集,所以不同字符集可能会路由到不同的分区(且尽量不要有中文);
  4. 不能update shardkey字段的值,如必须则先delete,再insert;
  5. shardkey= 放在create语句的最后面,如下示例:
mysql> create table test.right ( a int not null,b int not null, c char(20) not null,primary key(a,b) ,unique key(a,c)) shardkey=a; Query OK, 0 rows affected (0.12 sec) 

6. 访问数据尽量都能带上shardkey字段,可以极大的提升效率;

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 这些问题,腾讯全部遇到过
  • 分布式数据库为什么能解决容量、并发、扩展等难题
  • 腾讯云分布式数据库DCDB
  • 分布式数据库DCDB的分表方案
  • 如何选择拆分键
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档