以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase

2024年 5月 7日 40.4k 0

作者简介:赵旭东(花名航野),蚂蚁集团数据库技术专家。

2022年3月24日, OceanBase 开源社区为大家展开了《深入浅出 OceanBase 》系列第一期直播分享,来自蚂蚁集团的数据库技术专家赵旭东(花名:航野)为大家分享了《 OceanBase 性能调整与优化》。本次分享从 OceanBase 架构、部署环节、初始参数、事务特性、schema 和 SQL 等视角介绍高并发场景下 OceanBase 的性能调整与优化方法,旨在通过多样化的方式,助力 OceanBase 发挥更好的性能。鉴于性能调优涉及内容比较多,无法将所有内容一次性全部讲解清楚,所以本文结合了蚂蚁的使用场景,尝试从几个不同的角度来聊聊性能调优这件事。希望通过这篇文章,大家能对 OceanBase 的性能调优有更深入的了解。

一、从 OceanBase 存储引擎看性能优化

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-1

上图展现的是 OceanBase LSM Tree 存储引擎架构图。OceanBase LSM Tree 存储架构由两部分组成,一部分是磁盘数据 SSTable;另一部分是增量内存数据 MemTable ,我们先从内存数据 MemTable 看起:

业务写入的数据先存在内存里,所以有时候我们也把 OceanBase 称之内存数据库,在转储的时候才会落盘。

在查询上,OceanBase 有特殊的缓存优化机制。OceanBase 首先采用 bloomfilter 逻辑,如果命中不到,则会再查 row cache,如果 row cache 也没有,才会查 block cache,block cache 再没有,才会从转储和基线的 sstable 里把数据加载到缓存。OceanBase 引入 rowcache 可以在热点数据查询场景下,大幅提升查询性能。

另外,增量数据 MemTable 的内存结构上也有优化,MemTable 有两种组织形式:hashtable 和 btree ,hashtable 优化单值查询场景性能,btree 则优化范围查询场景性能。

接着我们看下磁盘数据 SSTable:

从内存 dump 到磁盘的多个转储版本的 SSTable 达到指定个数时,会触发增量转储数据和基线数据的合并,产生一个新版本的基线数据。

这样的读写分离架构和传统的数据库 MySQL,Oracle 有很大区别,该 LSM Tree 架构也是 OceanBase 高性能的基础。基于这个架构,业务写入的数据异步批量入盘、连续存储,特别适合做数据的编码和压缩,采用数据编码和压缩不仅可以降低存储成本,还可以带来额外的性能提升。

为什么采用数据编码和压缩可以提升性能呢?

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-2

由图可知,编码不影响增删改查,主要有2点依据:

1.数据编码作用对象是列,编码后的数据不需要解码,直接支持查询

2. 同时一个数据块在编码后可以容纳更多的数据,同样磁盘吞吐量的情况下,可以加载更多的数据,OceanBase 的 IO 性能也随之提升了。

所以,OceanBase 数据编码只在集群合并时有开销,对业务增删改性能无损,对部分场景查询性能有提升。

OceanBase 实现了多种数据编码方法,并会自动根据数据特征为每一列选择最合适的数据编码。编码的压缩比受列的数据特征和微块大小影响比较大,一般来说微块长度越大,数据的压缩比会高一些,但相应的一次 IO 读的代价也会越大;微块长度越小,数据的压缩比会越低,但相应的一次 IO 读的代价会更小。微块的默认大小为 16KB,蚂蚁线上 OLTP 使用的也是默认配置,但面对 OLAP 场景,我们可以根据自身业务的测试结果,适当调整一下微块的大小,选择更合适的微块大小。

数据压缩对比数据编码,不光在合并时有开销,在查询被压缩数据前,OceanBase 还需要对数据块进行解压。根据测试,我们从 OceanBase 支持的众多压缩算法里选出了2个能均衡好压缩比和压缩解压速率的算法 lz4 和 zstd,这两个压缩算法是我们线上 OLTP 业务在大范围使用的2种算法。

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-3

