|作者 陈爱声,腾讯云数据库高级工程师,目前负责TDSQL PG版(原TBase)的应用系统架构设计工作。
经常有开源用户跟我交流——“为什么我对TBase的使用和大家的效果是不一样的?”事实上,在使用分布式数据库的时候有些开发规范还是必须要遵循的。只有遵循了这些开发规范,应用系统使用起来才能够流畅。今天我就和大家分享一下TDSQL PG版(原TBase)数据库的开发规范和最佳实践的问题。
Part 01 TDSQL PG版(原TBase)的由来和架构解析
大概在2015年,微信支付快速发展起来时,面对商家支付需求,对于原有系统来说更加复杂,因此当时业务对数据治理的能力需求很强。大家都了解过,PG开源30年了,号称最稳定、功能特别强大开源关系型数据库。所以我们当时做了一个基于(Postgresql)开源分布式数据库系统。TDSQL PG版基于PG模型下,我们做了大量二次开发,增加了很多企业特性,包括安全方面、审计方面,以及Oracle兼容性等等都做了加强,还有很多稳定性及bug修复。19年, TDSQL PG版对外开源,开源以后有很多来自社区的使用上的问题。今天和大家来分享一下TDSQL PG版在开发过程中有哪些问题是一定要注意、要提前规划好的。我本身也来自PG社区,从2009年的PG大会一直到现在,也算是PG的老用户了。所以,大家了解TDSQL PG版首先还是要从它的最基本的架构开始——TDSQL PG版有四个最主要的架构:
一、服务体系
第一,TDSQL PG版整个服务体系由三大组件组成(如图):最左边GTM,是事务管理器,提供统一时钟和支持分布式事务。单机事务控制,放在内存里管理。对于分布式数据库,事务管理使用GTM节点来统一管理,所有事务的请求都必须向这个节点获取一个事务ID。右边是CN节点,也就是接入节点,连接数据库的时候要从上面CN节点进行连接。CN节点部署时是多组的部署架构, CN节点可以是很多个CN节点,可以到1024个,CN节点上面不会有实际的业务数据,只存储一些路由信息和对象元数据。从任何一个节点的接入看到的视图都是一致的,随着业务的并发、业务的量增加,CN节点可以水平扩展。下面是DN节点,存储用户数据。业务数据从CN进来后,经过路由计算把数据发到对应DN节点,业务数据访问对于业务层是透明的,不需要关心保存在哪里。DN节点也是可水平扩展,最大可以到1024个,每个DN节点都是存储独立的数据。每一种节点为了实现高可用,都有主节点、备节点,出现异常故障的时候,可以切换到备节点为主节点,继续提供服务。二、存储组结构
第二是存储组。上面有六个DN节点,分成两个存储组:每个存储组存储业务数据可以是没有互相关系的两个独立应用,也可以是用于冷热分离分区表应用。如上面的冷热存储两组,热情存储组我们可以使用高速的ssd存储,而冷的存储组我们使用便宜的sas盘介质。虽然分开不同的介质,但对于上层CN的节点,存储组也是透明的,下层有多少个存储组都能在CN上看得到,这样如原来的传统的数据切割出去就不再需要,应用访问变得很友好。
三、逻辑体系结构
第三是实例的拓扑结构。实例下可以很多库,比如有一个Postgre库,以及一些自定义业务库,数据库之间是无法互相访问的(只能借助于dblink,fdw来实现跨库访问),每个库下面是模式(schema),schema下面再分表、索引、序列和视图,这一点在PG生态是一致的。
四、连接池管理
第四,提高高并发性能的连接池管理。前文提到,访问接入是通过CN,但是数据是放在DN节点,因此,为了提高访问效率,应用程序开发的时候,应用程序到数据库之间会建立一个连接池,需要数据库连接的时候可以直接从连接池获取已经建立数据库连接,复用连接这样可以提高连接的效率。其中,每个CN或者DN节点也都有自已的连接池,当CN或者DN节点要从另一个节点获取数据时就会从连接池中获取一个已经存在的连接,以此实现更高的效率。
连接池有两个维度需要维护,一个会基于用户,一个基于DATABASE,CN需要通信的DN都要提前建立连接,如果要维护的连接数特别大,则维护成本非常大,所以我们尽可能一定程度控制用户和数据库数量,因为相对而言连接池维护连接小、效率更高。这一点机制跟应用程序的设计一样。
讲完体系架构,以下分享TDSQL PG版(原Tbase)数据表使用规范和指南,包括普通shard表,分区表,冷热分区表,复制表,四种表都和数据治理有关。
普通shard表就是分片表。假如有两个分片,数据如何存储?举个例子,指定放到存储组(to group default_group这个实际可以不用写,这样可以兼容PG,但是这里为了完整就写成这样),如果一个shard表有两个分片,数据表有两个字段,存储的时候,数据存放于两个分片上,而且在分片1中数据,就不会存在于分片2中,这个也是分布式数据库的特性,数据打散存储。
第一分布键的选择。选择主键或者数据值重复率低的字段,总之要让数据平均分散到所有的分片中。打散所有分片是要让数据打的足够散,否则某个分片会有倾斜,访问性能也会出现倾斜,这样的话整套实例在某一个节点会出现性能瓶颈,性能都会堆积在最慢的节点上面。
第二分布键的约束。分布键值不能修改,数据类型不能修改。一定要特别注意到这一点。第三是JOIN的问题。设计业务满足使用分布键join,否则产生数据重分布。对一个OLTP类的业务,重分布产生更多连接和更高的网络延迟不利于系统水平扩展,对于OLAP类的业务,这一点关系不大。第四,在使用表的时候有几点特别要注意——查询,修改,删除数据,使用分布键字段做为WHERE条件,才能实现水平扩展,否则性能将达不到分布式数据库的水平扩展能力。二、分区表
刚才分享了TDSQL PG版水平扩展能力,下面来看垂直扩展能力。数据分片以后,实际上某个表到了每个分片的数据量可能还是特别的大,接下来可能还需要再做垂直切分,这就是分区表——在每个分片里进行垂直切分。
分区表比较适合带时间属性、ID属性的数据,可以实现每一个分片里面的这张表的每个物理子表的数据量尽可能低,能实现快速剪枝,性能更好。举个例子,从五千万到一个亿索引,不分区的话,高速连续写入时性能将降低一半。分区表的优势,表大小得到有效控制,更新性能更好。注意对分区表进行查询、更新、删除数据时,要限定到某个分区范围执行才能发挥分区表带来的好处。其它的如全表扫描成本开销更大,DDL开销更大,使用这些操作需要注意。
三、冷热分区表
冷热分区表是TDSQL PG版数据治理的特性,如交易业务场景的微信支付。大家日常使用微信支付的时候,很少时刻关注支付明细数据,但有时还是会回查某个时间段的交易数据流水,比如有一笔账什么时候支付的、支付给谁,或者商家过了一段时间会进行报表查询。如果这些冷数据全部用高速的SSD存储,大量的冷数据存在那里访问频率很低,存储成本又很贵;而如果切割出去,用另外的实例存储,则会发现前端的应用程序又要连接很多数据源,或者说中台需要做各种的拼接,拼接以后才能返回前端,这样导致业务路由非常复杂——针对这种业务特性,TDSQL PG版这里针对这种业务特性做了一种设计,就是冷热分区表。前面介绍了存储组,存储组定义了一个热的存储组和一个冷的存储组,创建表的时候可以创建这样一张表:它的存储组有两个,一个热存储组,一个冷存储组;TDSQL PG版系统里面有一个总的路由时间,可以控制什么时间点的数据放在热存储组、什么时候的数据存放在冷存储组。对应用来说,TDSQL PG版可以自动帮助路由,完全透明。适用于历史数据量大,历史数据查询更新频率低的业务数据。这种历史数据特别庞大,比如交易数据,占用的存储空间很大,可以设计冷热的分区表。冷热分区表的数据分开不同GROUP存储,跨GROUP查询时开销相对较大;禁止高频跨GROUP 查询,或跨GROUP的大数据量查询。四、复制表
复制表是数据治理特性的另外一种。在做业务改造的时候,经常碰到一种情况,如有一些配置表,或配置中心、产品中心,这些表数据量不大,也不会经常改,但是这些表和我们的业务经常有JOIN关联访问,很高并发的情况下,累计的成本非常多,为了提高总体吞吐量,我们经常把这种表设置成复制表,复制表特性就是所有数据会存在分片1,也会存在分片2,JOIN就不需要做数据重分布。这种模式最大的好处就是减少数据重分布,减少网络流量,减少连接数。经常要跨库JOIN的小数据量表可以考虑使用复制表。但是复制表是所有节点都有全量数据,对于大数据量的数据表不适合。复制表更新性能较低,高频更新容易产生死锁。
以下介绍TDSQL PG版的索引,包括索引类型、特殊索引,还有索引维护。
一、索引类型
TDSQL PG版索引跟PG是一致的,目前分为四种:
二、特殊索引
主键索引:创建主键时,系统默认创建一个对应的唯一索引。函数索引:使用函数索引匹配于查询中使用函数对字段进行修饰。条件索引:条件索引可以加速某个字段值的查询。这也是属于数据治理的方式,查找的时候如果维护成本加大,可以把里面一些值排除在外,维护会很快,甚至只是加速某一个ID来提高访问速度,也可以针对某个ID创建一个很小的索引,这样访问这个ID的时候性能会非常高。三、索引维护
通常创建索引会对数据表施加排它锁,我们可以使用CONCURRENTLY方式实现在线创建索引,不会数据表DML的执行。通过查询系统视图pg_stat_all_indexes可以评估索引使用情况,删除不必要的索引。减少不必要的索引,提高更新效率。
增删改,为了提高性能,归纳起来有三个部分:合并操作,减少扫描,数据库保护。
一、合并操作
因为分布式数据库走的是网络,如果全部合并起来的话网络成本会降低,合并操作有三个:
二、减少扫描
三、数据库保护
首先,限制连接数:微服务化改造,往往会带来更多的连接,TDSQL PG版基于1个连接,一个进程,如果连接多,高并发时进程不断切换,会造成大量CPU上下文切换,CPU的工作效率低下,正确的设计方案是数据库保持最优化的连接数,应用基于这个连接数进程队列获取连接。第二,一定要配置锁超时:分布式数据库出现获取锁超时问题会更加复杂,而且应用程序必须有这种锁机制处理分支,往往这样做,服务的可用性更好。第四,收集慢SQL,及时发现慢SQL并优化,才能保障系统隐定高效运行。以上是对TDSQL PG版的使用规划还有最佳实践的总结,欢迎大家下载体验TDSQL PG版的开源版本(原TBase),使用时遵循以上这些规范使用起来会更加流畅。