前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实现分区表性能提升超10倍,解密TDSQL PG版开源升级特性

实现分区表性能提升超10倍,解密TDSQL PG版开源升级特性

作者头像
腾讯云数据库 TencentDB
发布2022-01-14 11:40:20
7960
发布2022-01-14 11:40:20
举报

1月11日,腾讯云TDSQL PG开源版(开源代号TBase)再升级:分布区表关联查询性能(join)提升超10倍,同时提升了产品在分布式场景下的易用性,增加灵活可用的功能组件。

该升级版本在第十一届PostgreSQL中国技术大会上正式公布,同时更新文档已同步在GitHub上。依托社区和内部业务系统的实践检验,TDSQL PG开源版基本保持每月一次小升级、每半年一次重大升级的节奏,助力众多开发者应用前沿数据库技术。

本期将为大家深度解读TDSQL PG开源版升级特性,具体包括:分区表功能增强、异地多活易用性增强、分布式死锁自动检测并解锁功能、2PC残留自动检测并清理功能等硬核干货。

TDSQL PG版

开源发展历程

TDSQL PG版(原名TBase)是腾讯自主研发的新一代分布式国产数据库,其具备业界领先的HTAP能力,属于MPP无共享架构,在企业级安全方面采用三权分立安全体系。        

2020年,腾讯云正式宣布数据库品牌TDSQL的全新战略升级计划。原有的TDSQL、TBase、CynosDB三大产品线统一升级为“腾讯云企业级分布式数据库TDSQL”。全新升级后的腾讯云TDSQL涵盖分布式、分析型、云原生等多引擎融合的完整数据库产品体系。TDSQL PG版则是TDSQL系列产品之一,主要针对HTAP场景。

下图是TDSQL PG版的总体框架。左上角为事务管理器GTM,负责整个集群的事务管理和全局事务的协调。右上角为协调节点CN,它是业务应用访问的入口,每个节点对等,业务连接任意节点,最终返回的数据都相同。右下角为数据节点DN,每个DN只存储部分用户数据,所有DN一起组成完整的数据集。最左边和最下边的部分属于管控系统,负责系统的资源管理和告警监控。  

TDSQL PG版最早可追溯到2008年,2012年其发布第一个分布式版本,2015年其发布第二个分布式版本。截至目前,TDSQL PG版已经在众多市场客户中得到应用,包括数字广东、云南公安、微信广告、微信支付等。值得一提的是,TDSQL PG版在2019年中标PICC,成为行业内第一个成功落地保险核心系统的分布式国产数据库。 

TDSQL PG版在2019年11月7日正式宣布开源。开源地址在Github平台上,下图是供广大开发人员使用参考文档的wiki地址。

TDSQL PG版开源对用户有重要价值,分别体现在:

  • 版本经过大量业务验证,成熟稳定,开源版本和腾讯自用版本共基线,能够帮助用户快速构建核心业务。
  • 同时支持OLTP/OLAP能力,提供一站式数据库解决方案。
  • 安全可控的企业级分布式数据库能力,腾讯专业研发运营团队持续投入开发和维护,推动社区进步。
  • 团队积极回馈开源社区,即时响应用户需求,努力创造开源社会价值。

TDSQL PG版

开源特性回顾

2021年7月,我们进行了TDSQL PG版 2.2.0版本的升级。2.2.0升级主要包括四个方面:内存管理优化,提供会话内存视图,进行优化管理;优化分布式执行器、优化器;分布式调优性能增强;分布式执行可视化能力增强。

2.1 执行器/优化器优化

我们将子查询在内部优化成一个关联查询,提高查询效率。以视图中的表格为例,需要根据表A中的ID找到表B中每一条对应ID的数据,再用表A的值与表B中值的MIN进行比较。在优化前,因为这是一个子查询,假如表A有1000条记录,则A中每一条记录都要在表B进行全量扫描。做完这个查询至少要将表B扫描一千次,这样做的成本非常高。在优化后,因为表B需要取B的MIN最小值,且我们需要利用id做join,所以可以先扫描一遍B表,根据id先进行聚集,把每一个id最小的MIN值取出来,生成聚集表,最后聚集表与表A进行hash join,因此我们只需将B表进行一次扫描即可。

我们还对distinct进行性能优化。在优化前,需要将所有数据从DN节点拉到CN节点,由CN节点进行distinct的去重操作。因为分布式系统数据量特别大,如果全部拉到CN,会导致数据量大,网络负载高,CN也会成为单点瓶颈,难以发挥分布式特性。我们针对此类情况进行优化。先在DN本地进行部分的distinct去重,使得每个DN可以并行计算,并行后将结果全部发到CN上,由CN进行最终的去重操作,减少了大量的网络交互,充分发挥出分布式数据库的特性。