再来看上图,该图展现了关于这两个压缩算法的性能。这是蚂蚁内部结合业务数据做的一次压测结果,压测数据是一个 2G 的业务表,微块是 16k 情况下,压缩比和压缩解压速率的表现,实际业务上线前,我们也可以多做一些相关的测试,平衡好压缩比和压缩解压速度,根据压测结果选择更适合的压缩算法,这样既能做到高压缩比降低存储成本,又不影响查询性能甚至达到优化查询性能的目的。

二、为高性能 OceanBase 提供的部署环境

很多同学入门数据库是从安装开始。安装数据库软件前,我们有必要检查一下部署环境是否是对数据库友好。硬件配置上,可以参照官方文档对硬件配置上做的推荐。如果想最大化发挥 OceanBase 的性能,我们还可以考虑在硬件上做一些升级。好的硬件可以让 OceanBase 发挥更优的性能。

除了硬件升级以外,我们的部署环境也可以做一些经过测试的调整,以发挥硬件的最大性能。比如说:

在 CPU 访问内存上,CPU 访问本地内存的延迟会小于访问远程内存的延迟,这个是物理层面的限制,而且现在一般厂商推出的服务器都是双核或者多核,那开启 numa 将带来比较可观的性能提升。

有一些企业部署数据库时会因为 numa 的历史 bug 而倾向于选择关闭 numa,但是 numa 的严重 kernel 层低级 bug 已经在2014年提交修复了,新的内核版本也经过验证没有问题。经过内部测试,开启 numaNPS1 模式,将 OceanBase 进程绑核,同时将网卡软中断绑定到和该网卡更亲近的 numa node,测试下来性能约有一倍以上的提升。

存储上一般不需要考虑做 raid,考虑到单盘故障,做 raid5 就可以了,可以不用考虑做 raid1,这是因为 OceanBase 正常最少是三副本部署,相当于数据已经做了冗余了,没有必要在单机再冗余一份,同时 OceanBase 内部拥有比较完善的 checksum 机制,所以如果是因为硬件导致数据写错,OceanBase 都能识别到。

网络上因为 OceanBase 的 clog 同步、rpc 等对网络开销较大。在高并发场景下,网卡的软中断占比还是比较多,如果不将网卡软中断打散,可能会出现网卡软中断集中在第一个 CPU 上的情况,这里建议所有类型的软中断以 round robin 方式全部打散到所有 core 上面,或者把网卡软中断列表绑定到和该网卡更亲近的 numa node cpu 上。其他操作系统层的配置,大家可以关注一下官方文档里列出的需要关注的系统配置项,下表记录的是蚂蚁生产环境使用的标准优化配置。

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-4

三、初始化参数调优

OceanBase 有很多参数和配置项,绝大多数跟性能相关的参数都可以在 OceanBase 官方文档中找到最佳实践。我们以蚂蚁实际工作为例,抽取出部分调优后对性能影响体感较明显的参数,来做一下重点关注。

cpu_quota_concurrency 租户的每个 CPU 配额所允许的最大并发数

首先是影响租户 CPU 使用的系统参数,这个参数限制了租户的每个 CPU 配额所允许的最大并发数,比方说设置为4,那 2c 的租户最大允许 8个并发,可以认为调整这个参数就是调整租户级的 CPU 线程超卖,对于本身配置规格比较大的租户,不建议再调大这个参数,建议设置为2,保留一定的租户线程隔离能力,降低租户间的 CPU 抢占而产生的相互影响。

转储系统级参数

什么情况下需要关注转储系统级参数呢?当租户的写入压力较大,转储释放的内存赶不上业务写入消耗的内存时,就可以考虑调整这个参数。比如我们可以通过将转储触发阈值 freeze_trigger_percentage 改小,将转储工作线程数 minor_merge_concurrency 和 L0 转储工作线程数 _mini_merge_concurrency 适当调大。这里要说明一下 OceanBase 的转储分 2 层,memtable 冻结后将数据 dump 到磁盘上,生成 L0 级转储 SSTable,我们称之为 mini merge,多个 L0 级转储 SSTable 在后台又会合并成一个 L0 转储 SSTable,称之为 mini minor merge。当到达触发条件时,多个 L0 转储 SSTable和一个 L1 转储 SSTable 又会合并成一个 L1 级转储 SSTable,称之为 minor merge。

