找回密码
 立即注册
首页 业界区 安全 技术解读 | OceanBase高并发场景下的性能保障 ...

技术解读 | OceanBase高并发场景下的性能保障

裒噎 昨天 22:13
本文摘自《OceanBase社区版在泛互场景的应用案例研究》电子书,点击链接获取完整版内容。
作者:高山岩,OceanBase资深技术专家
海量数据日益增长的今天,越来越多的业务系统面临高并发、高性能访问的压力,以至于企业对业务系统的性能保障诉求越来越强烈。数据库系统作为业务系统的基础组件,具备高并发、高性能的能力,是支撑业务系统、满足客户诉求的关键。本文通过阐述数据库组件的设计,解读做好系统性能保障的关键因素。
通过内核组件的合理设计,保障系统性能

作为连续12年保障“天猫双11”大促活动以及用于支付宝核心系统的数据库,OceanBase久经高并发场景的多重性能考验。2025年3月,OceanBase性能再次升级,在同等的硬件规模下(16 核配置),经过 Sysbench 标准测试集的实际测试(见图1),其单机版在整体性能(包括查询、批量读取、写入、读写混合、插入和更新操作)方面全面优于 MySQL 8.0。特别是在高并发写入场景中,吞吐量实现了显著提升,最高提升达到 214.99%,能够满足高负载场景下的业务需求。
1.png

图1 Sysbench 性能基准测试对比(OceanBase 单机版VS MySQL 8.0)
OceanBase的高性能离不开系统内核各个组件的设计与实现,主要包含高效的计划管理、并发控制、多维度缓存优化、热点行优化、日志聚合优化和编译优化等方面。下文将分别解析各模块,为大家揭开高性能的神秘面纱。
(一)高效的计划管理

1.计划缓存。
SQL语句的优化是一个比较耗时的过程,随着SQL语句的复杂度增高,优化的时间也会越来越长。为了避免反复执行优化过程,生成的执行计划会加入计划缓存中,以便再次执行该SQL时使用。每一个租户在每一台server上都有一个独立的计划缓存,用以缓存在此server上处理过的SQL计划。
在应用系统中,同一条SQL每次执行可能会使用不同的参数,为了减少计划缓存的大小,系统会首先将用户SQL的参数做参数化处理,得到与具体参数无关的SQL字符串,并使用该字符串作为计划缓存的键值。计划缓存是一个典型的Key-Value结构,Key就是参数化后的SQL字符串,Value就是该条SQL所对应的执行计划。在OceanBase的计划缓存中,SQL的执行计划可以分为本地计划、远程计划和分布式计划三种类型。在计划缓存中,同一条SQL根据其需要访问的数据不同,可能同时有这三种执行计划。对于某一条SQL的某一种执行计划,默认情况下OceanBase只会保留一个计划,该计划由第一次执行SQL时生成;但在某些情况下,同一条SQL的参数值可能会影响到计划的选择,计划缓存可能会根据需要,为不同的参数值保留不同的执行计划,从而保证每次执行时可以使用最合适的计划。
2.快速参数化。
有了计划缓存之后,如何快速获取缓存数据,是需要考虑的另一个问题。传统数据库在进行参数化时一般是对语法树进行参数化,然后使用参数化后的语法树作为键值在Plan Cache中获取计划,而OceanBase使用的是词法分析,对文本串直接参数化后作为Plan Cache的键值,因此叫做快速参数化。具体流程如图2所示。
2.png

图2 基于快速参数化的获取执行计划过程
计划缓存的优化,减少了计划生成的重复动作。快速参数化,省去了语法分析的过程,与此同时,相比对参数化后语法树做Hash和比较操作,对文本串进行Hash和MemCmp操作,效率更高,提升了从计划缓存中获取计划的效率。两个优化本质上均降低了CPU的开销,从而提升系统的吞吐能力。
(二)并发控制

1.数据管理。
OceanBase 存储引擎采用的是 LSM tree 架构,数据分成静态和动态数据。动态数据保存在 Memtable 中并定期 dump 到磁盘中,Memtable 采用 B+tree 以及Hash 双索引结构对数据进行存储,其中 B+tree 用于范围查询,Hash 用于单行查询。B+tree 的叶子节点保存了行数据的元信息,关键的3个字段:主键、锁以及链表指针,如图3所示。
3.png

图3 memtable内存数据结构图(行上的多次修改)

  • 锁信息表示是否有事务持有行锁,事务在修改数据之前需要先加行锁。
  • 链表信息指向多个版本的数据,每个版本只保存增量信息,比如某一次修改只修改一个字段,增量信息只会记录该字段的变化情况。
  • 对于尚未提交,已经转储到静态数据中的行,静态数据会进行特殊标记,用于行锁存在与否的判断。
