天天看点

LSM 优化系列(二)-- dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction

文章目录

  • ​​背景描述​​
  • ​​dCompaction设计​​
  • ​​触发条件 VCT​​
  • ​​触发VT 合并的条件 VSMT​​
  • ​​测试数据​​

优化的重心集中在减少写放大上,同时将读性能维持在和rocksdb 原生读性能接近,优化思想是中国科学院的2位博士 提出的。

论文原地址:

​​dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction​​

背景描述

关于LSM的问题,这里不多介绍,有兴趣的同学可以看看之前 总结的相关优化论文的描述:

​1. PebblesDB Building Key-Value Stores using FLSM-Tree(Fragmented) SOSP‘17​​

​​2. X-Engine: An Optimized Storage Engine for

Large-scale E-commerce Transaction Processing SIGMOD’19​​

论文中 通过YSCB 构造的workload 来统计 三种类型的操作造成的IO:Compaction, Get, Put.

如下图:

LSM 优化系列(二)-- dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction

其中IO操作主要是由compaction 造成的,而读IO仅仅会由读的比例的增加而增加,且最大不会超过 总的IO的20%,也就是大部分IO操作都是由Compaction造成的。

再通过分析Compaction的实现 如下图:

LSM 优化系列(二)-- dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction

可以发现实际compaction过程中针对同一个key可能会写入多次,比如C2–>C3 compaction,会将选择的C3的文件经过合并再次写入到C3之中,这就是写放大的源头。

dCompaction设计

为了减少写放大,dCompaction核心设计了 virtual compaction 和 virtual SSTables,如下图:

LSM 优化系列(二)-- dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction

compaction过程中 内存里维护virtual sstables ,之间以树状结构来管理实际的real stabiles。virtual sstables 包含如下几种类型的元数据:

  • smallest key
  • largest key
  • file number
  • file size
  • Parent SStables

相比于实际的real sstables 多了一个parent SStables,用来管理实际的sst文件

dCompaction 实际的过程如下图

LSM 优化系列(二)-- dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction

原本的Compaction实现:

  1. T22@L2 + T32,T33@L3 --> T34,T35,T36@L3
  2. T34,T35,T36@L3 + T42,T43@L4 --> T44,T45,T46,T47,T48@L4

也就是T34,T35,T36中的key-value会被多读、多写一次

dCompaction实现:

  1. T22@L2 + T32,T33@L3 --> VT34,VT35,VT36@L3

    这一步仅仅将实际的sstable中的元数据读上来,在内存中构造 virtual table,合并real table的元数据,从而完成virtual compaction。不需要对T34,T35,T36中的数据多读写一次。

  2. VT34,VT35,VT36@L3 + VT42,VT43@L4 --> T44,T45,T46,T47,T48@L4

    这一步通过L3的virtual table + L4的virtual table 完成一次real compaction。

通过dCompaction,将实际T22@L2 + T32,T33@L3 + T22@L2 + T32,T33@L3 + T42,T43@L4 --> T44,T45,T46,T47,T48@L4

降低为T22@L2 + T32,T33@L3 + T42,T43@L4 --> T44,T45,T46,T47,T48@L4

所有的key-value仅仅只需要产生一次IO操作即可,能够有效得降低读写放大,提升写性能。

但是这个过程 对读性能有影响。dCompaction 下的读 和 原生rocksdb的读 流程对比如下图:

LSM 优化系列(二)-- dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction

实际的读在有virtual table的情况下会有如下几步:

  1. 读memtable
  2. 读block cache
  3. 读virtual table
  4. 确认key是在VT smallest – largest key之间
  5. 读Parent sstables
  6. 从实际的T 中读取key-value

相比于从实际的T中直接读取 多了两步。

触发条件 VCT

VCT定义了一个阈值用来控制当前compaction是virtual compaction还是real compaction,触发算法如下:

  1. compaction开始
  2. 选择需要被合并的 sst files
  3. sst files 计数
  4. Count = sst files 计数
  5. 如果 Count < VCT

    ​ 触发virtual compaction

    否则

    触发real compaction

如果VCT 被设置为0,那么默认就是real compaction;

随着VCT被设置的数值不断增加,virtual compaction会触发得越来越频繁,compaction产生的IO会降低,但是VCT 越大,并不代表系统性能越好。

  • 这其实也是变相的compaction delay,virtual compaction进行的越多,单次real compaction的量会越大,这一次的 real compaction会将系统的性能拖到低谷。
  • Virtual compaction越多,real ssttables 也会越多,这其实会增加读延时,从而降低读性能。

所以VCT的值需要做一个实际的测试来平衡real compaction 和 sst files 计数 compaction

触发VT 合并的条件 VSMT

这个阈值主要是用来控制一个virtual sstables 能够包含多少real sstables,如果读的过程中发现virtual sstables的real sstables 超过了这个阈值,就对当前virtual sstables进行合并。

这个参数主要是为了 降低 的读请求命中VT 的时 对读性能的影响。

LSM 优化系列(二)-- dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction

比如读请求命中 VT34,发现其中的real sstables 的个数超过VSMT,那么触发VT的合并。

将VT34 管理的三个real sstables T22,T32,T33都读到内存中,合并为T34,T35,T36。

同理 其他的VT35,VT36 也需要合并到T35,T36。这个过程其实是对IO带宽的一种浪费,但是VT merge 能够减少查找时的IO,提升读性能。

实际的合并算法:

  1. 如果 sstable.type == virtaul sstable

    ​ 2. 计算VT中有多少个real sstables

    ​ 3. Count = the number of real sstables

    ​ 4. 如果 Count >= VSMT

    合并virtual sstable 到real sstables

实际VSMT 也不能随意设置,否则同样会对性能有很大的影响。

如果VSMT设置的过小,VT merge会很频繁,将增加合并过程中的IO消耗(需要读到内存,合并 并写入)。为了降低一部分读延时,缺增加了dCompaction对读写放大的优化效果。

而如果VSMT设置的过大,VT 得不到合并,同样无法达到提升读性能的效果。

测试数据

硬件如下:

CPU: Intel Xeon E5645 (6core,2.4GHz, 12MB L3 cache)

DRAM:2GB

2 * 1TB SATA hdd( 平局寻道时间/旋转延时 : 8.5 ms/4.2 ms, 传输带宽:150M/s)

1 * 480GB SATA intel ssd (平均读/写延时:80 μs/85 μs, 平均读/写带宽:550/520 MB/s)

rocksdb 配置 都是默认的配置,dCompaction的VCT 是12, VSMT 是5。

使用YCSB 按照读写比,生成的workload。

和开头提到的 dCompaction的目标集中在减少写放大,保证读性能。

如下图为四种workload下的测试情况:

D1: (2.4×10^7, 1, 0, 256 B, 6 GB),

D2: (2.4×10^7, 0.8, 0.2, 256 B, 5 GB),

D3: (2.4×10^7, 0.2, 0.8, 256 B, 2 GB),

D4: (2.4×10^7, 0, 1, 256 B, 6 GB)

其中 D(O, W, R, V, S) 为数据集的描述,O表示操作次数,W 表示写占的比例,R 表示读占的比例,V 表示value siz,S 表示总的数据集大小。

LSM 优化系列(二)-- dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction