西北工业大学亚军战队,数据库性能优化实操分享!

2024年 5月 7日 45.4k 0

上期分享👉《 2022 OceanBase数据库大赛决赛经历分享 》

本期邀请来自西北工业大学的亚军团队 426白给突击队 的队长王炳杰,为大家分享决赛性能优化实操,欢迎分享给感兴趣的朋友,共同学习成长。

本文更多是思路的分享,并不关注实现细节。初赛在满分后一周左右我写了篇总结,把大部分赛题的思路大致记录了一下;决赛在这篇博客中主要按时间顺序来梳理优化的过程,字少图多。

关于初赛

仓库:luooofan/miniob-2022

总结:Summary · Issue #25 · luooofan/miniob-2022

西北工业大学亚军战队,数据库性能优化实操分享!-1

01. 决赛题目分析

👉 训练营链接

西北工业大学亚军战队,数据库性能优化实操分享!-2

02. 优化思路

以下主要按照时间顺序来梳理我们的优化思路。

针对 Demo 的优化

OceanBase 一开始给了一个单线程的旁路导入 Demo

其流程如下图所示:

西北工业大学亚军战队,数据库性能优化实操分享!-3

整体可划分为前后两部分

  • 前半部分数据预处理

   输入是 csv 文件,输出是有序的数据文件;首先读数据到内存中,然后经过 CSVParser 组件解析出一行一行的数据(ObNewRow),再经过 RowCaster 组件把 ObNewRow 转换为 ObLoadDatumRow(这种数据结构可以直接走写宏块的流程),之后交给外部排序组件,这里使用归并排序

  • 后半部分写宏块生成 SSTable

   输入是有序的数据文件,输出是 SSTable;数据有序化后即可按序交给 SSTableWriter 组件来写宏块进而生成 SSTable。

针对这个 Demo,我们做了两步优化:

  • 把数据预处理部分多线程并行化:直接对 csv 文件分块,每个线程处理一个块的数据,加速 22min+;
  • 调大 fragment size 参数(归并排序每次要落盘一个有序的 fragment):增加了归并路数,减少了归并次数,加速 9min+。

这两个优化做完之后,开始思考以下几个问题:

西北工业大学亚军战队,数据库性能优化实操分享!-4

调整整体架构

基于上述几个问题我们调整了 Demo 的整体架构。

西北工业大学亚军战队,数据库性能优化实操分享!-5

调整后使用了桶排序,整个流程分四部分:

1. Do Sample

主线程对csv数据文件随机采样,从而确定各个桶的范围,比如第一个桶负责0-99,第二个桶负责100-199,以此类推。

2. Data Preprocess

通过单生产者多消费者模型完成数据分桶的任务,生产者不断地读数据到内存中,每个消费者取出 buffer,仍然是通过 parser 和 caster 生成 datum row 后,交给 bucket writer 处理,bucket writer 根据行主键二分查找到对应的桶,在序列化后异步写落盘。

3. Sort & Write MacroBlocks

等全部线程完成第二阶段后,在第三阶段通过多线程来完成桶内数据的排序以及写宏块的任务。每个线程负责连续的几个桶,比如负责0到9号这十个桶的数据,每次读取一个桶内的所有数据行到内存,解序列化后存储在 memory store 中,排序后交给 macro block writer 来写宏块,接着处理下一个桶,直到把该线程负责的所有桶都处理完。

4. Create SSTable

等全部线程完成第三阶段后,主线程生成 sstable,完成导入。

这样调整后解决了前面提出的四个问题,加速 10min+。然后来分析一下调整后的性能:

西北工业大学亚军战队,数据库性能优化实操分享!-6

有几点要说明:

在第一第二阶段,io_submit 和 io_destroy 属于意料之外的时间引入,分析后发现我们的异步写其实很弱很弱,其原因应该是系统参数限制,👉 让 io_submit 阻塞的另一种方法 - 知乎。其中 io_destory 的时间可以通过新起一个线程来避免,加速 23s。

第一第二阶段的 CPU 和 IO 利用率都不高,是因为存在互相等待的情况,也就是并没有同时的充分地利用两种资源,这里有很大的优化空间。

第三第四阶段明显 CPU 是瓶颈,之后逮着火焰图优化就行。

优化性能瓶颈

到此时已经调整好了我们的整体架构,之后就是针对资源瓶颈进行优化了。

IO 瓶颈

首先想到了可以做压缩,用 CPU 来换 IO;具体实现上,在序列化之后做压缩,解序列化之前做解压缩,调优后使用了 lz4 算法;做完后加速 7min+,这部分的 CPU 利用率涨到了很高。