转储租户级参数

_enable_parallel_minor_merge 开启单分区并行转储:

比如说如果一个租户写入量很大,但是这个租户比较极端,只有一个表一个分区,那如果租户转储是单线程的,那就会出现转储释放内存不及时的风险,租户内存可能会被打爆。对于一张用户表,可以通过表级参数 tablet_size 来调整并行合并的粒度,当 SSTable 的大小超过表的 tablet_size 时,就会按照 tablet_size 对数据进行拆分,开启并行合并;但一般来说,并行合并的并行度不会超过配置的合并线程数。

_ob_queuing_fast_freeze_min_countqueuing 表删除达到指定行数时开始触发冻结:

首先介绍一下 queuing/buffer 表概念,这个是 OceanBase 的一个 badcase,当用户在某张表上频繁的执行插入并且同时进行频繁离散删除或更新时,可能会遇到一种现象:表中的数据行数并多,但是范围查询性能出现明显下降。这种现象在 OceanBase 中称为 Queuing 表(业务上有时又称 buffer 表)效应,_ob_queuing_fast_freeze_min_count_queuing 这个参数和 queue 表有关,通过调低这个值触发 queuing 表的频繁冻结转储,实现绕开 queuing 表查询性能下降的问题,其原理是这样的:

OceanBase 做数据删除和更新时,同其他数据库一样也是做的标记删除,在转储时,OceanBase 会将连续删除的数据做一下 purge,对不连续的离散的删除是没有做 purge 的 ,这就导致在做索引范围查询时,可能会有大量的逻辑读,OceanBase 目前引入了 buffer minor merge 设计,可以做到规避 queuing 表的这个问题,可以指定表的 mode为 queuing,然后调整表删除达到指定行数时开始触发冻结的阈值,当触发阈值时,会触发 queue 表转储,即可消除掉增量数据里的所有 Delete 标记。

四、部署优化

从部署的角度我们将分享三个例子,看下蚂蚁如何通过部署提升整体性能。

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-5

首先说明下图上带颜色的小方块是不同的副本类型,图中红色小方块代表是全功能主副本;蓝色代表全功能备副本,绿色代表只读副本,黄色代表 log 副本。图中展现了三种部署模式:主主备部署模式、弱读就近访问的部署模式、三地五中心降低事务耗时的部署模式。

主主备部署模式:该模式指的是通过调整租户 primaryzone 将集群里所有租户的压力均衡到各 zone 的一种部署模式。这种模式的特点是使资源充分利用,同时宕机切主的情况下容量也不受损。

弱读就近访问的部署模式:该模式充分利用了业务某些场景的读请求对实性要求不高,容忍一定延迟,通过使用弱读,将全功能备副本和只读副本的资源充分利用起来。弱读的就近访问可以通过 OBproxy 支持。

三地五中心场景如何降低事务耗时:通过降低多数派之间的网络耗时优化三地五中心提交耗时。如图所示,s h 是上海机房,h z 是杭州机房,然后 h y 是河源机房,s z 是深圳机房。假如一个租户在上海有两个全功能副本,同时主也在上海,那可以将第三个副本放在离上海比较近的城市杭州来降低事务提交耗时。这是因为上海跟杭州的网络延迟是五毫秒,而深圳到河源耗时是二十六毫秒。通过在杭州放一个只读副本,事务提交耗时将减少到五毫秒。

同样河源到深圳的耗时是五毫秒,河源到上海的耗时是二十六毫秒。那如果租户的全功能主副本是在河源的话,我们就会就近选择离河源比较近的一个城市,比如说深圳部署一个 log 副本,那这样他事务提交的延迟也同样会降下来。归纳起来,多数派之间的网络耗时降下来之后,整体的事务吞吐量就可以提上来,从而达到性能优化的目的。