2.并发控制。
OceanBase 基于MVCC和行上的互斥锁,实现了并发控制,主要特点如下:

  • 快照版本一个时间戳,通过比较时间戳的大小就可以确定事务的可见性。因此,相比其他数据库系统,OceanBase不需要维护全局事务管理器,高并发场景下,不存在全局事务管理器访问瓶颈的问题。
  • OceanBase 行的元数据上保存了锁信息,同样也不需要额外的锁管理器。
  • 读操不加行锁,写操作加行上的互斥锁,做到了读、写不相互阻塞,提升了高并发场景下的吞吐。
4.png

图4 memtable内存数据结构图(读写请求逻辑)
(三)多维度缓存

上文提到,OceanBase 存储引擎采用的是 LSM tree 架构,其存储引擎整体架构如图5所示。
5.png

图5 OceanBase存储引擎架构图
通常来讲,LSM架构的查询,需要将静态数据和动态数据做merge,经过投影之后再返回给客户端。对于多级的sstable,这无疑会增加执行路径。为了提升查询效率,OceanBase设计多级缓存策略,具体包括以下5项。
(1)Block Cache:类似于Oracle的Buffer Cache,缓存具体的数据块,实际上Block Cache中缓存是解压后的微块,大小是变长的。
(2)Block Index Cache:缓存微块的索引,类似于Btree的中间层,在数据结构上和Block Cache有一些区别,由于中间层通常不大,Block Index Cache的命中率通常都比较高。
(3)BloomFilter Cache:BloomFilter是一种结构,可以帮助加速对空查询的过滤,有助于提升insert的性能。OceanBase的BloomFilter是构建在宏块上的,按需自动构建,当一个宏块上的空查次数超过某个阈值时,就会自动构建BloomFilter,并将BloomFilter放入Cache。
(4)Row Cache:Row Cache缓存具体的数据行,在进行Get/MultiGet查询时,可能会将对应查到的数据行放入Row Cache,这样在进行热点行的查询时,就可以极大地提升查询性能。
(5)Fuse Row Cache:跟row cache的差异在于,fuse row cache缓存的是当前系统中动、静态数据merge之后的值,对于高频的数据访问,可以直接访问fuse row cache;
(四)热点行优化

随着在线交易、电商行业的发展,业务系统的热点并发压力逐渐成为一种挑战。热点账户短时间内余额大量更新,或者热门商品在营销活动中限时抢购,都是这种场景的直接体现。热点更新的本质是短时间内对数据库中的同一行数据的某些字段值进行高并发的修改(余额,库存等),这其中的瓶颈主要在于关系型数据库为了保持事务一致性,对数据行的更新都需要经过 “加锁->更新->写日志提交->释放锁” 的过程,而这个过程实质上是串行的。因此,提高热点行更新能力的关键在于如何尽可能缩短持有锁的时间。为了缓解热点行更新的问题,OceanBase提出了提前解行锁(Early Lock Release)的优化方案,其原理见图6。
6.png

图6 提前解行锁原理
1.优化前。
在用户发起 COMMIT 操作后,数据库(DB)端会触发日志的持久化流程。这个过程包括以下4个步骤:
(1)将内存中的数据序列化并提交给本地的 Log buffer。
(2)数据库将日志数据发送到所有备机。
(3)等待多数备机同步日志成功后,数据库才认为日志持久化成功。
(4)最终解锁事务,并向客户端返回事务提交成功的应答。
在此流程中,一个事务的持锁时间包含以下几个部分:数据写入、日志序列化、同步备机的网络通信、日志刷盘的时间。对于三地五中心部署或者磁盘性能较差的情况,持锁时间较长,容易对热点行产生显著的性能影响。
2.优化后。
在数据库优化方案中,整体提交流程基本保持不变,但对解锁时机进行了调整。在新的流程中,当日志序列化完成并提交给 Log buffer 后,立即触发解锁操作,而不再等待多数备机的日志刷盘完成。这样可以有效减少事务的持锁时间。事务解锁后,允许后续事务对同一行进行操作,实现了多个事务并发更新同一行的效果,从而提升了系统的吞吐量。
该优化生效的前提是OceanBase内核保证了以下关键特性:

  • 提前解锁的事务如果最终发生了回滚,后续凡是读到该事务信息的事务都需要回滚,我们称之为级联回滚;
  • 提前解锁的事务尚未应答客户端之前,后续凡是读到该事务信息的事务,都不能提前应答客户端;
  • 只支持单机事务使用ELR优化,降低级联回滚的概率。
3.优化效果。

基于上述优化方案,热点行场景下的性能可以通过以下公式计算:
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册