技术内幕|Hummock: 为流处理而生的云原生存储引擎重大优化

作者:刘玮 RisingWave Labs 内核开发工程师

1. 背景

在「Hummock :专为 RisingWave 流处理而设计的云原生存储引擎」一文中里我们已经介绍了 Hummock 的设计理念与基本架构,本文主要介绍 Hummock 近期几个版本的重大改进与优化。

2. Fast Compaction

在设计之初,Hummock 的数据文件格式参考了 RocksDB Sstable 的设计。之后为了提升查询性能,Hummock 引入了 Xor Filter 用于替换原有的 Bloom Filter (RocksDB 也引入了基于 Xor Filter 改造的 Ribbon Filter 算法)。但是 Xor Filter 在构建过程中会短暂使用大量的内存,为了减少内存的使用,Hummock 改造了数据存储格式,转而为每个 block 单元的数据构建 Filter 而不是构建全局的单一 Filter,从而降低了构建过程中的内存峰值,使得 RisingWave 可以运行在更加低配的环境中。

LSM Tree 相比 BTree 类的数据结构而言,通过顺序写入+后台整理的方式换来了更高的写入吞吐,然而也付出写放大的代价的,也就是说同一份数据可能会被反复整理(compact),更多细节参考此处。对于 L1 及更旧的数据而言,当数据库试图把上层的一个文件的数据挪到下层时,往往会和下层的多个文件产生重合,为此不得不把远多于一个文件引入同一个 compact 任务中,这正是写放大的主要来源之一。我们注意到,即便上层的文件和下层的多个文件产生了范围重叠,依然不意味着上层的每一个 block (通常在 4KB ~ 256KB 之间)都和下层的某个 block 产生了范围重叠,除非每次写入的数据都在同一个范围内严格的等概率分布。因此,如果我们的 compact 算法不是按照 key 为粒度来遍历数据,而是以 block 为粒度,那么对于那些没有和任务中其他文件的 block 产生重叠的 block,可以避免解压以及再次压缩的开销,直接将这部分数据复制到新的文件中。

传统的 compact 算法如下图所示:

而改进后的算法如下图所示:

通过对比可以看出,SST2 中的 block-1 和 block-3 如果和 SST1 中的数据没有重复的话,可以直接复制到输出文件中,避免额外的解析以及压缩开销

我们测试了多种不同的读写负载,该优化能够节约20%~50%的 compactor CPU 资源。对于那些写入数据较多、吞吐较大的场景,该优化能够显著降低 compact 操作带来的成本问题。目前该功能还在测试中,默认不开启。

3. IO Prefetch

由于 Hummock 的存储设计和 RocksDB 一样,是基于 Block 为粒度来组织数据。当上层应用查询数据时,会逐个读取 block ,如果 block 不在 cache 中,则触发一次 IO 操作读取 remote storage (如果是 AWS 环境部署,则后端为 S3 存储)。然而对 S3 有所了解的开发者都知道,S3 的随机读延迟极高,更适合用于大对象的顺序读取。因此,当用户执行 OLAP 类型的查询时(例如:select count(*) from mv; ),Hummock 需要逐一发送 IO 操作,极大地增加了查询耗时。还有一种类似的场景,对于已经导入的数据表,用户希望再次创建出另外的 Materialize View, 此时也需要遍历所有的历史数据,因此也会受制于上面所提到的读取方式。

因此,对于 RisingWave 中的 batch 查询,我们在底层的存储中,当发现 cache 中没有当前 block 时,会一次性读取当前范围内的多个 block。通过这样的方式我们能够尽可能最大限度地利用用满 S3 的带宽吞吐,同时由于 S3 按照 IO 个数收费,而流式接口只算做一次 IO,因此该优化也同时降低了 S3 的 IO 成本。通过一些简单的测试,该优化可以提升部分 OLAP 查询速度至多 8 倍。当然这只是极端情况下,还有很多复杂的 SQL 瓶颈在于计算操作,实际提升还取决于查询类型与业务场景。

4. 总结

除了查询性能以外,成本也是数据库所关注的重点。对于 AWS S3 这样的存储后端来说,除了存储数据按照大小每月固定收费以外,IO 操作按照次数收费。因此,除了优化性能以外,如何利用 S3 的高吞吐高延迟的特征,尽可能提高 S3 的使用效率来降低成本,也是我们优化存储系统的重要方向之一。接下来我们会根据查询计划的不同更加精确地选择 IO 策略来进一步提高处理速度,以及基于本地磁盘作为二级缓存来进一步提高命中率,减少对 S3 的访问频率。

5.关于 RisingWave

RisingWave 是一款分布式 SQL 流处理数据库,旨在帮助用户降低实时应用的的开发成本。作为专为云上分布式流处理而设计的系统,RisingWave 为用户提供了与 PostgreSQL 类似的使用体验,并且具备比 Flink 高出 10 倍的性能以及更低的成本。

🔧如果你还不知道如何上手 RisingWave,请体验中文入门教程:www.risingwavetutorial.com/

💻想要更深入地理解并使用 RisingWave,请阅读中文用户文档:zh-cn.risingwave.com/docs

相关推荐
Flying pigs~~1 天前
RAG智慧问答项目
数据库·人工智能·缓存·微调·知识库·rag
misL NITL1 天前
mysql之如何获知版本
数据库·mysql
许彰午1 天前
CacheSQL(二):主从复制——OpLog 环形缓冲区与故障自动恢复
java·数据库·缓存
2401_832365521 天前
JavaScript中rest参数(...args)取代arguments的优势
jvm·数据库·python
2301_779622411 天前
Go语言怎么用信号量控制并发_Go语言semaphore信号量教程【入门】
jvm·数据库·python
薪火铺子1 天前
微服务认证方案对比与选型
微服务·云原生·架构
2301_766283441 天前
c++如何将控制台输出保存到文件_cout重定向到txt【详解】
jvm·数据库·python
北极的冰箱1 天前
MySQL Ver 8.0.41 for macos14.7密码遗忘
数据库·mysql
冬奇Lab1 天前
一天一个开源项目(第89篇):Warp - AI 驱动的现代化 Rust 终端
人工智能·rust·开源
XDH_CS1 天前
MySQL 8.0 安装与 MySQL Workbench 使用全流程(超详细教程)
开发语言·数据库·mysql