阿里云PolarDB单机性能优化揭秘:TPC-C测试登顶背后的技术秘密

阿里云PolarDB在TPC-C测试中登顶,本文揭秘其单机性能优化内幕,涵盖高并发、CPU效率、IO链路及复制性能等多方面。

原文标题:揭秘技术内幕|数据库单机性能是如何优化的?

原文作者:阿里云开发者

冷月清谈:

本文深入解析了阿里云PolarDB在TPC-C基准测试中取得优异成绩背后的单机性能优化策略。PolarDB通过共享存储架构,实现了计算节点和存储节点分离,解决了传统数据库在扩展性和性能上的瓶颈。针对TPC-C测试的四个核心特征——海量用户连接、高CPU占用和内存访问、高IO吞吐、更长的日志写入链路,PolarDB分别采取了高并发优化、CPU和内存效率优化、IO链路优化以及复制性能优化等方案。高并发优化方面,PolarDB引入了PolarIndex、PolarTrans、多级分片Buffer Pool和全异步执行架构;CPU和内存效率优化方面,PolarDB采取了乐观开表复用和存储过程缓存机制;IO链路优化方面,PolarDB提出了PolarIO解决方案,通过软硬协同的方式提供媲美本地盘的I/O延迟能力;复制性能优化方面,PolarDB基于RDMA降低网络传输时延,并采用全链路并行的复制框架。通过这些优化,PolarDB在TPC-C测试中取得了显著的性能提升。

怜星夜思:

1、PolarDB通过共享存储架构实现了计算和存储分离,这种架构相比传统数据库有哪些优势和劣势?在实际应用中,你觉得什么样的场景更适合使用这种架构的数据库?
2、文章中提到了PolarDB针对高并发场景做了多项优化,例如PolarIndex、PolarTrans等。这些优化方法对于其他类型的数据库是否有借鉴意义?如果让你设计一款高并发数据库,你会优先考虑哪些方面的优化?
3、PolarDB通过PolarIO解决了IO瓶颈,其中提到使用了AliSCM高速设备。你怎么看待数据库对新型硬件的依赖?未来数据库的发展方向是否会越来越依赖于硬件的创新?

原文内容


背景信息

传统的关系型数据库有着悠久的历史,从上世纪60年代开始就已经在航空领域发挥作用。因为其严谨的一致性保证以及通用的关系型数据模型接口,获得了越来越多的应用。2000年以后,随着互联网应用的出现,很多场景下,并不需要传统关系型数据库提供的一致性以及关系型数据模型。由于快速膨胀和变化的业务场景,对可扩展性(Scalability)以及可靠性(Reliability)更加需要,而这又正是传统关系型数据库的薄弱之处。此时,新的适合这种业务特点的数据库出现,就是我们常说的NoSQL。但是由于缺乏一致性及事务支持,NoSQL被很多业务场景拒之门外。缺乏统一的高级的数据模型和访问接口,又让业务代码承担了更多的负担。数据库的历史就这样经历了多重否定,又螺旋上升的过程。

PolarDB就是在这种背景下出现的,由阿里巴巴自主研发的下一代关系型分布式云原生数据库。在兼容传统数据库生态的同时,突破了传统单机硬件的限制,为用户提供大容量、高性能、高弹性的数据库服务。[1]

核心技术之共享存储

PolarDB采用了共享存储(Share Storage)的整体架构。采用远程直接数据存取(Remote Direct Memory Access,以下简称RDMA)高速网络互连的众多区块服务器(Chunk Server)一起向上层计算节点提供块设备服务。一个集群可以支持一个主(Primary)节点和多个二级(Secondary)节点,分别以读写和只读的挂载模式通过RDMA挂载在Chunk Server上。

PolarDB的计算节点通过libpfs挂载在PolarStores上,数据按照Chunk为单位拆分,再通过本机的PolarSwitch分发到对应的Chunk Server。每个Chunk Server维护一组Chunk副本,并通过ParallelRaft保证副本间的一致性。PolarCtl则负责维护和更新整个集群的元信息。

