Less is More: De-amplifying I/Os for Key-value Stores with a Log-assisted LSM-tree
近年来,基于Log-Structured Merge Tree (LSMtree)的键值存储(key-value store)在数据中心系统中得到了广泛的应用,如LevelDB、RocksDB等。尽管针对高速写处理进行了优化,但严重的I/O放大仍然是阻碍它们达到最大性能潜力的关键约束。不幸的是,这个问题深深植根于lsm树结构的基本设计中。少量频繁更新的键值项可能会迅速污染整个树结构,导致结构的重复更改,并迅速放大树中各个级别的磁盘IOs数量。在本文中,我们提出了一种新的方案,称为Log-assisted LSM-tree (L2SM),从根本上解决了长期存在的I/O放大问题。L2SM采用小容量、多层次的日志结构,将对树形结构产生破坏作用的键值项进行选择隔离,高效积累和吸收重复更新的键值项,并在早期删除过时和删除的键值项。我们基于LevelDB创建了L2SM结构的原型。我们对YCSB基准测试的评估显示,磁盘IOs数量减少了40.2%,吞吐量增加了67.4%,平均延迟减少了40.1%,结果很有希望。
一. 研究问题
lsm -树结构作为一种基础设计,其正确的功能依赖于KV项目按键的严格排序。由于严重的I/O放大问题,这一过程是非常低效的,这是由几个内在的结构问题造成的。
1. First, the data storage unit (SSTable) is much larger than the data operation unit (KV).
2. Second, the locality information is lost and ignored in the data placement.
3. Third, due to the tree-like structure, changes in the top-level are eventually rolled down to the bottom, level by level
随着KV数据存储规模的扩大,随着树结构的广泛和深入,这些问题将变得更加突出。一个巨大的挑战是如何保留基于lsm树的结构的优点,但避免其负面影响?
二,研究方法
我们的目标是保留基本lsm树结构带来的所有优点,但消除有害的I/O放大效应。我们的主要思想是最大限度地保持LSM-tree的稳定性。
本质上,前面提到的所有问题的根源都是对树结构频繁的、破坏性的更改,这迫使所涉及的sstable被反复重组。通过移除、隔离和延迟这些变化,我们可以将它们对当前状态的影响降到最低,使树结构稳定下来,从一开始就消除了I/O放大的根本原因。
实现过程:首先,它作为一个缓冲区,用于隔离接收频繁更新的KV项目。将热kv从lsm树中分离出来,防止树结构被重复污染。其次,识别并移出“稀疏”的sstable,这些sstable与低层的许多sstable重叠,并使它们有机会被压缩到日志中。此外,废弃和删除的kv会在早期删除,而不会下滚到更低的级别,这避免了不必要的I/ o,释放了占用的磁盘空间。第三,日志还会延迟对lsm树的修改,这就为影响多个结构的修改(例如重叠的更新、删除)提供了一个机会,可以将这些修改合并到更少的操作中。
图2显示了每一层所涉及的磁盘IOs数量。我们可以看到,在每个级别上,磁盘IO量随着请求的到达而增加,这与预期一致。L0的磁盘IOs数量的增长速度几乎与传入的请求相同。这是因为缓冲在内存中的KV项直接作为sstable刷写到L0中,并且L0中不同sstable的KV项没有排序。因此,L0几乎没有维护开销。然而,随着层次的加深,磁盘IO量的增长率也会增加。换句话说,级别越低,涉及的IOs磁盘越多,而且速度越来越快。
因此,它受到放大效应的影响更为严重。在测试结束时,L3的维护I/O开销是传入请求量的5倍。这个例子生动地展示了不同级别的I/O放大。
L2SM DESIGN
本文提出了一种高效的解决方案,称为日志辅助的lsm树(Log-assisted LSM-tree, L2SM),从根本上解决I/O放大的关键挑战。在本节中,我们将首先概述所提出的体系结构,然后介绍每个组件的设计细节。
L2SM在内存和磁盘存储中维护KV数据。(1)内存结构:与经典的LSM-tree类似,L2SM保留了LSM-tree的两个内存结构,MemTable和ImmuTable,作为一个暂存缓冲区,将小的、随机的KV条目组织成大的、顺序的I/ o。(2)磁盘结构:与经典的LSM-tree不同,磁盘上的数据存储分为LSM-tree和SST-Log两部分。
L2SM结构中的数据流如下。(1)传入的KV项首先被打包到MemTable中,然后转换为不可变的。接下来,Minor Compaction (MC)进程将不可变对象合并到L0中,作为一个持久的SSTable。(2)当任意级别的sstable的数量超过大小限制时,我们监控并识别可能影响树结构的sstable,例如那些具有稀疏键或热键范围的sstable。伪压缩(Pseudo Compaction, PC)进程将选定的sstable移动到同一级别的SST-Log中,该日志由日志元数据管理器管理。请注意,PC不会招致任何物理I/O,而只是更新元数据结构。(3)如果SST-Log级别的大小超过限制聚合合并(Aggregated Compaction, AC)进程从日志中选择和删除受害sstable,并与树的下层重叠的sstable进行合并。因此,在L2SM中,一个KV项首先从树移动到日志,然后向后和垂直向下移动到树,以此类推。此过程重复执行,日志逐级从树中过滤破坏性更新。
1)Hotness and Density
为了减少对lsm -树结构的干扰,我们需要识别出更新频繁的sstable和稀疏的sstable,并将它们隔离在SST-Log部分,以稳定lsm -树结构。
我们用热度和密度两个指标来定量地测量SSTable的性质。热度度量SSTable中KV项的更新频率。密度衡量SSTable覆盖范围和影响范围的大小。
前者描述时间属性(频率),后者描述空间属性(宽度)。
L2SM维护热度检测位图(HotMap)来定量测量SSTable的热度。HotMap是一个全局的内存数据结构,由多层bloom过滤器组成
2) Density of SSTables
密度是影响树结构的另一个重要因素。密集SSTable是指大量KV项集中在一个小范围内,可能与下层较少的SSTable发生重叠,在合并排序过程中,参与合并排序的SSTable数量较少。因此,最好将稀疏的sstable隔离在日志中,而将稠密的sstable留在LSM-tree中。
3)Aggregated Compaction
聚合合并(AC)负责回收日志空间。它试图在日志中保留对结构影响最大的sstable,并将冷的和稠密的sstable返回到树的较低层次。当AC发生时,我们需要特别考虑以下问题。
Maintaining the query correctness 一个键在日志中可能有多个版本的值数据。在合并到较低的级别之前,最好将这些多个版本累积并合并为一个。
Considering both density and hotness AC需要同时考虑SSTable的温度和密度来决定是否继续将其保存在日志中。非常稀疏或非常热的SSTable应该继续保留在日志中。在选择sstable进行迁移时,我们需要有一个平衡的方法来综合两者的考虑。
Controlling the involved I/Os. 当将一个SSTable从日志归并到树中时,底层树中的多个SSTable可能会涉及到(由于生成结构)
结论
本文提出了一种新的基于lsm树的I/O放大结构L2SM,用于解决I/O放大问题。L2SM通过引入一个特殊的SST-Log结构来从LSMtree中隔离热和稀疏sstable,一个伪合并和一个聚合合并过程来吸收日志中的高成本更新来实现其设计目标。我们已经基于LevelDB构建了一个原型。实验结果表明,L2SM可以取得显著的性能提升。