OBKV性能优化70%~220%,事务处理更高效

2024年 6月 4日 71.9k 0

1. OBKV 是什么?

OBKV是OceanBase的多模KV产品,主要用于提供低成本的大规模结构化/半结构化数据存储,以及简单操作接口下的极致访问性能。

在实现上,OBKV Bypass了SQL层,直接基于OceanBase的分布式存储,在其上构建各种多模KV形态,比如OBKV现在支持了兼容HBase接口的OBKV-HBase,兼容Redis协议的OBKV-Redis,以及直接基于表格接口的OBKV-Table等多种多模产品形态。在分布式存储和多模形态之间,OBKV有一层称为TableAPI的框架层,向模型层提供封装的存储/事务调用能力。架构如下图:

OBKV性能优化70%~220%,事务处理更高效-1

2. 基础性能优化介绍

在v4.2.3(本特性也会Patch到v4.3.3),相较于之前的版本,v4.2.3~v4.3.3的OBKV单行读写性能提升约70%,批量读写性能提升80-220%。下面介绍v4.2.3 OBKV性能优化的原理,主要包含两大优化点:

  • 多行Batch操作的性能优化。
  • 单行操作的性能优化。

2.1. Batch性能优化

OBKV提供了Batch接口,用户可以通过调用Batch接口,将多个单操作聚合为一个批量消息,提交给服务端。Batch能提升性能意味着减少了消息请求响应的数量,所以在网络IO量不变的情况下可以处理更多的消息。在OBKV中,单操作/单分区的Batch会保证事务语义,单分区的Batch中所有的操作会作为一个事务来提交,也减少了事务的开销。

但为什么说OBKV已有的Batch能力并没能完全发挥OceanBase内核的优势呢?主要原因有两点:

  • OBKV的Batch是按照分区粒度组织,分区数量会对Batch性能产生较大的影响。
  • OceanBase底层内核支持了Batch语义,OBKV没有把Batch语义下压给存储,有一定的性能损失。

因此,本次优化针对性地支持LS粒度的Batch,并将Batch语义下压给存储,提升性能。

2.1.1. 支持LS粒度的Batch

OBKV v4.2.3之前的版本,Batch是分区粒度的,当分区数比较多的时候,一个Batch的操作比较有限,不能很好的发挥Batch的优势。OceanBase 4.0版本之后,底层分布式存储引擎引入了LS(Log Stream)的概念,LS是分区的逻辑容器,一般情况下,LS可以看成是节点级别的概念,一个LS内的事务的性能和单机事务的性能是一样的。在OBKV v4.2.3,引入了更匹配LS概念的消息格式,可以按照LS来组织Batch,也就是可以按照节点维度来做Batch,客户端以及服务端消息交互,以及服务端事务的开销,都有了大幅度降低。

新的消息格式,也做了一些消息请求瘦身的优化,比如:

  • Batch消息中引入列名字典:之前Batch的消息格式,是单操作消息的集合,而每个单操作消息中都单独带了列名信息,有较大冗余。之所以考虑引入字典,是因为存在每个单操作消息需要访问的列名不同的场景(比如表结构中,列数比较多,但是每次插入操作,只有部分列有值)。引入字典后,各个单操作消息中需要访问的列的信息,只用持有列名字典的引用即可。
  • 对元数据做了瘦身:列的元数据用于和服务端交互列的类型,是否为空等信息,之前的消息格式采用定长的元数据结构,在新的消息格式中,元数据结构中的内容做了精简的同时,也引入了变长的元数据格式,大幅度降低了消息包中元数据的开销。

2.1.2. Batch语义下压给存储

OceanBase存储内核,很早之前支持了Multi Get的能力,在v4.2.3支持了Multi Set的能力。为了简化描述,把存储的Multi Get/Set概念,按照TableAPI的Batch Get/Set概念来统一介绍。

接下来以Batch Get为例,分别解释在存储内外做Batch的区别:假设数据在存储中逻辑组织成一颗树,在存储外做Batch Get,每个Get都是一次对存储的调用,每次调用都会从存储树的根节点开始检索数据。在存储内做Batch Get,先对这一批单操作请求的主键做排序,只调用存储一次接口,在迭代一次存储树的过程中按序检索多条记录。也即Batch语义直接下压给存储,减少存储接口调用次数,减少了存储树重复迭代的次数。

OBKV在v4.2.3中,适配了存储的批量能力,一个Batch请求(如果是同一种操作),会在TableAPI层转换为存储的一次批量调用,进一步提升Batch的性能。

2.2. 单操作的性能优化

OBKV的单操作性能,是基于OceanBase底层分布式存储的性能,能够优化的空间有限。OBKV v4.2.3引入了组提交的思路,对不同客户端的单操作请求,在数据库服务端做聚合,基于服务端优化后的Batch能力,降低事务以及存储的调用开销。通过组提交的方式,在请求密集型的场景,请求RT不明显增加的情况下,单操作性能提升70%。

本次组提交作为OBKV的一个实验性功能,需要通过配置项控制,默认关闭:

打开:AlTER SYSTEM SET enable_kv_group_commit=true

组提交在使用上,和客户端Batch有一些不同:

  1. 首先,客户端Batch是请求级别,通过用户显式调用Batch接口,聚合一个客户端的多个请求。组提交在服务端做批量,自动聚合多个客户端的同一类型操作,比较适合单个客户端压力不是太大,但是客户端比较多,整体压力较大的场景。
  2. 其次,组提交的聚合是自适应的,业务不需要设置Batch Size。当压力较小的时候,组提交会退化为单操作。当压力比较大的时候,组提交会基于请求队列的积压情况,系统平均RT等因素,自动选择聚合的粒度以及提交的时机。基于自适应组提交,系统的平均RT也不会有明显的变化。
  3. 最后,组提交对业务的环境,编码要求更小,可以直接通过配置项来开启或者关闭组提交,也能获得一个相对不错的服务端批量性能。但是服务端为了把多个单操作模拟成Batch,做了很多适配,比如聚集消息,把结果集拆分为单操作的响应包等,也会有一定的性能损耗,Batch在一些简单场景,可以获得更极致的性能。

综上,组提交和客户端Batch,都是基于批量的思路优化OBKV的基础性能,提供类似自动档和手动档的方式,给业务纷繁的场景以不同的选择。

相关文章

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

发布评论