日前,阿里云PolarDB云原生数据库以超越原记录2.5倍的性能一举登顶TPC-C基准测试排行榜,以每分钟20.55亿笔交易(tpmC)和单位成本0.8元人民币(price/tpmC)的成绩刷新TPC-C性能和性价比双榜的世界纪录。每一个看似简单的数字背后,都蕴含着无数技术人对数据库性能、性价比和稳定性的极致追求,PolarDB的创新步伐从未止步。

一、TPC-C 是什么?

TPC-C 基准测试模型是由国际数据库事务性能委员会 TPC 组织制定的针对衡量OLTP系统性能的基准测试,涵盖了数据库的增删改查等典型处理路径,最终性能以 tpmC (transaction per minute,每分钟订单创建的数目)来衡量。TPC-C 测试模型能够直接和客观地评估出一个数据库的性能表现,是全球最具公信力的测试标准。

本次TPC-C基准测试使用的是PolarDB for MySQL 8.0.2版,作为阿里云瑶池数据库自研的旗舰产品云原生数据库 PolarDB 通过 90 多种单机优化和性能提升方式,将单核性能提升了1.8 倍(对比原纪录),取得了数据库领域的里程碑式成就。本文将揭秘 PolarDB 单机优化的技术内幕

在打榜过程中,通过对数据库压力模型的深入分析,我们梳理了以下4个核心特征及对应的优化方案:

  • 海量用户连接 → 高并发优化

  • 高 CPU 占用和内存访问 → CPU 和内存效率优化

  • 高 IO 吞吐 → IO链路优化

  • 更长的日志写入链路 → 复制性能优化

这4个特征也是真实线上用户业务常见的性能瓶颈,下面我们将简述 PolarDB 的整体性能链路,再基于这4个典型特征,分别介绍单机性能链路上做的关键优化。

二、PolarDB 性能链路

作为共享存储的云原生数据库,PolarDB 不仅提供了超强易用性(快速备份和恢复,高可用),以及超强弹性(存储/计算解耦)的能力,还通过软硬协同演进,提供了和本地盘一致的 I/O 时延能力和更强的 IOPS 能力,使得在性能、易用性、扩展性三方面都做到了极致。

传统部署在本地盘的 MySQL 架构,受益于本地盘的低 I/O 时延,但也存在着存储容量有限,弹升困难的限制,并且跨机主备复制的高时延,也掩盖了本地盘在性能上的收益。对于直接部署在云盘的 MySQL 架构,虽然能够利用云盘的存储资源的扩展性和高可用,但云盘的高时延又无法发挥 MySQL 的性能,并且无法做到计算资源的横向扩展。

为了解决性能和扩展性的问题,用户会考虑分布式数据库,但存在业务改造大,运维成本高等问题,PolarDB 通过 Proxy 到底层存储的全链路软硬协同优化,很好地解决了这三点。

图1:兼具高性能,易用性和扩展性的PolarDB

图2 展示了 PolarDB 的整个性能的优化链路概览,用户连接的 SQL 查询通过代理的转发,到达数据库内核,通过 SQL 解析、索引查找,最终通过文件系统到达磁盘存储。整个性能优化链路横跨了从上层的 Proxy 代理到底层存储,PolarDB 通过全链路的性能优化,使得在高压力的 tpcc 负载下,保持高效事务处理性能。

图2:PolarDB 性能链路概览

三、高并发优化

首先对于 TPC-C 基准测试负载的第一个典型特征:海量的用户连接,在 PolarDB 的集群测试中,客户端一共创建了 16 亿的用户连接,即便通过多级的连接池,到达单个数据库节点的用户连接仍然达到 7000+,这对数据库的并发处理能力提出了考验。

(一)PolarIndex

为了解决大量并发在索引写入上的锁瓶颈,PolarDB 提出了高性能的 Polar Index,以提升多线程并发的索引读写性能。