在对优化器进行优化后,我们取部分TPCDS标准测试集进行测试,发现有些SQL的性能可以提升上千倍。

2.2 内存管理优化

我们提供Memory的内存视图详情,能够详细看到每一个进程占用的内存情况。除了对视图进行增强外,我们还对内存使用进行详细优化。

下图展示的是假设有一个用户连接,这个连接在访问一万张表后的内存占用情况(访问完该连接还没有退出、仍处于空闲状态时的内存占用情况)。从下表中可以看到,TopMemoryContext上出现数量级增长,实现10倍以上提升,CacheMemoryContext也实现20倍的提升。

针对明显空闲的连接却占用大量内存的不合理情况,我们进行了优化我们将内存的使用分为两部分:第一部分是RelCache,即用户数据表的Cache;第二部分是Cat Cache,即元数据的Cache。如果需要对某个Rel进行Cache,我们会将新来的项放在Relation LRU List的最前面,此后每次来新的项我们都往前面加。当LRU项目超过预定意义的参数时,我们会从后往前去遍历LRU,将引用计数为0的Relation的内存项释放掉。Cat LRU元数据缓存也同理,我们将新来的某条元数据缓存,将其放在Cat LRU List的最前面,再从后往前进行遍历,将引用计数为0的项进行删除,从而释放内存。由此可以将部分占用内存大且低频使用的空闲连接,通过LRU将其替换出去,使会话内存减少55.7%。

对于分布式系统,除了单点外还要考虑分布式内存管理。当一个应用程序连接到CN后,CN需要跟DN进行数据通信。但它与DN的通信的DN进程需要向本地的Pooler申请连接,Pooler会将本地缓存的部分到DN的空闲连接分配给CN,此后CN才能与DN进行通信。Pooler本地缓存了很多到DN的空闲连接,实时准备为CN提供服务,以至于存在许多空闲连接。对此,我们在Pooler内部上线实时检测空闲连接的功能,将大于配置参数的连接释放掉,使得空闲连接占用减少89.3%。

经过优化后,在2CN、2DN的情况下,依旧是一个连接在访问一万张表后的内存占用情况,优化前总内存占51.4M,经优化后只占5.4M。节点内部DN自动释放空闲连接,空闲连接直接减少89%,经过RelCache LRU替换后,CN连接内存减少55%。

2.3 分布式执行可视化

以下图为例,表A和表B进行join,A表作为分布键,B表作为非分布键,我们进行join时要将join的过程下推到DN节点执行,但因为表B不是分布键join,所以需要对表B按f2字段进行重分布。在重分布过程中,DN1上有一个backend进程,需要扫描本地的表B,把扫描到的部分数据留给本地的DN节点,部分数据则重分布到DN2数据节点。所以一次重分布中,本地会新创建一个DN1的backend进程进行数据扫描,还要创建另一个backend进程负责发送数据给DN2。

利用分布式可视化的能力,可以查到任意一个用户的session id,查到session id后,可以根据session id查到对应的在不同CN、DN上的各个进程目前在做什么。比如这个节点我们需要做hash join,因为需要根据f2字段做数据重分布,现在在等待重分布的数据,另外一个进程是扫描表B,扫描完后会提供给前面的进程,才能进行hash join,CN1则是在执行查询事务。通过分布式执行过程的可视化视图,我们可以详细知道一个SQL下去各个节点在做什么。

下图展示的是分布式可视化功能的使用方法,详情可参考Github上的wiki地址:

TDSQL PG版

开源重磅升级

TDSQL PG开源版此次升级V2.3.0版本包括四个方面:分区表能力增强、异地多活易用性增强、分布式死锁检测、2PC残留自动清理。

3.1 分区表能力增强

针对分区表能力,本次TDSQL PG版升级,整体响应速度更快,有效应对此前业界仍然面临数据量大时读写性能慢等问题。新版本通过分区表功能增强,包括增加hash分区类型、支持default分区子表创建、分区父表索引操作自动同步子表等,实现分区表便捷管理;同时,新版本实现了分区剪枝性能提升30%,分布区表关联查询性能(join)提升超10倍,完美解决查询效率问题。

具体来说,在原有支持range和list分区表的基础上,TDSQL PG版新增hash分区表功能。用户在创建时可以指定该分区表为hash分区表,再指定分区键,同时需要指定hash模数和余数。

