ITPub博客

首页 > 数据库 > 国内数据库 > 腾讯云TDSQL-C云原生数据库技术

腾讯云TDSQL-C云原生数据库技术

原创 国内数据库 作者:腾讯云数据库 时间:2021-09-26 17:15:43 0 删除 编辑

9月16日,Distributed Cloud|2021全球分布式云大会·上海站隆重召开。在全球分布式云大会不懈布道下,云计算行业对分布式云的关注度愈发高涨,以全球分布式云联盟成员为代表,涌现出了大量分布式云技术和实践成果,为分布式云计算发展夯实了基础。


2021全球分布式云大会为分布式云计算发展再添强大推力,本次大会共设有分布式云主题报告会、边缘云论坛、云原生专题论坛、分布式数据库论坛四大论坛,围绕分布式云、边缘算力、云原生、分布式架构等技术与实践展开。全球分布式云联盟联合阿里云、腾讯云、Google Cloud、中兴通讯、京东云、安迈云、网心科技等国内外分布式云顶尖技术服务商,共话分布式云创新新趋势,共谋云计算变革新未来,共享分布式云计算新红利!


在9月16日下午召开的云原生专题论坛上,腾讯云数据库专家工程师张远发表了题为**《腾讯云TDSQL-C云原生数据库技术》**的精彩演讲。


# TDSQL-C简介


张远介绍说,TDSQL-C是腾讯云自研的新一代企业级云原生分布式数据库,经过五年的打磨,**具有以下几个关键的特性:**


**可靠性。**TDSQL-C基于共享存储的云原生架构,存储是多副本的,能够保证数据可靠性。同时能够做到即时回滚,任意时间数据都可靠。


**极致性能。**腾讯云对主备机读写性能做了全面优化,同时也根据不同规格做针对性优化。


**可用性。**TDSQL-C可以做到秒级的RTO,故障几乎无感知,同时主备延迟可以做到毫秒级。此外,基于共享内存,数据能够快速恢复、快速预热。


**弹性扩展。**数据能够快速透明拓展,而且容量最大可以达到1PB,满足大的需求。