在 Polar Index 1.0 上,解决了因为全局索引锁而不允许并发分裂和合并(SMO)操作问题,每次遍历索引,遵循 latch coupling 的原则,即成功获取下个节点的写锁时才释放父节点写锁,将 SMO 分解为多个阶段,允许了 SMO 期间分裂节点的并发读取。

在 Polar Index 2.0 版本,PolarDB 进一步优化了索引的加锁粒度,和 latch coupling 相比,每次对 btree 的自上而下遍历,只拿一个节点的锁,同时优化 SMO 为自底向上的加写锁顺序,缩短了锁范围更大的上层节点加锁时间,允许更高的并发读写操作。

PolarIndex 的高性能读写使得 TPC-C 基准测试中,索引的并发读写不再是写入的瓶颈。

图 3:PolarIndex 的多阶段 SMO 流程

(二) PolarTrans

为了解决大量并发在事务系统上的扩展瓶颈,PolarDB 提出了无锁的事务管理系统 PolarTrans,提高事务提交和可见性判断的效率。

原生 Innodb 存储引擎,事务系统维护一个全局集中的活跃事务列表,通过一个全局锁保护,事务操作存在扩展性瓶颈。PolarTrans 使用提交时间戳技术(CTS),通过 CTS log 每个事务 id 和 事务提交序列号(CSN)的映射关系,并进行大量无锁优化,使得事务状态的操作逻辑更加轻量。

在事务启动,只需要将事务在 CTS log 中注册即可,提交时在 CTS log 标记提交的 CSN,在可见性判断时,通过事务系统的最大提交时间戳来代替原生活跃事务数组,极大地提高了事务管理的效率。

图 4:CTS log 的实现

(三)多级分片 Buffer Pool

为了解决大量并发访问在 buffer pool 缓存的扩展瓶颈,PolarDB 使用了多级分片的 buffer pool 缓存系统。

PolarDB 将访问拆分到多个 LRU 缓存上,并采用异步的 LRU manager 线程进行 LRU 链表尾部 page 的淘汰,前台用户线程不主动淘汰 LRU 的 page,避免增加事务处理的 CPU 时间。

LRU manager 与 LRU 链表数目采用一对多关系,LRU manager 通过维护空闲页的堆结构,每次从中选择空闲页最少的 LRU 链表扫描尾部的淘汰区,刷写脏页,提供内存空闲页给前台线程,避免了大量后台线程切换。

对于 I/O 密集型的负载,为了减少关键 page 淘汰和频繁移动数据页位置带来的锁开销,PolarDB 在 LRU 链表的头部建立 hot cache list,对于特定 page(索引中间页,元数据页)和根据频率识别的热点表会被优先放入 hot cache,减少淘汰频率。

图 5:多级分片 Buffer pool 的实现

(四)全异步执行架构

为了解决传统线程模型下高并发请求导致的 CPU 争抢、频繁上下文切换等问题,PolarDB 设计了基于协程的全异步执行架构,实现了鉴权、事务提交、锁等待等核心逻辑的异步化执行,显著提升数据库的高并发处理能力。

1.全异步架构设计

PolarDB 通过引入协程技术,将用户请求的生命周期与物理线程解耦,重构为全异步执行模型:

  • 请求协程化:事务请求被封装为独立协程,由用户态调度器管理。

  • 主动让出机制:协程挂起后释放执行权,调度器立即切换到其他就绪协程。

  • 资源高效复用:单线程可并行处理数百个协程,降低线程的调度开销。

2.协程通信机制

PolarDB 设计了基于 eventfd 的轻量级通信协议。每个协程绑定独立的 eventfd 作为信令通道,当协程挂起时,由 epoll 线程实时捕获事件;资源就绪后,通过写入 eventfd 触发信号,立即唤醒挂起线程。该机制突破传统线程广播唤醒的局限,实现三大提升:零无效唤醒、纳秒级响应及百万级并发管理能力。

图 6:异步执行逻辑

四、CPU 和内存效率优化

在 TPC-C 基准测试中,大量的 SQL 的解析执行和数据表的访问仍然会消耗较多的 CPU 和内存资源。PolarDB 针对表元数据管理,存储过程等模块做了深入分析,做了大量节省 CPU,提高计算效率的工作。