TDSQL PG版还新增了default分区。在上一版本中,在创建分区表且创建子分区时,如果没有创建default默认分区,用户插入数据时,如果插入不属于指定分区的其他数据,会出现报错。在本次升级后,如果插入的数据不属于其他指定子分区,所有数据会落到default分区。比如下图右边的例子,2019年12月和2020年3月的数据,都不属于指定的其他子分区,因此会落入default分区。其优点是不需要报错,同时必要时可以查询不属于指定分区的其他零散值。该功能目前仅支持range和list分区,不支持hash分区。因为在指定hash的模数和余数后,数据就必然会落在指定分区,不存在不属于指定分区的情况。

TDSQL PG版也支持分区键更新。在上一版本中,如果要更新创建表时指定的分区键,就会出现报错,不允许更新。新版本对此进行升级。在下图左边的例子中,一个分区子表存储0到30的数据,另一个分区子表存储30到60的数据,用户可以对分区键即id键进行更新,将id从25改为50,数据会自动从原来的分区转移到新的分区。

此外,TDSQL PG版还支持分区父表建索引自动同步子表。在上一版本中,如果要为分区表建索引,只能给某个指定子表建分区,不能给父表建分区。在新版本中,我们对此进行优化,支持在父表上指定建分区。在下图右边的例子中,假设要给tbl表的id字段建索引,在创建后它会自动将索引同步到所有子分区上,比如2020年1月分区、2020年2月分区和default分区。用户只需要在父表上执行一条SQL,它就会自动在所有子分区上全部创建该索引,其优点是方便用户对分区里的索引进行维护。我们也支持创建唯一分区,但需要包含分区键。

除了分区能力的增强,TDSQL PG版还引入partition-wise join,对原有性能进行提升。假设有两个分区表,分别为A表和B表,它们的分区数量完全相同,且分区的字段类型一致。如果没有partition-wise join,在进行join时,需要先将A表中所有子分区的数据全部捞取,再将B表中所有子分区的数据全部捞取,再用A表全量数据与B表全量数据进行join,这种操作方式的数据量非常大。在引入partition-wise join后,因为两个分区键为同一类型,且分区数量相同,我们可以将A表的分区1与B表的分区1进行join,A表的分区2与B表的分区2进行join。我们并不需要将A表的全量数据与B表的全量数据进行join,只需要将对等的分区进行join即可,从而使性能得到大幅提升。

下图是该功能实际效果的测试对比。在partition-wise join打开的情况下,与上一版本相比,最新版本的性能有10倍的提升。

3.2 异地多活的易用性增强

另一重要升级,是异地多活的易用性增强。原先单活时跨区接入延时大,一旦发生故障服务和数据库都需要切换,流程复杂;而异地多中心接入时延小,业务在一个中心内能完成闭环,秒级即可完成切换。本次升级新增多活插件化功能,方便用户安装配置,提升了产品易用性。

异地多活主要区别于传统两地三中心的单活模式。在单活模式中,假设主库在南方,北方的服务要写入主库,因为地域相隔太远,延时会非常大。如果出现南北网络故障,北方用户就无法访问主库,出现不可用情况。如果采用异地多活模式则不存在上述问题。我们可以在北方多设立一个主库,北方的服务写入北方主库,南方的服务写入南方主库,南北主库之间进行双向复制。其优点在于南北主库各自都有全量数据集,且业务可以就近接入,在一个中心内部实现闭环,即使南北出现网络故障也不会影响服务。

异地多活采用双向复制功能,下图是异地多活架构示意图。区域1是深圳,区域2是上海,我们将区域1的数据节点作为发布端,将区域2的CN节点作为订阅端(CN可以订阅作为发布端的数据节点上的数据),在完成数据订阅后,CN需要经过一个路由才能将订阅到的数据写入本地的DN节点上,这样我们支持了异构集群之间的同步,一个CN可以订阅多个数据节点。

在新版本中,我们对易用性进行增强。通过tbase_subscription工具,用户可以利用SQL直接创建整个同步的异地多活过程。创建时还可以指定订阅的并行度,从而提高订阅效率。此外,因为一个CN可以订阅多个DN,用户可以将订阅任务下发到不同CN上,使CN进行负载均衡。

3.3 分布式死锁自动检测

以下图为例。假设有两个CN,分别为CN1和CN2。有两个用户,用户1连到CN1,产生一个session,用户2连到CN2,也产生一个session。用户1使用显示事务查询A表数据,用户2也采用显示事务查询B表数据。用户1查询完A表数据时,想将B表进行删除。因为是分布式系统,CN2上也存在B表,需要同步进行删除。如果要删除B表则需要B表的排他锁。但这时在CN2上,用户2刚启动显示事务查询B表,获得B表的共享锁,这就产生了锁冲突,反之亦然。