五、使用 Partition group 提高事务性能

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-6

Partition Group 简称 PG, 是 OceanBase 在 2.2 版本之后开始的一个重要的性能优化。该功能也是2019年淘宝双11所强依赖的功能。使用 Partition Group 可以有效提高事务提交性能,经测试,其性能可以提升 35%以上。

首先,我们先通过建表语句,对 Partition Group 名词做一个解释。Table Group 是一组表的集合,通过定义 Table Group,用户可以控制一组表在物理存储上的临近关系。特别地,对于包含分区表的 Table Group,它由若干个 Partition Group 组成,每一个 Partition Group 包含每个分区表的一个分区。一般情况下,属于同一个 Partition Group 的所有 Partition,系统会通过自动调度使得他们位于同一台 OBserver 服务器上,且这些分区副本的 Leader 也位于一台 OBserver上。

为什么使用 Partition Group 可以提升速度性能呢?其内部原理在于,该功能将单机多分区事务转化成单 PG 的事务,事务提交由原来的一阶段提交优化成单 PG 提交,由写多条日志,变成写一条日志,从而提高事务提交的性能,同时减少网络及磁盘的开销。

总结一下 Partition Group 的使用场景。首先是需要使用分区表,同时业务没有跨 Partition Group 的事务,或强一致性 SQL。

接下来我们做一下 PG 事务跟其他事务类型的对比,加深一下对 PG 的了解。OceanBase 的事务按照类型可以划分成多机分布式事务、单机多分区事务、单机单分区事务以及 PG 事务。这里只对多分区的事务做比较。OceanBase 多机分布式事务采用的是两阶段提交,根据自身特点做出一些优化。相比于传统二阶段提交,它采用了参与者及协调者。然后事务里面第一个分区,它是默认作为协调者。协调者是一个无状态设计,不需要协调者写额外的日志。

多机分布式事务提交过程中,有网络 rpc 开销,以及写多条日志的开销。单机多分区事务仍然是走分布式事务的流程。每一个分区都需要作为参与者,需要写单独的日志。但是 OceanBase 内部对单机多分区事务也做了优化的,将两阶段提交优化成一阶段提交,网络的 rpc 也优化成不走网络的内部调用,单机多分区事务内多个分区的日志做了合并落盘。

我们再看下 PG 事务,PG 内的分区,他们切主这些动作是在一起的,所以 PG 类型的单机多分区事务可以优化成单 PG 提交,单 PG 提交只需要写一条日志,PG 事务的提交性能接近于单机单分区事务。

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-7

六、使用 PS 、PL/SQL 优化性能

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-8

讲完事务层的优化,我们再来看下客户端和 server之间的通信上可以有哪些优化,首先我们看下 Prepared Statement, PS 市面上很多数据库都是支持这个协议的,通过使用 PS 主要可以带来以下好处:

1.通过 PS 可以避免每次执行均去解析SQL,进而提升SQL的执行效率 

2.PS 中 client 与 server 通信采用 binary protocol,普通的 SQL 使用的是文本协议,用二进制协议可以减少网络的开销 

3.使用 PS 可以有效的防止 SQL 注入

OceanBase 的 java client 和 OBProxy 对 PS 的支持相对其他数据库做了特殊的优化,我们都知道到 PS PRPARE 是有代价的,相对于传统 MySQL 中的 Prepared Statement,OceanBase 的 Java client & proxy 在 session 级别对 PS 进行缓存,业务代码代码调用 close 逻辑时时,Java client & proxy 只会在 cache 中打标记,并不会向 Server 发送发送 销毁 PS 的请求,这样下次业务在 PS prepare 时,可以复用 cache 中的 PS 缓存,从而达到减少 prepare 代价,提升性能。