(一)乐观开表复用

对于结构化数据库,在做 DML 前需要持有表的元信息锁进行操作,识别行结构的同时,也避免其他 DDL 造成数据的不一致。

对于传统悲观加锁,用户线程每次执行 SQL 访问数据前,都需要生成所有表的元信息,并加元数据锁(MDL),在执行完事务后释放。这是极大地消耗 CPU 时间的,尤其是事务通常是由数十条 SQL 组成,每次循环执行时,CPU 开销更加被放大。

PolarDB 实现了乐观的开表复用机制,为执行重复事务的连接,减少其每次重复构建和销毁表的元信息操作,以及重复加/解 MDL 锁的开销。通过维护一个连接的私有缓存,保存将事务访问的数据表和用户连接信息,提供给下次事务执行复用,如果访问的数据表是私有缓存的子集,可以复用已缓存的表元信息和 MDL 锁。为了避免死锁发生,如果访问新的数据表或者断连后,会清空私有缓存和释放对应的 MDL 锁,重新走悲观加锁流程。

图 7:乐观开表复用优化

(二)存储过程缓存机制

TPC-C 事务执行依赖存储过程的解析和执行,存储过程的执行效率极大决定了事务处理性能。

为了提高存储过程的执行效率,PolarDB 针对存储过程的缓存机制做了以下优化。

  • 将用户连接级别的结构缓存转换为全局级别的结构缓存,避免因大量的连接造成内存使用过多,从而来提高 buffer pool 的 page 内存,减少 I/O 开销。

  • 实现存储过程中 SQL 的 prepare 结果缓存,结合乐观开表,将需要绑定的数据表的列信息缓存在 SQL 表达式的 item 中,避免每次存储过程调用时的重复 prepare 开销,造成 CPU 浪费。

  • 实现执行计划缓存,并基于索引统计信息固化简单 SQL 的执行路径,如单主键索引查询,无索引的范围查询,避免优化器下潜到存储引擎,占用额外 I/O 和 CPU 资源。

图 8:PolarDB 存储过程的缓存机制

五、IO 链路优化


TPC-C 一次事务的执行可能涉及数十次读 IO,使得事务的数据访问性能高度依赖于磁盘 I/O 的性能。

PolarDB 针对 IO 链路提出了一套 PolarIO 解决方案,如图 9 (a) 所示,从存储引擎 Page 和 Redo I/O 两大主要类型出发, 对 Buffer Pool,Redo buffer,I/O 队列进行改造,最后通过自研用户态文件系统 PFS ,持久化到底层的弹性存储中。

除了前文介绍的 buffer_pool 模块,图 9 (b) 展示了 PolarDB 并行 redo 写入的设计,将 redo buffer 划分为多个分片,并发地发出异步 I/O 的任务,结合异步的 redo prepare 机制(如 redo 对齐,checksum 计算)等。在高 redo 压力的实测中,PolarDB 的 redo 吞吐就能达到 4GB/s。

图 9: PolarIO 解决方案和并行 redo 日志落盘

在 PolarIO 解决方案中,另一关键是文件系统和底层存储的持久化,在写路径上,数据通过 PolarFS 写入 PolarStore ,经过 100Gb loosy RDMA 网络写入有接近内存的延迟的高速设备 AliSCM 中。在读路径上,PolarDB 基于 DRAM 和 AliSCM 构建的百TB级的超大弹性内存池。整个 IO 全链路 ByPass Kernel 实现软件栈,I/O 路径无任何内存Copy,有极低的软件栈开销,通过软硬协同的方式提供媲美甚至优于本地盘的I/O 延迟能力。

六、复制性能优化

TPC-C 在故障容灾测试中,要求数据库采用半同步的事务提交,即事务提交前,要保证 redo 日志通过网络传输到备节点的另一台主机,这样在主节点发生机器故障后,能正常从备节点恢复。

但是,跨机的复制链路带来了两方面的影响:

  • 复制链路延长了事务等待日志持久化的时间。

  • 在主节点高负载的写入下,备节点也需要更强的复制能力。