在这种情况下,CN1有A表的共享锁,需要等B表的排他锁,CN2有B表的共享锁,又要等A表的排他锁,两个事务之间就形成了分布式死锁。

针对这种情况,我们引入了pg_unlock工具。该工具可通过extension安装,快速便捷。用户安装后可以查到分布式死锁之间的依赖关系。比如在上面的例子中,CN1是一个依赖于CN2的事务,CN2是一个依赖于CN1的事务。用户还可以查到集群中一个死锁的详细信息。比如CN1上的drop b需要B表的排他锁,CN2上的drop a也需要A的排他锁,它们之间都是求而不得存在死锁。我们可以通过执行pg_unlock execute来解开死锁,解开的方法是回滚掉一个事务。在回滚事务时,我们会在内部进行优化,计算出回滚代价最小的事务并进行回滚。

3.4 2PC残留自动清理

以下图为例,假设有两个CN,分别为CN1、CN2,有两个DN,分别为DN1、DN2。用户连进来创建A表,再进行prepare transaction,该事务命名为create a。我们通过另一个CN连接进来,可以查询处于prepare状态的事务有哪些,可以看到CN1上有一个prepare事务叫create a,CN2、DN1、DN2也有。

用户继续执行在DN2上将create a事务进行回滚的操作,此后该操作会话直接退出。退出后我们再去查处于prepare状态的事务,发现CN1、CN2、DN1各有一个create a事务,但DN2上没有。因为上述会话在退出前,对DN2上的create a事务进行回滚,相当于该事务不存在prepare状态。由于会话已经退出,该事务永远不会终止,就出现了2PC残留的情况。

针对这种情况,我们引入了pg-clean工具。通过pg_clean check transaction,用户可以直接查到目前有哪些2PC残留事务,以及这些事务的名称、参与的节点等。通过pg_clean execute,我们可以对2PC残留事务进行自动清理。这实际上是将残留事务进行abort操作。因为CN1、CN2、DN1上的事务都处于prepare状态,但DN2上执行了abort,它只能将该事务abort,不能将其提交,否则会出现部分提交数据不一致的问题。我们能够根据事务状态自动选择回滚或提交,从而将2PC残留事务进行清理。

TDSQL PG版

开源生态未来发展计划

在下个版本中,我们计划在以下四个方面对TDSQL PG开源版进行加强:

  • 存储能力加强。支持透明压缩,减少磁盘存储成本;提供Direct IO能力,提高某些情况下的写效率。
  • 索引优化。支持全局索引,提升非分布键查询性能。
  • 优化器能力提升。提高执行效率,提升业务查询及写的性能。
  • 分布式状态可视化。优化全局session可视化、query可视化、分布式锁可视化、分布式事务状态可视化,帮助用户更好地掌控系统。

开源的本质是以技术开放促进技术创新。腾讯云对TDSQL PG版不断开发和投入,版本经过大量业务验证,成熟稳定,开源版本和腾讯自用版本共基线,能够帮助用户快速构建核心业务,将持续给客户带来价值,与广大开发者共同打造可持续的国产数据库开源生态。

同时欢迎各位感兴趣的小伙伴,与我们一起共同助力国产数据库技术创新与开源生态发展!

-- 更多精彩 --

腾讯云在PostgreSQL领域的‘‘再次突破’’

一文详解TDSQL PG版Oracle兼容性实践

↓↓点击阅读原文,了解更多优惠

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云数据库 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TDSQL PG版
  • 开源发展历程
  • TDSQL PG版
  • 开源特性回顾
    • 2.1 执行器/优化器优化
      • 2.2 内存管理优化
        • 2.3 分布式执行可视化
        • TDSQL PG版
        • 开源重磅升级
          • 3.1 分区表能力增强
            • 3.2 异地多活的易用性增强
              • 3.3 分布式死锁自动检测
                • 3.4 2PC残留自动清理
                • TDSQL PG版
                • 开源生态未来发展计划
                相关产品与服务
                TDSQL MySQL 版
                TDSQL MySQL 版(TDSQL for MySQL)是腾讯打造的一款分布式数据库产品,具备强一致高可用、全球部署架构、分布式水平扩展、高性能、企业级安全等特性,同时提供智能 DBA、自动化运营、监控告警等配套设施,为客户提供完整的分布式数据库解决方案。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档