然后我们再看下 OceanBase 的 pl/sql,OceanBase 既支持匿名块也支持存储过程,pl/sql 在蚂蚁内部也有着比较多的使用场景,比如蚂蚁交易支付场景,预算扣减场景均使用 PS 、pl/sql 获取极致性能,pl/sql 提升性能主要是通过通过预编译和减少客户端与服务器之间的网络交互来实现的,OceanBase pl/sql 使用上是兼容传统数据库 MySQL/Oracle 的,性能提升的原理是一样的

七、提前解行锁提高热点行吞吐量

接下来我们说一个和业务使用场景紧密相关的优化,提前解行锁提高热点行吞吐量。

典型的场景,像秒杀扣库存、营销扣减预算,可能会出现热点行争用导致吞吐量上不去的现象,有些业务可能会去寻求缓存解决热点行的方案,但是缓存方案又要解决缓存和数据库数据一致性的问题,这样在业务实现上也比较复杂。OceanBase 针对热点行性能上不去的问题做了专门的优化:提前解行锁。优化前吞吐量只有几百的热点行,优化后可以有几十倍以上的性能提升。单行热点实验室测试结果能达到1.4w以上的 tps,实际生产单行跑到 7k 以上的 tps,都还是没有抖动的。

下面我们解释下提前解行锁的原理:

正常事务提交的流程是当 OceanBase 收到用户的 commit 请求后,db 端开始触发日志的持久化操作,持久化过程包含这些步骤:本地日志序列化后提交 buffermanager 并落盘,备机同步日志并落盘,等多数派备机同步日志成功之后,日志才算持久化成功,然后才会解锁,最后给客户端应答事务提交成功。

从上面这个图看,很明显一个事务持锁的时间,包括了4个方面:

1.数据的读写、计算操作

2.日志序列化

3.同步备机网络通信

4.日志刷盘的耗时。

对于三地五中心或者磁盘比较差的场景,热点行的性能影响还是比较大。

大家可能会有疑问,提前解行锁做了哪些优化,能让单行热点能力达到上万 tps 呢?大家可以看看下面这张图:

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-9

整个提交流程基本不变,仅仅对解锁的时机做了调整。新方案里面,等日志序列化完成,提交到 buffer manager 之后,就开始触发解锁操作,不再等日志多数派刷盘完成,从而降低了整个事务的持锁时间。当前事务解锁之后,允许后续的事务进来操作同一行,达到多个事务并发更新同一行的效果,从而提高了系统的吞吐能力。

那提前解了行锁后,事务的正确性如何保证呢,这里引入了两个概念,我们将提前解行锁的事务A叫做前驱事务,当前驱事务解锁之后,后面操作同一行的事务会读取到前驱的最新数据,这样后继和前驱产生了依赖,我们称当前事务为后继事务。

提前解锁的事务,并不代表日志一定会同步成功。所以解锁之后,不能立即给客户端应答 commit 成功,需要等日志完成持久化成功之后再决定。

前驱事务如果出现了回滚,后继事务必然需要回滚。前驱没有明确 commit 成功之前,后继事务是不能确定 commit 成功,需要等前驱的状态确定。

八、好的表结构设计带来质的性能提升

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-10

表结构设计的好坏,有时候会影响到性能,有时候表结构的设计,还需要考虑到数据库的数据存储特性。

这里我们举一个线上的例子说明一下:

大家都知道,Oracle 用的比较多的是堆表,MySQL/OceanBase 用的比较多的是索引组织表。假设表是从 Oracle 迁移到 OceanBase 的,是一个账号金额变动日志表,他的主键是由业务生成的无序不重复的 uuid 值,唯一键是账号 id+一个数据入库时间,业务使用这张表通过3个 SQL ,其中插入 SQL ,因为这个表上没有删除SQL ,所以在 Oracle 上数据基本上是顺序写入数据块的,而如果表结构不做调整,迁移到 OceanBase 后,因为主键写入的无序,可以认为主表数据从 顺序扫唯一索引再回表的视角看是离散地写入数据块的,这样会导致什么问题呢?我们来看第二个 SQL ,第二个 SQL 是一个查询 SQL ,他是走唯一索引先 access 数据的主键,然后回表,虽然扫唯一索引是顺序的,可因为主键的无序,回表查找数据的时候会发现回表的数据在主键上分布非常离散,这就导致在表数据量比较大时,这个 SQL 可能会产生大量的物理读。