为了解决因跨机复制的性能问题,PolarDB 基于 RDMA 的低延迟优势,降低了网络包传输的时延。并且专门维护了复制同步使用的 redo cache,使用了异步的并发链路提高 redo 传输的吞吐。并使用多信号量的唤醒机制,防止事务无效唤醒。

PolarDB 在备节点使用全链路并行的复制框架,整个 PolarDB 的复制流程从 redo log 的读取,解析和应用都做了并行处理。基于备机的并行复制优化,在 TPC-C 的 20 亿 tpmc 测试压力下,备机的复制延迟维持在毫秒级别。

图 10:PolarDB 主从同步链路和并行复制框架

七、总结

TPC-C 的压力模型涵盖了对 CPU 和 IO 资源全面测试,极大考验了数据库内部大部分模块的并发执行和协同效率。PolarDB 结合实际应用场景,持续不断地对数据库进行性能优化,尽可能地让每个核都能物尽其用,充分发挥最优的性能。

欢迎点击阅读原文实际体验具体场景「PolarDB MySQL 列存索引加速复杂查询」

[1]:

https://help.aliyun.com/zh/polardb/polardb-for-mysql/what-is-polardb-1?utm_content=g_1000403483


极速突破,PolarDB MySQL 列存索引加速复杂查询


本方案为您介绍如何通过云原生数据库 PolarDB MySQL 版列存索引(In-Memory Column Index,简称 IMCI)实现大数据量场景下的高性能复杂查询。


点击阅读原文查看详情。

数据库对硬件的依赖是必然的,软件优化终究有上限。AliSCM这种高速存储介质能极大地提升IO性能,未来数据库的发展趋势一定是软硬件协同优化。单纯的软件优化无法突破硬件的限制,而硬件的潜力需要软件来挖掘。

高并发?听着就头大!我只想用现成的,谁爱优化谁优化。不过话说回来,如果非要我优化,我会选择加钱!加钱上更好的硬件,比什么优化都快!

PolarIndex和PolarTrans的核心思想是减少锁竞争,这在任何高并发场景下都是通用的优化思路。设计高并发数据库,我会优先考虑:1. 无锁数据结构的应用;2. 异步化处理;3. 连接池和请求队列的优化;4. 读写分离和缓存机制。

从数据库理论上讲,共享存储避免了数据冗余,简化了数据一致性维护,但实现起来复杂度较高,对网络要求也高。感觉适合那些对数据一致性要求高,同时又能容忍一定延迟的应用场景,比如金融行业的某些核心系统。当然,前提是RDMA技术足够成熟可靠。

我觉得最有借鉴意义的是PolarTrans。解决并发事务的关键就是怎么高效管理事务状态,CTS log这个思路很巧妙,通过时间戳来判断事务可见性,避免了全局锁,很值得学习。如果要我设计,我会先搞定事务并发这块,然后再考虑其他优化。

共享存储听起来很高大上,但是感觉就像是把磁盘阵列放到了云上一样。优势肯定是省成本,动态扩容方便,劣势嘛,万一存储挂了,整个集群都遭殃。所以说,鸡蛋不能放在一个篮子里啊!

我觉得硬件是基础,软件是灵魂。再好的硬件,没有优秀的软件调度也发挥不出作用。未来的数据库应该更加智能化,能够根据硬件特性自动调整优化策略,这样才能充分利用硬件的优势。

共享存储架构的优势在于扩展性强,计算节点可以独立扩展,存储容量也可以灵活调整。但同时也带来了网络延迟的问题,需要RDMA等技术来优化。个人觉得对于需要弹性伸缩、数据量增长迅速的业务,例如电商、在线游戏等,共享存储架构的数据库会比较合适,能更好地应对业务高峰。

有没有人跟我一样,看到AliSCM就想到SSD?感觉数据库厂商都在疯狂堆硬件,但是价格也水涨船高。什么时候能用上便宜又快的存储设备啊,哭唧唧。