什么数据库可以撑起微信支付每天数亿笔交易?
本文作者:李跃森
大家好,我是李跃森,目前负责腾讯云TBase数据库研发的相关工作。今天跟大家分享的内容主要分为两大章节:第一章,数据库技术的基本概念和基本架构;第二章,TBase产品的典型案例,以及在国产化上我们所做的具体工作。
数据库产品分类
首先,我们来看一下数据库的分类。数据库分类有多种方式,接下来会介绍三种分类。
一、按照数据库的业务场景划分
一般我们在谈论数据库的时候,首先会问数据库是OLAP还是OLTP?
OLAP,即在线分析型处理,这一块其实是按照业务特点来划分的。OLAP的第一个特点是数据量比较大,一般会要求PB级或者更大的数据量,数据量大了以后,对存储的成本会比较敏感,对数据压缩也会有一定的要求,OLAP业务系统的并发量不会特别的高。另外,OLAP场景下查询一般都会比较复杂,每个查询需要消耗大量的资源,会要求多个用户之间的查询要减少相互之间的影响,进行资源隔离。类似产品还是比较多的,比如:TeraData、SybaseIQ、GreenPlum、HP Vetica、 Gauss200、 VectorWise、AWS Redshift,以及现在比较流行的ClickHouse等。
OLTP,即在线事务型处理。在线事务处理数据量相对较小,普遍时延要求较高,要求达到毫秒级。在吞吐量这一块,普遍要求能够达到百万级以上的TPS。OLTP业务系统都是我们核心的业务系统,包括银行、保险、电信这样的实时在线的业务,业务特点决定对容灾能力有一些突出的要求,一般来讲要求99.99%以上的可靠性。传统上来讲,我们一般讲数据库都是指:Oracle、IBM DB2、Informix、MySQL,以及PostgreSQL这样的一些数据库。
这两年还兴起一个数据库概念叫做HTAP,即混合事务处理和在线分析型数据库。基本的思路是能够在单集群内部同时处理OLAP和OLTP两类业务,而且OLAP和OLTP业务之间有良好的资源隔离。典型产品这两年宣传的比较多的如TiDB,包括TBase设计之初也是这么考虑的。
二、按照时间划分
现在我们一般会讲Old SQL,这个所谓的Old SQL是指传统的SQL数据库。此类数据库的典型特点:它是一个完整的关系模型,具备完整的事务能力。像Oracle、IBM DB2、MySQL、PostgreSQL这些是传统的数据库。
在2010年前后,No SQL数据库在互联网中大量兴起,泛指一些非关系型数据库,主要特点是没有完整的事务支持,而且没有模式的概念,普遍采用无共享架构,根据业务进行分区。另外在复制这一块,使用异步复制,保持最终的一致性。典型产品包括Redis、HBase、MongoDB等。
最近这两年,结合上面的Old SQL和No SQL的概念,又提出了一个New SQL的概念, New SQL其实是结合了Old SQL和No SQL的概念,它既具备了No SQL的便利性,又能够支持传统数据库数据库架构,但是New SQL在关系模型的完整性上存在一些问题。
三、按照架构
数据库的划分经过多年的演进,大概有三种架构。
第一种是单体数据库,所谓单体数据库就像之前我们经常提到的Oracle、PostgreSQL、MySQL这种单机的数据库,单个实例能够提供独立的服务,主备机通过流复制来做HA,这是传统的架构。
第二种是共享存储架构,多个数据库实例同时访问一份存储,数据是存储在专门的存储设备中,这里的存储设备一般是指磁盘阵列或者类似于这样专用的存储设备,现在我们能看得到的包括Oracle RAC、SybaseIQ都是这样的架构。
第三种是无共享,也就是我们常说的MPP。每个DN节点存储一个数据分片,在DN节点之上会有另外一层节点,这层节点在不同的数据库中有不同的名字,但是它的作用其实是一样的,都是接收业务请求,然后分发,同时对业务请求进行返回。TeraData、GreenPlum、TBase、TDSQL、TiDB都是属于这种架构。
随着云业务形态的诞生,这两年在传统的数据库架构基础上,产生一种比较流行的新架构——云原生架构,日志即数据库。
它会把数据库的业务逻辑沉到底层的存储节点里面去,存储节点和上面的计算节点是进行逻辑上的分离,其实也就是物理上的分离,另外一种叫法是计算与存储分离。在下层的存储集群之间,通过一致性协议来保证多个副本之间的一致性,统一对上层的数据节点提供一个可靠的存储服务。这里补充说明下:数据库节点就是把数据库的业务逻辑,包括SQL解析及SQL的执行都做到上层去。类似的产品现在也比较多,基本上几个大的云厂商都有自己的产品。主要有两个技术优点,1、可以做到存储计算分离,存储和计算可以做到单独扩容,2、它可以实现存储的超卖,这在云上这是一个比较有价值的能力。
这里给大家重点介绍一下PostgreSQL数据库,如果是在十年以前提到PostgreSQL,大家可能都会一脸懵。经过这几年国内PostgreSQL社区的推广,PostgreSQL的认可度已经高了很多。
它是由图灵奖得主石破天主导的一个项目,以BSD风格协议开源。PostgreSQL的好处是源代码可以随意的修改和发布,甚至可以用来盈利。PostgreSQL在网站上声称是最先进的开源数据库,经过这么多年的发展,PostgreSQL的整个功能上距离商业数据库Oracle确实越来越近,作为开源产品也具备了一些Oracle不具备的灵活性和扩展能力。最近几年社区发布版本的速度是越来越快,技术思路逐渐向商业数据库靠近,相信后面会有越来越多的业务跑在PostgreSQL上。
很多人都问MySQL和PostgreSQL两个之间有什么区别。这边简单列举了一下它们的区别。
接下来跟大家分享下TBase的整体情况,先从TBase的简史说起。
TBase是基于PostgreSQL研发的一个分布式数据库,最早可以追溯到2009年。当时是拿PostgreSQL来作为我们内部数仓的补充,支撑小数据量的分析。2014年开发了TBase第一个版本,内部开始使用。2015年TBase在微信支付商户集群里面上线后。到了2018年,发布了TBase V2,在数字广东和云南公安上线。2019年发布了TBase的V3版本。
数据库核心技术选型
在讲架构设计之前,先来看一下TBase面临的业务场景。
TBase的整体物理架构,跟前面提到的架构是比较类似的。
TBase整体物理架构分三个部分,图中的左侧上层GTM是事务管理器,它主要是提供全局事务的信息,同时管理全局对象。另外图中右侧上层Coordinator(协调节点CN),它主要提供业务访问入口。协调节点中每个节点之间是对等的,也就是说业务访问这三个节点里面的任何一个,它得到的结果都会是相同的,而且访问这个节点,事务的一致性能够得到保证。图中中层是集群数据交互总线,把整个数据库集群的各种连接到了一起。图中下层是数据节点,数据节点有些是我们实际存储数据的地方。每个数据节点会存储一份本地的Local元数据,同时还有本地的数据分片。
接下来给大家详细分享下TBase是怎么做的,重点分享架构设计思路。
讲分布式事务之前首先讲下Sharding模式存在的问题。这里举个例子,我们现在有AB两个帐户,每个帐户余额是10元,两个帐户总额是20元,我们对这两个帐户之间进行转帐,从B往A转5元,并发量很大的时候,如果是一个一致性保持的比较好的系统,那么无论我们有多少的并发,两个帐户的总额应该总是20元。
在sharding模式下,事务3和事务4存在严重的事务不一致问题。那为什么很多业务系统中用了sharding的模式,却没有这类问题呢。主要的原因是大多数使用以上模式的业务都是互联网公司的业务,互联网公司的开发团队有比较强的开发能力,可以让业务代码处理上面遇到的问题,把数据库作为一个简单的数据容器来处理。但对于一些普通用户或者普通场景的话,就不一定具备互联网公司的资源和技术能力了。在TBase中,我们也是需要处理分布式事务的一致性问题,为业务屏蔽掉事务的相关细节。
这里我分享下TBase分布式事务系统的目标。
首先在保证分布式事务完整性的基础上能够提供高性能、低延时、高吞吐的事务能力,并尽量使用低成本的硬件来达成我们的目标。同时,也希望在保证这三者的基础上,我们事务的处理能力能够随着集群的规模近似线性的增加,提供事务处理能力的扩展性,提供包括死锁检测和事务故障恢复等事务保障能力。
在开始介绍TBase事务模型之前,先来看一下现在大家常用的分布式事务模型。
一、分布式的快照隔离
可以简单理解是PostgreSQL使用的MVCC的分布式的实现,这里面主要分几个部分。
在GTM上,要求维护一个开放的事务列表,事务列表指的是当前这个集群里面正在运行的一些事务。举个例子,如果说我当前启动一个新的事务,然后我就会把它加到这个列表里面来。如果这个事务结束了,这个事务列表就会把这个xid从事务列表拿掉。客户端在跑一个SQL的时候,都会要求从GTM上拉取一个事务的快照,所谓的事务快照是将当前这个事务列表里面的一个拷贝,发到我们的DN上做活跃事务的判断。这里有以下3个问题:
问题1:这个活跃事务列表是一个O(N)的长度,也就是说它和当前事务并发的个数是呈正比方式的,有多少个并发的事务在跑,这个事务的列表就有多长。
问题2:刚才也提到我们每个客户端在访问SQL的时候需要从服务器去拉取一个快照到本地去,这样的话也就是说对GTM的网络占用的比例是N的平方,也就是N的平方乘以M,M是SQL的个数。
问题3:刚才也提到了,事务列表是全局资源,不管是事务的启动还是提交,甚至获取快照都需要对这个列表进行加速。这样的话,基本上来讲我们是在系统里面增加了一个全局的大锁,这个大锁就会成为这个系统的一个扩展的瓶颈。
二、基于物理时间的并发控制
基于物理时间有两种方式:
第一种方式是Google spanner中采用的方式,这个分布式系统要求提供一个全球分布式的一个分布式数据库,达到百万级的数据库节点。基于全局时间快照的进行并发控制,它的全局时间快照使用的是GPS和原子钟一起生成。全局时间版本,这个东西有一个6毫秒左右的误差。也就是说它的一个事务在运行的时候,最低延时就是6毫秒。第二个问题是成本比较高,需要专用硬件,每个IDC都需要有自己的原子钟和GPS设备。
第二种方式是CockRoachDB,其实是Google Spanner的变种。主要的区别是它使用的是本地的时间来进行控制,严格意义上讲应该是混合时钟。相比之下成本会比较低廉,并且没有中心节点。但是NTP精度会影响事务的时延。
三、基于逻辑时间的并发控制
现在大家讨论的比较多的是基于逻辑时间的并发控制。
用一个TSO集群提供集群的逻辑时间戳作为版本号。这个事务模型相对来讲就没有之前提到的那几个版本控制的问题。里面会把当前事务里面进行的所有的修改记录都记录下来,在事务提交的时候一次提交,也就是说它是一个O(N)的动作,N指的是我们在这个事务里面修改了所有的记录的集合。而且这个过程中集群会加锁,阻塞后面的写入。
这里重点介绍TBase这一块,TBase的并发控制,全局事务的一个控制其实是结合了最早提到的分布式快照隔离一起做的一个隔离模型。
核心部分是GTS集群,GTS集群和TSO的功能很像,也使用了逻辑时间戳的概念,这个时间戳的基线是我们自己定义的一个开始的点,单向递增。
我们自己内部定义了MVCC机制原理,对于当前事务,记录的gts_min已经提交,而且事务的gts小于记录的gts_max,我们才能看到这条记录。
GTS是从0开始的一个单向递增的逻辑时钟源,通过硬件提供足够的稳定性保证,保证不发生偏斜。同时,GTS本身通过流复制的方式来保证自己的可靠性。性能方面,一般普通24 core的服务器可以达到1200万的QPS,几乎可以满足所有业务场景的需要。
下面分享一下TBase在行存储和列存储这一块的一个选择。
行存储的话,顾名思义,是按行存储。也就是说在磁盘存储的时候,我们像上面的表一样,我们存储的时候是先存储完第一行,然后存储第二行,再存储第三行,再第四行,这样紧密存储。这个好处在于:每次IO的时候,可以把一行记录的所有的列都能够读到这里面去,适合OLTP场景。
另外一个是按列存储,我们把同一列的数据连续存储在一起。比如:蜘蛛侠、超人、火箭浣熊、闪电侠这一列在磁盘上面,第二列是另外一个文件,这种存储的好处在于:每次IO的时候,只会读取同一列的数据,可以大大的提升聚合操作处理的效率,比较适合OLAP的场景。
在分布式场景下,我们不得不考虑另外一个问题,除了选择的行列之外,还要考虑我的数据在集群里面如何存储,也就是怎么把数据分片存在我们的分布式集群里面去,TBase里面叫选择表的分布类型。
第一种是复制表,有的地方叫快表,在集群里面的指定节点上,每个节点都会有数据的完整副本,这样的表特别适合一些变化比较小的小表,对于一些关联插件的加速是比较有用的。
第二种是大家比较常见的是HASH分布,就是把数据打散到不同的存储节点上去,明显的问题是HASH倾斜。
第三种也是比较常见的方式RANGE分布,即按照数据的范围来进行分布。其实在分布式场景中,除了这种我们可以指定具体的算法进行分布的方式之外的,还有就是在数据仓库里面比较常用的随机分布,不用任何算法来进行分散,把数据全部打散到整个集群中去。TBase的分布方式主要有复制表和HASH分布两种。
关于分布式查询的执行方式,在MPP这种架构下每个DN的数据都是不完整的。为了完成一个完整的分布式查询,有一些策略需要选择。如果是一些单点的查询就无所谓,比较难搞的是分布式的JOIN。
这里面的策略主要有两种,一种是所谓的PUSH QUERY,通过把它的查询下推到DN节点上去, SQL在DN上执行,把数据返回给CN。另外一种方式就是PULL DATA,也就是通过把DN节点上的数据拉取到CN上通过CN来完成所有的计算。数据量较大的时候, PUSH QUERY效率会高很多,PULL DATA在一些数据量比较小的时候,效率会比较好。TBase里面两种方式都会有,我们也会选择PUSH QUERY或者PULL DATA,至于选择哪种是根据我们的优化器来选择。
分布式执行在 SQL shipping还是PLAN shipping之前该如何选择?
SQL shipping是指我们在PUSH QUERY的时候是PUSH SQL,DN完成SQL解析和优化执行。这种场模式不适合复杂SQL的执行,但架构相对比较简单,易开发易维护。所谓的PLAN shipping是在CN节点上生成整个执行计划,CN节点再根据我们的统计信息和数据分布来生成计划的分片,再把这个下推到各个DN节点上去,这个时候DN节点就不会进行二次解析,拿到执行计划并返回结果。这种方式优点其实比较明显的,它对SQL的优化能力是比较强的,能够在一些特别复杂条件的时候,效率会比较好。不过缺点比较明显,对于一些数据量不大的场景,执行计划的解析和下发花了很多的时间,导致简单查询的时候,小数据量查询效率不高。在TBase中,我们会根据我们业务的特点和数据的特点来选择两种中的任何一个,也就是说TBase两个都是支持的。
在执行计划生成层面,我们生成执行计划的策略有两种。
第一种是规则优化(RBO),即 RULE BASED OPTIMIZER,顾名思义就是在生成执行计划的时候,是根据SQL的模式,遇到了什么条件,就生成什么样的执行计划给它。这种方式其实在实践起来比较简单,某些方面比较高效,缺点是弹性不足,对一些复杂场景,它很难去应对,没有足够的弹性。
第二种是代价优化(CBO),即COST BASED OPTIMIZER,这是用的比较多的主流优化方式。它主要会从目标SQL诸多可能的执行路径中选择成本比较小的一条作为执行计划,成本值是根据目标SQL语句所涉及到的表、索引、列等相关对象的统计信息算出来的。它的适用性会比较好,特别适合一些复杂的场景,而且在一些复杂场景下会性能表现比较稳定。缺点是复杂度比较高的,有一定的前置条件,包括我们统计信息的准确度,代价计算模型的一个精确度。TBase来讲的话,两块都会有,更多的会偏向于后面的代价优化(CBO)。
TBase在整个设计分布式执行方式的时候,我们有一个很明确的目标:希望业务的SQL不需要感知集群结构,它可以像使用单机的数据库一样来使用TBase。
也就是说客户和业务在使用TBase的时候,他不用考虑分库分表的问题,也不用考虑这个集群里面有多少个节点,SQL是怎么写的,他就可以像使用普通的单机的数据库一样来使用TBase。为了达成这个目标,我们使用了前面我们讲到的各种各样能够帮助我们解决问题的技术。比如说我们在进行查询优化的的时候,如果发现表这一列都是按照分布列来进行查询的,就走规则的优化,查询直接下推;如果我们不是按照分布列来进行查询的,是按照表A是分布列,表B是非分布列,这个时候进行查询的时候就会根据代价来进行判断。如果这个表B足够小的话,会通过广播的方式,把表B在每个节点上都形成一个完美的副本,拿表A进行查询。如果表A和表B都很大,这个时候我们就会选择一个成本相对比较低的表来进行重分布,选择的方式是表B。假如说表B相对于表A要小一点,按照表B来进行重分布,来完成整个查询。这个用在上面,我提到了包括redistribution和replication,还有push down。后面两个我们push的是PLAN。
在TBase里面,在MPP的架构下,我们具备了并行计算的架构基础。
全并行大概分几级,其中第一级是节点级的,也就是说一个SQL来了之后,我们会把这个查询的同时发给三个节点,三个节点同时开始计算。然后在节点内部的话,我们会进行算子级的并行。比如说进行一个Hash JOIN,我们会多进程的完成这样一个Hash JOIN的过程。在每一步计算的过程中,还会使用指令级的SIMD的一些指令来加速。这样其实做到了从节点级到进程级以及指令级的一个并行。
前面介绍了我们对性能进行优化的方式,这里讲一下数据库常见的容灾方式。
数据库容灾方式大概分几种:
第一种是我们传统单机数据库,包括MySQL、PG、ORACLE,常规的这种容灾方式也是通过流复制的方式,流复制的基础是基于日志,或者是基于数据块。复制方式有同步复制和异步复制,所谓同步复制是等主机返回请求之前一定要等到备机的日志可靠落地之后,它才会返回成功给客户端。异步的话是主机事务日志落盘后,异步把日志发送到备机,不用等待备机事务的可靠落盘。同步和异步对外体现的主要是业务的RTO、RPO的影响。这种方式一般来讲下,我们在主机上提供读写能力,在备机上提供只读能力。
第二种容灾方式大家看到的比较多,主要是使用一致性协议来复制日志,也就是说每个写入请求来的时候,它都会通过一致性协议进行集群内部的协商来达成最终的一致。这样的架构的好处是每个副本都可以写入,但缺点也比较明显,每个写入都需要经过若干次的网络同步,效率其实要比基于流复制的容灾方式弱一些。因为它的每个副本都有完整的一个数据,而且都可以进行导换,所以它的RTO表现会好一点。从这里其实我们可以看出来,数据库容灾的本质其实就是数据的多副本,各种方案的区别主要是在于多副本我们是怎么实现的。TBase多副本实现没有使用一致性协议。
接下来给大家介绍下TBase运维管控架构,TBase作为一个分布式系统,整体的架构是比较复杂。
我们需要一个运维管控系统来保证整个系统的可靠运行和高效的运维。整个TBase的运维管控系统如图所示,图中最上层是ETCD集群,即TBase的元数据管控集群。另外它提供一些控制中心的选主的能力。第二层是运维管控中心,它实时的监控集群的状态,同时这里也可以去触发一些故障处理逻辑。第三层是数据探活集群,这一层主要是有部署在每台服务器上的Agent来完成,它会实时的去探测每个数据库实例的健康度并进行上报,同时它也会执行上层的运维管控中心下发的一些指令。最下层是数据库实例,这一层其实是通过资源池化的方式来进行资源隔离,同时内部也进行了一些容灾的控制。
这里我提一下数据库里面比较重要的备份问题。我们为什么要进行冷备?
前一段时间发生的数据冷备被删除,导致业务中断估计大家还有印象。所谓的冷备其实也是数据库安全的最后一套防线,我们一般什么时候用到冷备呢?经常是在发生重大的误操作的时候,比如说我不小心把库删了,或者说整个机房所有的副本都挂了,另外如果说数据做了恶意的修改或者篡改之后,需要把数据恢复到一定时间以前的数据,冷备是数据库的最后一个保护伞,对数据库来讲是非常重要的。
冷备可能会存在的一些问题。
分布式场景下数据库的冷备存在的问题和分布式事务存在的问题是很类似的。我们集群内部会有多个节点在并行跑事务,最难搞的问题是在分布式冷备系统中如何找到一致性的恢复点。如图,集群里有两个节点DB1和DB2,冷备点1和4的,恢复就是一致的。冷备点2和冷备点3就是不一致的。整体一致点的选择非常重要。如果选择不当就会造成数据的损失和不一致。
分布式数据库里面,如何寻找一致的冷备点也有一些方法可以参考。
第一种是要求在做冷备的时候,通过设置事务栅栏来保证整个事务的一致性,我们会在所有的日志里面设置一致性标签,然后恢复的时候,指令说恢复这个标签就停下来,这样可以保证整个事务的一致性。但是这里有一个缺点,在进行一致创建的时候,必须得去阻塞或者延迟当前事务的执行,对系统的影响其实还是比较大的。TBase是通过时间戳的方式,每个事务都有一个时间戳,那么在选择冷备点的时候,就可以决定说要恢复到某个具体的时间戳,通过事务的时间戳我们就可以很好的保证整个冷备恢复的一致性。
前面介绍了TBase在执行和冷备及可靠性分析的设计,接下来介绍下TBase特有的安全能力,在支撑公司业务过程中摸索出来的一套比较有效的数据安全管理体系,我们管它叫MLS(multiple layer security)。
这个数据安全体系的基础是三权分立,所谓的三权分立指的是:安全管理员、审计管理员、数据管理员三个角色在系统里面相互隔离。安全管理员主要是负责安全规则的制定;审计管理员主要负责审计规则的制定;数据管理员更多的相当于我们之前的DBA的一个角色。这三个角色之间在权限上和能力上来讲是完全隔离的,相互之间在功能上没有交叉。安全管理员的安全规则会约束到审计管理员和数据管理员,然后审计管理员的审计规则会约束到安全管理员和数据管理员。接下来给大家分别介绍下:TBase的行级强制安全规则、列级的安全规则、数据脱敏和加密。
1、TBase的行级强制安全规则
行级安全规则保证在TBase中我们可以做到数据行级安全的权限控制。安全规则三元组:一个是level(安全级别),这个安全级别是从上往下兼容,也就是说我如果具有绝密级别的安全权限的话,我就可以获取到机密、保密和公开级别的数据的一个访问权限。第二个是Catalog/compartment(目录控制Catalog/compartment,这是一个集合的概念。也就是说如果有了α、β和∑这三个对象整体的权限的话,我就可以单独的去访问只有α或者β或者∑其中一个或者几个组合的数据。最后一个是Group(组),这个概念比较容易理解,类似于公司组织关系,上级节点具有下级节点的权限。
举个例子,比如说上图中的右边是我们的数据,左边是我们的用户。
成都分公司总经理能够从级别这里看到所有的数据。但是他在目录这个级别的话,他只能看到成都的机密级别以下的数据。同时,因为他的组里面有工程部和人力资源部,他只有这两个,也就是说他能够看到工程部和人力资源部的成都的数据。对于总部的人力资源总经理的话,我们就会发现他能看到北京和成都的,也就是说能看到所有归属地的员工的人力资源里面的数据。对于董事长来讲,一般董事长的级别能够看到所有的安全级别的数据,他能看到北京和成都两地的数据。在组的关系上来讲,董事局一般是整个公司部门里面最高级的部门,所以他在组这个级别上,他就能看到他下属所有部门的数据,也就是说对钢铁侠来讲,他能看到整个公司全部的数据。通过这个安全规则我们就可以做到对数据做到行级的过滤、行级的保护。
2、TBase的列级安全规则
在TBase中是通过访问控制列表来实现的,也就是说我们会在每一个列上加一个ACL的列表来指定这一列对谁有权限,谁没有权限。
比如:我们在薪酬上设定说普通员工是没有权限访问,对蜘蛛侠或者普通员工来讲的话,他看到的数据就只有他自己的数据。但是对于钢铁侠来讲,因为钢铁侠是董事局的主席,他能看到这两列所有的数据。通过行级权限控制和列级权限控制可以得出我们对表里面的数据能够做到行和列的任意访问的控制。
3、TBase数据脱敏和加密
脱敏和加密面对的场景有一些差别,加密主要面对的是数据文件本身的泄露,比如我的文件被别人拖走了,然后他通过代码可以把数据解析出来。我们现在常见的数据库的存储格式基本上来讲是属于半公开的状态。也就是说大家只要拿到了数据库的数据文件,只要有一个数据程序就可以把它解析出来,我们要通过数据中心的加密防止泄露。脱敏主要指的是我的数据在访问的时候,有些数据的用户是没有权限去看到它的明文的,但是它还用一些运维的操作或者其他一些工作上的需要,他需要能访问这些数据,但是他不需要真正看到这些数据,这两个是完全不同的需求。加密在存储层的时候,存储的是密文,只有在执行这个程序的时候才会对数据进行解密和加密,然后把它反馈给用户。对于脱敏的话,存储的是明文,在buffer里面也是明文,只有在用户访问的时候,我们授权用户、非授权用户来进行公平的处理。对授权用户得到的就是完整的数据,对非授权用户得到的数据就是脱敏以后的结果。加密和脱敏可以进行混合的使用,也就是说我们既可以对存储内容加密,也可以针对不同用户采用用户的一个脱敏的规则,来保证我数据访问的一个隔离。
下面针对TBase MLS透明脱敏和透明加密举个例子。
我们有两个脱敏和加密的规则,也就是说我们会针对非董事长用户进行加密的脱敏。脱敏之后的数据,我们可以指定一个任意的值来展示给这个非授权用户。现在我们对于这个非授权用户,也就是说对于成都的分公司总经理和总部人力资源总经理,他们看到这两个数据,一个是0,一个是1。但是对于董事长来讲,因为他是超级用户,他是没有受到加密和脱敏的约束的,所以他看到的数据是正常的数据。通过这种方式我们就可以很好的来隔离系统里面不同等级用户对于同样一些数据看到的视图,达到一个隔离的效果。
另外,跟大家分享下TBase MLS的审计能力。
TBase具备完整的审计能力:1、语句审计,对特定的语句类型进行审计;2、对象审计,可以针对数据库的某个对象,比如说一张表,或者一个数据库,甚至一个索引来进行一个审计。3、记录用户审计,记录用户所有的访问。4、还有一个比较好玩儿的功能是TBase的一个系统的审计,我们可以做一些针对用户自定义的审计规则,比如审计的时候,我们判断如果用户的余额大于这个值的时候,我们就会把它的审计结果记录下来。同时我们还会自定义它的审计的一个动作,也就是说如果这个条件被触发了之后,我们会去做什么事情。比如说上面这个例子是我们会调用一个发文件的功能来做我们的审计。
TBase客户案例
下面介绍一下TBase的客户案例。
TBase最早是在2016年初的时候替换了微信支付原有的分库分表的MySQL集群。当时大概每天只有500万笔,后来支撑到每天数亿笔。整个过程中我们保证了微信支付业务的连续性和稳定性。
主要有几个策略:
第一个是大小商户策略。微信商户系统,商户业务不同于个人业务,存在大商户和小商户的区别。大商户像大型的网购平台,还有电商平台,它都属于大商户。小商户就是各种各样的小店,他们的数据量不一样的,所以我们需要对于不同的用户量来进行一个处理,来保证两边服务的质量。
第二个是冷热分离的策略,因为对于微信支付的系统来讲的话,它的冷热存活都是我们的订单数据,都是跟钱相关的东西。这一块来讲的话,跟我们相关法律的要求,这些数据我们需要存储四年以上。但是,其实对于其中的数据,绝大部分来讲,比如说三个月以前的数据访问量是非常低的,我们如果都使用相同的存储策略,我们整个集群有400多T的数据,如果都是用成本较高的SSD存储,效率和成本之间不是最优的结果。所以我们就需要一些针对最近3-4个月的热数据和4个月以前的冷数据采用不同的存储策略,来帮助业务降低成本,同时来保证我们业务的访问效率。
第三是我们还为业务提供了一个跨城容灾的能力,来保证业务的连续性。
由于来访问这个系统的业务有很多种,运维的同学也会有潜在的不同的各种各样的应用程序,我们需要针对不同的应用程序或者不同的用户,来提供不同的数据视图,来保证我数据整体的可靠性。这个是前面提到的第四是MLS的安全系统。
总结一下,微信支付整个集群大概是这么一个结构。
图中最上面是我们CLB,是腾讯内部的一个负载均衡的组件。CLB下面是我们的接入节点,我们在内部首先把数据会分为大商户和小商户,在下面可以看出来小商户热数据集群,小商户冷是商户冷数据集群,大商户热是大商户热数据集群,大商户冷是大商户冷数据集群。冷热集群之间的差别在于说存储设备是不一样的。热集群主要使用的是SSD的设备,冷集群使用的是普通的TS5的设备,降低存储成本。整体来讲的话,通过这种方式之后,我们就把我们整个集群的成本降低到了ICB存储的四分之一左右,全部使用ICB存储的四分之一。
在外部我们有一个比较大的保险公司,然后上线了200多个TBase实例在跑保险的核心业务,这里只展示了我们的部署架构。
我们上面分为两个平面,一个是读写平面,一个是只读平面。读写平面,业务通过VIP来提供读写能力。我们的只读平面通过业务VIP在多个节点做负载均衡,提供一个业务的只读能力。然后TBase的数据在生成之后,我们还需要把这个数据同步到我们其他的一些系统里面去,比如说ES、INFORMIX、MONGODB或者说MySQL,甚至同步到Oracle里面去。同步到Oracle和INFORMIX里面去主要是为了保证业务切换的可靠性,也就是我们把数据再回写回去,来保证这个切换过程中的稳定性。需要补充一下,TBase在往这个后面同步数据的时候,其实我们是先通过自己的逻辑解析的数据,把数据解析成了Json格式,通过Kafka同步过去。
国产化能力建设
下面介绍一下TBase在数据库国产化方面的工作。第一个,在国产化平台上面,我们支持了国内主要的平台,包括华为的泰山,还有中标麒麟。在操作系统这一块的话,中标麒麟已经支持和UOS也在支持中。国产芯片这一块, X86和ARM我们是支持的比较好的。
在国产化计划这块,一定会提到数据库的异构迁移,TBase现在已提供了完整的数据库迁移服务。
主要分为两部分,一部分是工具,在工具这一块的话,我们有数据的迁移工具,数据迁移评估工具以及数据校验的工具。同时我们还提供了专门的专家咨询服务,专家咨询的话,我们会有一些迁移评估,方案设计,改造建议,优化建议等等。通过整体的解决方案,我们会把数据从原有的商业数据库,包括Oracle、MySQL等等可以把它很可靠的同步到TBase里面来,来解决数据库国产化替换的一个数据迁移的问题。
在硬件这一块的话,现在我们常见的几种硬件进行了性能的评测,下面是评测结果。
在前面提到的X86环境下的话,我们在服务器上跑了68万TPM。然后LinuxOne能跑127万,测试结果跟服务器的配置有关系。说到数据库的国产化替换,肯定是绕不开Oracle兼容的,Oracle兼容TBase做了相当多的工作,包括我们的对象的支持,数据类型的支持,函数,SQL特性和存储过程。这一块我们后续会进行一些增强和扩展,来提升我们的兼容度。
>>>>
Q & A
Q1:分布式表的库备份,所有的DN都要独立备份一份吗?
A:TBase每个DN是整个数据库的数据的分片,所以说在备份的时候,至少每个DN是要备份一份出来的,但是它不是独立的一份,因为在备份逻辑里面会控制保障整个集群的完整性,也就是各个DN之间,每个DN都会有一个相应的副本存储到冷备里面去。
Q2:冷备这块最大一致时间戳方式,会不会因为服务器之间的时间差异造成备份不一致?
A:冷备的时间戳问题,我觉得这个不用担心,分享中我提到有5种方式:1)分布式快照隔离;2)绝对物理时间隔离;3)硬件绝对物理时间隔离;4)本地时间隔离;5)逻辑时间戳的隔离。TBase使用的是逻辑时间戳,这个时间戳不是本地的时间戳,是TBase内部的时间戳,我们会保证它的稳定性和单向递增,它不会发生反转,也不会发生偏移,而且它有容灾的特性。即使机器发生故障,然后再把它拉起来,它也是能保证整个稳定性的。
Q3:时间戳是个全局自增值吗?gtid?
A:至于说这个时间戳是不是一个自增值,简单理解上,说是自增值是没有问题的。但是核心问题是我们需要保证它,不能让它有全局瓶颈,不能让它因为一把锁,把它全局吞吐量都拉下降了。
Q4:安全控制方式上,select 如何输入token?
A:TBase的安全控制方式更多的是通过用户的接口,比如说安全管理员,他会有自己的一套接口来创建自己的密钥,创建自己的安全规则。
Q5:冷热数据分离是通过人工方式做的还是自动方式?判断冷热数据的标准是啥?有没有采用存储分层的能力自动来判断?
A:至于冷热分离的转储是存储层的设置策略还是在云数据库层去做,其实冷热转储这一块,冷热的访问逻辑和逻辑的定义是在数据库里面定义的,但是冷热的转储,是通过TBase的管控系统来做,这个逻辑相对来讲还是比较重,我们需要有一些专门的机制来保障它的可靠性和易用性,所以TBase整个把它移到了管控系统里面来。
冷热分离的方式是人工去定义的,我们根据的业务逻辑来定义哪个数据是冷,哪个数据是热的。但是它的判断,它下层的迁移的逻辑是自动的,只要把这个规则定义好了之后,整个系统会自动的运行,不需要人为干预。
判断冷热的标准是什么,举个例子,比如说微信支付是四个月的数据是热数据,四个月之前的数据是冷数据,其实是按照时间来判断的,我们取当前的时间往前面算,往前面偏移。超过了一定的阈值它就是冷数据。
关于存储分层之后,TBase更多是从数据库本身的能力来做。
Q6:备份工具是原生内置的吗?
A:TBase的备份工具不是数据库内置的,是我们在管控里面做的,说句实在话,冷备这一块东西需要打交道的周边模块比较多。比如需要把冷备的数据同步到一个外部存储里面,外部存储有可能是一个磁盘阵列,有可能是一个HDFS,也有可能是一个其他的存储,这些东西放在数据内核里面不合适,太重了,冷备功能是我们提供的独立工具来做的。
Q7:TBase本身就是一个数据库引擎,它不是一个数据库中间件?
A:TBase本质上是一个数据库引擎。今天我讲的PPT里面,大家可以看到,整个过程中其实我都没有提中间件,一直在讲数据库底层引擎的一个原理,比如说优化器的原理、执行器的原理,还有分布式优化逻辑,以及我们的分布式事务的逻辑,其实都是引擎里面的原理。中间件一般只会做SQL解析、SQL转发和结果的返回,很少涉及到执行计划。
Q8:PUSH QUERY和PULL DATA如何选择?
A:其实PUSH QUERY和PULL DATA这个选择没有一个严格的界限,一般PUSH QUERY在数据量相对比较大的时候会比较有效一点,因为把QUERY下推之后,下层节点的执行会过滤掉大部分数据,拉取的数据量大大的减小。然后PULL DATA在一些简单的查询,表非常小的时候,把它拉回来算可能更快一点。这一块选择没有严格的标准,可以根据我们的场景决定。
Q9:如果是从Oracle转到分布式数据库有哪些知识需要补充?
A:说实在话, Oracle是一个发展了三四十年的数据库产品,整体的架构和功能都非常强大了。分布式数据库是一个新兴的领域,产品架构,包括它的生态也都是一直处于建设和完善中,因此在调优、使用和数据业务的建模这一块跟以前的Oracle还是有所区别的。从哪一块入手,我觉得这要看你使用的是哪些分布式数据库。如果是MPP的话,可能就需要了解一下MPP里面的关键点。比如数据的分片怎么分,跑SQL的时候,怎么去结合分布逻辑去很好的设计SQL,这个可能是在接触分布式数据库的时候需要考虑的一个比较重要的问题。
Q10:两个大表分布在不同的DN,做HASH,如何保证选择正确的执行计划和高效率?
A:两个大表分布在不同的节点里面,我们要进行一个查询,如何提升它的效率。如果两个大表,首先第一个来讲,我们得搞清楚这些表进行查询的时候关联的KEY有哪些。比如说如果我们都是使用这一列进行关联,那是不是可以在设计的时候就按照性能这一列进行数据的分片,在进行查询的时候,就可以下推到每个DN节点来执行,换句话说每个DN节点的执行层是并行的,没有相互之间的交互,这样效率在分布式的时候是最高的。
如果这个表查询的SQL非常多,一张表有一两百个字段,但是关联的时候,有的是按照分布KEY进行关联,有的不是按照分布KEY进行关联,这个时候就得有一些取舍。要看一下,如果按照分布KEY进行关联效率会最高,而且可能会比不按照分布KEY的效率高不少,那么我们会选择优先的把我们业务里面用到的一些频率比较高的,要求比较高的一些SQL优先的按照那些SQL来设计表的分布方式。然后对于其他的一些SQL,对于那些JOIN的列进一步建索引,提升查询效率。
另外在写SQL的时候,尽量做到某个节点上进行查询的时候,能够通过我们表达式的过滤掉一些无效的数据传输,这样的话就可以保证一个相对比较好的效率。
Q11:学习分布式数据库有哪些知识要补充?从哪里开始?
A:至于说这些数据库知识有哪些需要补充,我觉得是这样的,数据库本身是一个比较古老的技术,如果说从哪里开始,有机会的话,从使用开始就最好了。比如说先做一些最简单的数据库的使用,建表、生成数据,最好有一个业务系统作为驱动,边用边学,这样上手更快一些。
Q12:TBase代码开源了吗?
A:TBase的代码已经开源,大家有兴趣的话,欢迎访问:https://github.com/Tencent/TBase。TBase预计今年年中左右会重新推动一个新的版本出来,大家敬请期待。
长按进入小程序,进行30天打卡