我们将原来的表结构做一下调整,将写入值不连续的主键调整为唯一键,将写入相对连续的唯一键提升为主键,这样第二条 SQL 他的物理读将会大大降低,性能也会得到提升。同时这个业务其他的 SQL 也并不会因此而出现较大的性能下降。

这个 case 总结一下就是:索引组织表的主键值要尽量做到写入是顺序的,不连续可能会导致查询回表产生大量 io,同时在合并时的 io 开销也会变大。

九、性能问题排查方法论

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-11

性能问题的排查可以使用瓶颈确认法,先抓主要矛盾主要问题,如当我们定位到该性能问题是由网络瓶颈导致的,此时,我们可以一下网卡配置速率是不是达到上限了;如是磁盘写入先到瓶颈,我们可以一下集群是不是在做转储或者在做合并,从而影响到了线上。如是内存瓶颈,我们可以看一下租户分配的内存是否足够,转储相关参数配置是否适合。如是 CPU 瓶颈,单核高,可以看一下网卡软中断是否打散;多核高,我们则可以判断一下是容量问题、事务问题,还是 SQL 问题。

正如开篇我们所提到的,数据库调优是个很宏大的主题,蚂蚁数据库团队也是将调优的经验积累起来,形成了一个平台 OAS 。

OAS 是什么?

OAS 是定位为一款数据库自治产品,可以提供一站式的数据库高可用解决方案,为稳定性负责,兼顾运维效能,在蚂蚁集团内部,OAS 接管了所有生产数据库的稳定性问题。

OAS 的功能

OAS 拥有以下七个功能。

  1. 风险巡检:提供 全方位立体式的数据库风险揭示能力 , 与 Tars 能力互补
  2. 故障自愈:提供 故障的定位能力及自动恢复能力
  3. 风险自治:提供 告警的根因诊断及自动修复能力
  4. 容灾中控:提供数据库的容灾能力,包括容灾巡检、容灾变更、容灾保鲜等
  5. 应急平台:提供故障时的人肉快速恢复能力,包括快速识别/快速诊断/快速恢复
  6. 容量自治:基于算法的容量风险检测,及智能化的扩容。
  7. 混沌注入:提供全产品技术栈风险的混沌工程能力

十、SQL 优化方法论

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-1

性能问题,很多时候都是 SQL 问题。针对 SQL 问题,我们尝试总结了一个方法论。上图展现了 SQL 优化的工具、定位 SQL 问题的黄金指标、应急方式。

在蚂蚁内部,数据库团队对 SQL 的管理和优化都依赖于 Tars 平台。

Tars 是什么?

SQL 是应用和 DB 衔接的唯一桥梁,而 Tars 就是 OceanBase SQL 智能诊断优化产品。

Tars 有什么功能?

Tars 可以做三种事情,事前的防范&治理;事中的识别&自愈以及事后可以优化&学习。

  1. 事前防范&治理主要包括 SQL 自动 Review、SQL 质量洞察、慢 SQL 日常治理、以及SQL 画像建设等等。
  2. 事中识别&自愈主要包括 SQL 诊断识别、SQL 影响根因分析和SQL 自愈(执行计划修正、限流等等。
  3. 事后优化&学习是指 SQL 和 Schema 自动优化、知识库的案例归档、SQL 自愈以及优化模型的自动学。

以上就是在蚂蚁集团内部场景下,DBA 日常关于 OceanBase 性能调优的所有内容了,如有疑问欢迎随时和我们取得联系喔。

最后的最后,您有任何疑问都可以通过以下方式联系到我们~

联系我们

欢迎广大 OceanBase 爱好者、用户和客户随时与我们联系、反馈,方式如下:

社区版官网论坛

社区版项目网站提 Issue

以蚂蚁集团不同使用场景为例,分析如何调整和优化高性能 OceanBase-2

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论