![file](http://image.openwrite.cn/24379_D9C6A3E41D30410096F40DE48664AFCD)


在总体架构上,TDSQL-C是基于共享存储的存储和计算分离的架构。与传统的MySQL主备架构对比,可以看到传统的MySQL主备通过binlog进行逻辑复制,而TDSQL-C是通过redo日志进行的物理复制;传统的MySQL需要向存储写多份数据包括data,binlog,redo log等, 而TDSQL-C只需向存储写一份redo日志即可;传统的MySQL主备各存储一份数据,而TDSQL-C基于共享存储只有一份数据。


# TDSQL-C内核关键技术


张远演讲的第二部分会围绕关键特性展开,详细介绍了TDSQL-C特性背后的技术原理和细节。


TDSQL-C之高性能。


TDSQL-C 高性能-plan cache


TDSQL-C 高性能的一个重要优化是实现了查询计划缓存,称之为plan cache。


图中展示了一条SQL在数据库中的执行过程,会经过以下几个阶段:


**首先MySQL server接受到用户的SQL请求,在parse阶段解析为逻辑的执行计划树;接下来在查询优化阶段生成物理的查询计划;然后执行器从存储引擎获取数据进行计算。**


![file](http://image.openwrite.cn/24379_870A7292180E446BA3A301B7DDB7C972)


经过plan cache优化后,一条SQL执行过程省略了前面的解析和查询优化阶段,SQL的执行时间大大缩短了。


![file](http://image.openwrite.cn/24379_78A2010D1CCA41D89A6FB956EBDF9B1B)


优化效果以sysbench场景为例,不同颜色代表不同阶段的耗时,可以看到经过plan cache优化后,parse和查询优化时间减少了,性能提升了70%左右。


**TDSQL-C高性能-异步组提交**


![file](http://image.openwrite.cn/24379_3F54D503B27D4F8388E79FF290E01B95)


TDSQL-C是计算和存储分离的架构,因此计算节点和存储节点之间的网络IO存在一定时延。而写事务提交时需要保证redo先刷盘才能完成提交,因此Redo日志刷盘存在网络IO。TDSQL-C在线程池的基础上进行了异步组提交优化,事务提交交给后台线程异步完成,将线程池资源提前释放从而能够去处理更多的请求。优化后整体的读写事务QPS有70%的提升。


**TDSQL-C 高性能-Log Compaction**


TDSQL-C是基于日志的数据库,计算机节点和存储节点之间有日志的传输,同时Master节点和TXStore存储之间也有redo日志传输,TDSQL-C将redo日志进行了压缩。


![file](http://image.openwrite.cn/24379_6A11998D53DA4FD991AE549593BFFA56)


下图是redo日志的结构,一条普通的redo日志包括日志头和日志内容,日志头主要包括日志类型以及Space ID和pageno等信息。通常情况下日志头占了日志的较大一部分。TDSQL-C对redo日志进行压缩存储,对于同一页面进行修改的多条redo日志可以共享一个日志头。优化后redo日志量减少了30%。


![file](http://image.openwrite.cn/24379_E84E10882D1E46E8BD6DB8FC2B0EB029)


# TDSQL-C之高可用


**TDSQL-C 高可用-物理复制**


![file](http://image.openwrite.cn/24379_788B725747DC4905A14CA5764681E1C0)


传统的MySQL的是通过binlog进行复制的。Binlog复制是在MySQL server层进行的,binlog记录的是逻辑的修改记录,binlog在备库apply需要经过server层的parser,optimizer后再经过engine的btree查找才能修改到对应的记录。这个路径比较长,复制速度慢。


而腾讯云TDSQL-C采用的是redo物理复制。Redo日志记录的是页面物理修改记录,redo复制是在engine层进行的,备库apply redo日志不需要查找就可以直接定位到页面,在内存中完成页面的修改。因此复制速度快。


更重要的一点是,TDSQL-C是基于共享存储的,主备数据物理上是一致的,而binlog复制只能保证逻辑一致。


**TDSQL-C 高可用-备库延迟优化**


TDSQL-C高可用另一个优化是备库延迟优化,TDSQL-C最多支持16个备库提供读服务,备库延迟可以达到毫秒级别。其中一个优化就是备库读写IO冲突优化。TDSQL-C备库是提供读服务的,同时备库也会apply主库传来的redo日志。


张远以场景举例说,首先用户读取pageA,pageA不在buffer pool中,那么会从TXStore中请求pageA,TXStore中请求pageA就存在网络和IO的开销。同时redo日志回放线程上有log1/log2/log3正在等待回放到pageA上。也就是说,用户发起的读操作可能阻塞redo日志回放线程,从而导致主备延迟。


![file](http://image.openwrite.cn/24379_89EEDD5328DA4ED3B325D01EF12C8E4D)


优化方案是将pageA上的redo日志缓存到page上的链表中,pageA IO完成以后再将链表中的redo日志回放到pageA上。这样pageA的IO过程就不阻塞redo的回放了。


**TDSQL-C 高可用-独立buffer pool**


TDSQL-C 高可用的另一个优化是独立buffer pool。Buffer pool是InnoDB数据页的缓存。


计算节点HA重启后,buffer pool需要重新加载进行预热,持续时间比较长,期间业务会受到较大影响。


TDSQL-C 将buffer pool从计算节点独立出来放到共享内存中,计算节点crash后buffer pool可以独立存在。这样一来,Buffer pool 不需要预热,重启时间也缩短了。


**TDSQL-C 高可用-秒级RTO**


TDSQL-C在基于redo日志的架构下,计算节点crash recovery不需要apply redo,redo的apply由存储节点来完成。从而crash recovery时间相比传统MySQL要快很多。在此基础上,TDSQL-C做了更多的优化,可以做到秒级RTO。例如经过测试,大规格实例重启速度比较慢,例如buffer pool为500G的大实例重启,初始化buffer pool耗时23秒,这对于用户来说是不可接受的。优化方案是并行初始化加pag上的mutex延迟初始化。并行初始化是指按InnoDB buffer pool instance来并行初始化。而page mutex延迟初始化,是指当page首次使用时才初始化,而不是在启动时全部都初始化。优化后buffer pool初始化速度提升近20倍,而且腾讯云将这个方案也贡献给了MySQL官方。另外回滚段并行初始化也贡献给了MySQL官方。


**TDSQL-C 之弹性扩展**


TDSQL-C 备库可以提供读服务。为了提供更好的读服务,腾讯云做了许多读优化。Btree一致性读优化就是其中一个。


Btree在数据的更新过程中会发生SMO操作,即btree的分裂或合并。


![file](http://image.openwrite.cn/24379_D240F06A48164DABA7AE97492C54DAC1)


如图所示,Btree发现分裂,page B分裂为pageB和pageC。Btree分裂时,用户查询pageB可能导致数据不一致甚至crash。但主库在Btree发生分裂时会通过index锁和page lock的方式保证正在发生分裂的page不被其他用户访问。但对于备库来说,备库通过redo日志不能感知Btree的SMO操作,SMO操作所产生的日志只有页面修改的信息,redo日志中没有index lock上锁信息。因此备库在SMO过程是没有被保护的,备库的查询可能异常。


这里有一个可选方案就是将SMO操作index lock记录到日志中,备库解析index lock日志对整个btree加index lock。但index lock会锁整个btree导致并发查询性能比较差。


![file](http://image.openwrite.cn/24379_327013392D7C42CEA8FAB5AF4AF15569)


TDSQL-C对此进行了优化,MySQL的SMO操作是原子的,所有产生的redo日志都在一个mini-transaction中。引入新的日志类型来标记redo日志中SMO操作的边界。这样用户在查询btree过程遇到page在SMO操作重新扫描btree即可。例如用户访问page A时会判断一下page是否在SMO,如果A在在mtr start和end之间则重试。


这样优化后,备库读不会被主库更新产生的SMO操作所阻塞。


# TDSQL-C 其它特性


**TDSQL-C 秒改列(instant modify column)**


在官方MySQL8.0支持instant add column后,修改列类型操作便顺势成为MySQL中最不友好的DDL类型,修改列类型既不是inplace的同时也需要rebuild table。而在我们用户实践中,修改列类型也是用户执行比较频繁的DDL之一,而此操作会长时间阻塞用户的读写请求,对业务的影响非常大。


TDSQL-C创新的支持了instant modify column功能,达到了秒级修改列的效果。


![file](http://image.openwrite.cn/24379_436C18132BDE41589B4458911467CC15)


**具体的实现方式是:**


元数据多版本化, 表元数据保存列的多个版本信息,用户只能看到的总是最新的表元数据。


行记录增加版本信息对应到不同版本的表元数据上。


修改列只修改元数据,修改列的过程中不修改实际的行记录。


行记录读取时,老版本记录会自动转换为最新版本的记录。


行记录更新时,老版本记录会自动更新为最新版本的记录。


值得注意的是,这是业界首创的方案。


**TDSQL-C purge预读**


Undo 空间膨胀问题是MySQL历史老大难问题,TDSQL-C创新的通过purge预读解决了此问题。


Purge会读取undo page并清理delete mark的记录,清理完成后会释放undo page,从而最终释放undo表空间。


IO bound场景, purge时读取undo page更容易出现remote IO。而remote IO时占用时间比较长,导致purge不及时undo日志空间膨胀。


解决方法是实现purge预读机制:根据事务提交顺序在内存中保存undo page的purge顺序用于预读。Purge coordinator异步预读这些page。


![file](http://image.openwrite.cn/24379_D9A1CA7D6ECA4089869C421E4C34E650)


# TDSQL-C展望 


展望TDSQL-C的未来发展,张远表示,未来TDSQL-C会进一步加强查询优化的能力,比如增加新的join类型如SMJ, 以及在parallel query上做一些拓展。同时TDSQL在支持多写方面会进一步探索,未来TDSQL-C也会向HTAP方向演进,TDSQL-C会同时具备OLTP和OLAP的能力。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69940575/viewspace-2793854/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2020-01-08

  • 博文量
    188
  • 访问量
    82579