title: dCompaction论文阅读
date: 2019-07-21 17:27:11
tags: 数据库
背景知识
Bloom Filter
定义
Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。Bloom Filter的这种高效是有一定代价的:在判断一个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(false positive)。因此,Bloom Filter不适合那些“零错误”的应用场合。而在能容忍低错误率的应用场合下,Bloom Filter通过极少的错误换取了存储空间的极大节省。
基本思想
它的原理是,当一个元素被加入集合时,通过K个Hash函数将这个元素映射成一个位阵列(Bit array)中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检索元素一定不在;如果都是1,则被检索元素很可能在。这就是布隆过滤器的基本思想。
LSM-tree Compaction过程
要注意的是:level0->level1的过程中,进行的是minor compaction,这个过程不会进行删除操作,而是直接把在mem中的immutable memtable直接传送到disk中。这是因为,这里只知道要删掉key记录,但是这个KV数据在哪里?需要进行复杂的查找,造成大量的I/O开销。
另外还有一点,lsm tree进行major compaction的过程中,对多个文件采用多路归并排序的方式,依次找出其中最小的Key记录,也就是对多个文件中的所有记录重新进行排序。之后采取一定的标准判断(对于某个key来说,如果在小于L层中存在这个Key,那么这个KV在major compaction过程中可以抛掉,这是因为越上层的key值是越新鲜的)这个Key是否还需要保存,如果判断没有保存价值,那么直接抛掉,如果觉得还需要继续保存,那么就将其写入(L+1)层中新生成的一个SSTable文件中。就这样对KV数据一一处理,形成了一系列新的L+1层数据文件,**之前的L层文件和L+1层参与compaction 的文件数据此时已经没有意义了,所以全部删除。**这样就完成了L层和L+1层文件记录的合并过程。
写放大问题
文中提到:
我们在RocksDB上进行实验,通过使用从具有256B值大小,随机密钥,Zipfian分布的YCSB生成的100%写入工作量来测量基于LSM树的KV存储的写入放大。 我们分别执行数据大小为4,6,8,10和12 GB的运行阶段。 从图a中我们可以看到,当输入数据大小为4 GB(压缩后实际为2.96 GB)时,实际磁盘写入I/ O为63.39 GB。 在这种情况下,写入放大率为15.85。 从图b中我们可以看到WAR增加到30.30,平均为19.86。 另外,随着数据大小的增加,写入放大变得更加严重。
而从下图中,我们可以看到(横轴坐标代表运行数据中Get数据的占比):
write-ahead log I/O的比例总是小于2%,并且get I/O的比例正在增加,但即使get比例增加到90%也不会超过20%。 Compaction I/O的比例始终大于80%。 因此,我们可以得出结论,严重的写入放大会大大消耗大部分磁盘I/O带宽,并且几乎不需要为前端应用程序请求提供服务(如前端应用程序需要调用get操作)。
名词解释
词语 | 含义 |
---|---|
M或AF | Amplification Factor,放大因子。AF(或M)= S i z e ( C i + 1 ) S i z e ( C i ) \frac{Size(C_i+1)}{Size(C_i)} Size(Ci)Size(Ci+1)。 |
WAR | Write Amplification Ratio,写放大率,即 真 实 写 入 磁 盘 的 数 值 用 户 写 入 的 数 值 \frac{真实写入磁盘的数值}{用户写入的数值} 用户写入的数值真实写入磁盘的数值(the proportion between actual write amount to the disk and the amount of data written by users)。 |
Log I/Os | the write-ahead log I/Os for ensuring the reliability of KV items,即写WAL时的I/O消耗。 |
Get I/Os | issued to get the specific KV items from disk-resident SSTables. |
Compaction I/Os | include reading KV items from disk-resident SSTables and writing KV items that were sorted and merged to SSTables. |
VCT | (写过程)Virtual Compaction Threshold,在进行real compaction触发之前,能够进行virtual compaction的real SSTable的数量的阈值(大于这个值,触发real compaction否则进行virtual compaction)。 |
VSMT | (读过程)Virtual SSTable Merge Threshold,表示虚拟SSTable派生的真实SSTable的数量。 |
研究动机
研究动机如上图,得出的结论是:
结论
在没有KV对在compaction发生后被删除的前提下:
(1) T 34 , T 35 , T 36 T_{34},T_{35},T_{36} T34,T35,T36中的KV对可以在 T 22 , T 32 , T 33 T_{22},T_{32},T_{33} T22,T32,T33中找到,同理, T 45 , T 46 , T 47 , T 48 T_{45},T_{46},T_{47},T_{48} T45,T46,T47,T48中的KV对可以在 T 34 , T 34 , T 36 , T 42 , T 43 T_{34},T_{34},T_{36},T_{42},T_{43} T34,T34,T36,T42,T43中找到。
(2)这个过程中存在着重复的写和读,以 T 22 , T 32 , T 33 T_{22},T_{32},T_{33} T22,T32,T33为例,其中的KV对至少被读取和写入两次。
有一个点要注意:
为什么 W ( T 34 + T 35 + T 36 ) = R ( T 22 + T 32 + T 33 ) W(T_{34}+T_{35}+T_{36})=R(T_{22}+T_{32}+T_{33}) W(T34+T35+T36)=R(T22+T32+T33)?
这主要是因为在前面
no KV items are deleted
的假设,再看到后面介绍到的W和R分别代表着:
名称 | 含义 |
---|---|
W | compaction发生过程中writeI/O的总大小 |
R | compaction发生过程中readI/O的总大小 |
也就是说,上面两个等式实际上说的就是compaction的过程,这个过程在compaction之前把数据read进入mem,在compaction之后又把产生的结果压缩回disk,如果no KV items are deleted,那么读出和写入的便消耗相同的I/O,这一点实际上就不言而喻了。
Design of Compaction
主要思想
Real Compaction
名词 | 含义 |
---|---|
real compaction | 如Figure 3(a)所示,我们它为real compaciton,即所选择的SSTable合并为新的并且无重叠的SSTable。 |
real SSTable | 如下图,我们定义由real compaction生成的SSTable为real SSTable。 |
Metadata | 对每一个real SSTable,都有一个对应的SSTable metadata,用来存储在这个SSTable中最大key,最小key,file number和file size,即下面(a)图所示。 |
metadata generation | metadata的生成阶段称为metadata generation |
因此,real compaction可以分为两个阶段,分别为data generation(数据生成阶段)和meta generation。 大多数I / O开销是由data generation引起的,而metadata generation则具有较少的I / O开销。
Virtual Compaction
在Virtual Compaction的过程中,没有进行data generation的过程,只进行metadata generation,因此,Virtual Compaction与Real Compaction相比,节省了Compaction可能消耗的I/O。
从上图中可以看出,
(1)在virtual compaction之后形成的virtual SSTable中,Meatadata除了保存Smallest Key,Largest Key,File Number和File size之外,还需要保存ParentSSTables。
(2)ParentSSTables存储的是Real SSTable,即形成了Virtual SSTable和Real SSTable的对应关系。
dCompaction的基本思想
通过Virtual Compaction将 T 22 , T 32 和 T 33 T_{22},T_{32}和T_{33} T22,T32和T33转换为 V T 34 , V T 35 和 V T 36 VT_{34},VT_{35}和VT_{36} VT34,VT35和VT36,并且仅在 V T 34 , V T 35 和 V T 36 VT_{34},VT_{35}和VT_{36} VT34,VT35和VT36记录metadata,所以就可以避免因real compaction而导致的compaction I/O消耗。在之后的real compaction中,将 T 42 , T 43 T_{42},T_{43} T42,T43与 V T 34 , V T 35 和 V T 36 VT_{34},VT_{35}和VT_{36} VT34,VT35和VT36的parentSSTable即 T 22 , T 32 和 T 33 T_{22},T_{32}和T_{33} T22,T32和T33合并,得到 T 44 , T 45 , T 46 , T 47 和 T 48 T_{44},T_{45},T_{46},T_{47}和T_{48} T44,T45,T46,T47和T48。
优点:
(1)与传统的compaction 策略相比, T 22 , T 32 和 T 33 T_{22},T_{32}和T_{33} T22,T32和T33在dCompaction中只读写一次,因此可以减少重复的I/O开销,写放大也会被极大降低。
(2)通过计算,当AF=10时, C 2 − > C 4 C_{2}->C_{4} C2−>C4这个过程省下的带宽为8.3%。
缺点:
虽然virtual compaction对写性能有很大的提升,但在读性能方面的影响更大,下面将讨论virtual compaction对读性能的影响。
读过程
real SSTable中的读操作
virtual SSTable中的读操作
与在real SSTable中的读操作相同,在Virtual SSTable中进行读操作:
首先,同样需要判断要查找的kv对的key值是否在该SSTable的key值范围内(介于smallest key和largest key之间)。假设在这个virtual SSTable中,那么就进行下一步。
然后就与real SSTable中操作不同了,读取parentSSTables,并依次在parentSSTables中搜索kv对(依次体现在图中)。
结论
通过对virtual SSTable的读取过程的分析,我们可以观察到,在许多real SSTable中搜索目标KV对时,读取的路径长度变大了,因此virtual SSTable中涉及到的real SSTable的数量是非常重要的。 换句话说,更频繁的virtual compaction意味着更高的写入性能但更低的读取性能。 相反,更频繁的real compaction意味着更低的写入性能,但更高的读取性能。 总之,触发real compaction或virtual compaction的条件对于写入和读取性能至关重要。
VCT和VSMT
VCT和VSMT对应了写和读过程中的两个阈值:
VCT 触发条件
Virtual Compaction Threshold,在进行real compaction触发之前,能够进行virtual compaction的real SSTable的数量的阈值(大于这个值,触发real compaction否则进行virtual compaction)。当大于这个阈值时,就发生real compaction。首先,我们计算real SSTable的数量,然后将其与VCT进行比较,以确定virtual compaction或real compaction(比如VCT为5,如果real SSTables的数量为6,那么就进行real compaction)。
如何设置VCT的值
(1)如果VCT的值设置的比较大,将会延长随后的real compaction的时间(因为总量上涨了),这将会导致写入吞吐量激增。因此就需要考虑:compaction过程中的总数据量以及随后发生real compaction时需要消耗的时间。
(2)如上文中所说的,如果增大VCT,那么就会导致virtual SSTables含有更多的real SSTables,增加了read latency。因此,从读取性能的角度来看,VCT应该限制在一定范围内。
总结
通过后面的实验,考虑write amplification,real compaction time和read performance在内的多种因素。认为VCT应设置在8-16之间。
VSMT的触发条件
Virtual SSTable Merge Threshold,表示虚拟SSTable派生的真实SSTable的数量。在读取过程中,如果读取操作读取的是virtual SSTable并且其real SSTable的数量大于VSMT,则我们触发虚拟SSTable merge(不是compaction,因为不是在lsm多层结构下的)。
以上图为例,表示了VSMT触发后,进行merge的过程:
不仅仅是 V T 34 VT_{34} VT34将被转化为real SSTable,与之相邻的virtual SSTable也将被转化。
这是因为在进行merge的过程中,生成了 T 34 , T 35 , T 36 T_{34},T_{35},T_{36} T34,T35,T36,所以与 V T 34 VT_{34} VT34相邻的 V T 35 , V T 36 VT_{35},VT_{36} VT35,VT36会被merge进入 T 35 , T 36 T_{35},T_{36} T35,T36中( T 32 , T 33 T_{32},T_{33} T32,T33中有一部分在merge中进入了 T 35 , T 36 T_{35},T_{36} T35,T36,而 V T 35 , V T 36 VT_{35},VT_{36} VT35,VT36代表的也是 T 32 , T 33 T_{32},T_{33} T32,T33,不需要重复两者,这样只会消耗更多的带宽,所以过程中相邻的Virtual SSTable也会被转化)。
影响
VSMT过大:对read性能的改善不明显。
VSMT过小:对经常性地进行merge,增加了消耗,降低了dCompaction本应该发挥的积极影响。
后续实验测的,3-6是一个合适的范围。