西北工业大学亚军战队,数据库性能优化实操分享!-7

后续在针对 CPU 优化了很多后,更换了一个具有更高压缩率的算法 zstd138,加速 8s。

CPU 瓶颈

1. 火焰图

西北工业大学亚军战队,数据库性能优化实操分享!-8

2. 内存 Sort:使用主键索引

西北工业大学亚军战队,数据库性能优化实操分享!-9

如图,原程序中对 memory store 的内存排序要使其完全有序化,有大量的内存操作,在火焰图上可以看到很宽一块儿,那我们可以提取主键列+索引列进行排序,通过有序索引来从 MemoryStore 中取得对应的行,加速 92s。

3. SIMD 优化

西北工业大学亚军战队,数据库性能优化实操分享!-10

如图,使用 SIMD 可以做到单指令同时比较 16 Byte,从而快速确定分隔符的位置,进而通过列数来分行。

PS:为了方便,图中只画了对 8 Byte 同时比较

该优化完成后,在日志中 Parse 的时间统计加快了 44s,但是根据提交分数计算只快了 32s。我们一开始怀疑是评测机器的原因,还特意请来哥帮忙看了看评测日志,但是结果和本地是一致的。

然后我们在分析资源利用情况后发现,在第二阶段执行过程中会有 CPU 轮番摸鱼,也就是说做了这个优化后 CPU 不再是这部分的瓶颈了,瓶颈又变成了 IO。由于资源瓶颈的变化导致了总体性能提升并没有 Parse 组件的提升大。

其他针对 CPU 的一些小优化:组件输入输出批量化、绑核、循环展开、分支预测等

无用优化:SOA(优化前没有好好分析导致白白浪费了时间)

IO 瓶颈

前面做完 SIMD 优化之后,瓶颈再次来到了 IO。

1. BinaryRow

从 csv 文件中解析出来的 ObNewRow 还是要先转换为 DatumRow 之后再序列化落盘,这里其实没必要转换为 DatumRow,可以设计自己的数据结构,很多队伍也都做了这个优化,只不过叫法不一样

西北工业大学亚军战队,数据库性能优化实操分享!-11

我们设计的 BinaryRow,其连续的存储每一个cell,并且只存储必要信息,同时舍弃了部分可以从表 schema 中获取到的结构信息,既减少了IO开销,又减少了大量内存操作,还节余出了部分内存空间,加速 73s。

2. 利用内存:留存部分 buckets

把一部分桶的数据直接留在内存中:

  • 减少写读磁盘的数据量
  • 减少这部分数据 [de]serialize、[de]compress 的开销
  • 加速 17s

3. 利用内存:留存更多 buckets

对留在内存中的数据做压缩:

  • 进一步减少写读磁盘数据量
  • 对于之前留存的 buckets 增加了 [de]serialize、[de]compress 的开销

PS1:这里其实有个小 trick 是在前半部分数据预处理的时候统计出 binary row 的 data 部分最大需要多少字节,到后半部分分配的时候就可以省很多内存空间;

PS2:这个算是决赛最后一天做的一个重要优化,当时有点子着急,本来应该给这部分单独设置一个压缩算法变量然后调优的,结果没设,所以其实是直接调整了整体的压缩算法,从 zstd138 改回了 lz4,相当于把前面改用压缩算法带来的提升给撤销了,受限于此,也导致没调到这个优化最优的效果。

总的来说还是带来了 21s 的提升。

03. 总结

决赛优化

西北工业大学亚军战队,数据库性能优化实操分享!-12

1. 首先使用桶排序替代归并排序:消去归并操作;

2. 然后在数据预处理部分,使用生产者消费者模型:利用了 CPU 资源,还优化了顺序读的时间;

3. 在消费者这里:使用 SIMD 做解析、引入 BinaryRow,减少了 CPU 的耗用;

4. 压缩、桶数据留内存、以及 BinaryRow 的设计,都减少了写读磁盘的数据量;

5. 在 bucket writer 这里使用了 LinuxAIO 异步写;

6. 第三部分做了多线程并行化,充分利用 CPU 资源;

7. 这里也通过引入 BinaryRow 减少了解序列化的开销,Sort 使用索引排序,MacroBlockWriter 循环展开分支预测等优化减少了 CPU 的耗用。

不足之处

优化上没做的主要是:

1. 列值编码

2. SSTableWriter

经验

1. 要做好代码 review、做好文档和记录;

2. 一定要对每次执行的结果备份!方便结果分析以及做 PPT。

王炳杰同学的分享到这里就结束了,关于参赛体验,如果大家有什么想交流的,欢迎评论区留言探讨~

相关文章

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

发布评论