如何基于磁盘 KV 实现 Bitmap

本文探讨了在基于磁盘KV存储如RocksDB中实现Bitmap时如何减少读写放大问题。作者分析了硬件层面和软件层面的读写放大原因,包括SSD的Read-Modify-Write机制和LSM-Tree的数据组织方式。Kvrocks通过将Bitmap拆分成多个小KV来优化写入,避免一次性读写大量数据,从而控制读写放大。在实现上,通过计算offset确定Bitmap的存储位置,并仅在写入时才将对应的KV写入磁盘。这种方式与Linux内存管理策略类似,有效地适应了Bitmap的稀疏写入需求。
摘要由CSDN通过智能技术生成

大部分开发对 Bitmap 应该都不陌生,除了作为 Bloom Filter 实现的存储之外,许多数据库也有提供 Bitmap 类型的索引。对于内存型的存储来说,Bitmap 只是一个特殊类型(bit)的稀疏数组,操作内存不会带来读写放大问题(指的是物理读写的数据量远大于逻辑的数据量), Redis 就是在字符串类型上支持 bit 的相关操作,而对于 Kvrocks 这种基于磁盘 KV 实现的存储则会是比较大挑战,本篇文章主要讨论的其实是「基于磁盘 KV 实现 Bitmap 要如何减少磁盘读写放大

为什么会产生读写放大

读写放大的主要是来源于两方面:

  • 硬件层面的最小读写单元

  • 软件层面存储组织方式

硬件层面一般是由于最小读写单元带来的读写放大,以 SSD 为例,读写的最小单位是页(一般是 4KiB/8KiB/16KiB)。即使应用层只写入一个字节,在磁盘上实际会写入一个页,这也就是我们所说的写放大,反之读也是一样。另外,SSD 修改数据不是在页内位置原地修改而是 Read-Modify-Write 的方式,修改时需要将原来的数据读出来,修改之后再写到新页,老的磁盘页由 GC 进行回收。所以,即使对同一页的一小块数据反复修改也会由于硬件本身机制而造成写放大。类似于如下:

由此可见,大量随机小 io 读写对于 SSD 磁盘来说是很不友好的,除了在性能方面有比较大的影响之外,频繁擦写也会严重导致 SSD 的寿命(随机读写对 HDD 同样不友好,需要不断寻道和寻址)。LSM-Tree 就是通过将随机写入变成顺序批量写入来缓解这类问题。

软件层面的读写放大主要来自于数据组织方式,不同的存储组织方式所带来的读写放大程度也会有很大的差异。这里以 RocksDB 为例,RocksDB 是 Facebook 基于 Google LevelDB 之上实现了多线程,Backup 以及 Compaction 等诸多很实用的功能。RocksDB 的数据组织方式是 LSM-Tree,在解决磁盘写入方法问题,本身的数据存储也带来了一些空间放大问题。下面可以简单看一下 LSM-Tree 是如何组织数据:

LSM-Tree 每次写入都会产生一条记录,比如上图 x 先后写了 4 次,分别是 0,1,2,3。如果单看 x 这个变量,这里相当于有 4 倍的空间放大,这些重复的记录会在 compaction 的时候进行回收。同样,删除也是通过插入一条 value 为空的记录来实现

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值