LSM-based Storage Techniques: A Survey

回顾了LSM-tree的历史,以及leveling和tiering两种合并方式,接着介绍布隆过滤器和分区(对于tiering还有两种分区方案)这两个普遍的优化,简要带过并发控制和恢复技术后,最后在写,点查询,范围查询,空间放大等角度分析了两种合并方式的开销。

1 Introduction

1)日志结构的合并树(LSM-tree)被广泛应用于现代NoSQL系统的存储层.LSM树首先在内存中缓冲所有写操作,然后将它们刷新到磁盘,并使用顺序I/O合并它们。这种设计带来了许多优点,包括优越的写性能、高的空间利用率、可调性以及简化并发控制和恢复。这些优点使LSM树能够服务于各种各样的工作负载

2 LSM-tree basics

2.1 History of LSM-trees


通常,索引结构可以选择两种策略中的一种来处理更新,即就地(in-place)更新和非就地(即异位,out-of-place)更新。就地更新结构,如B+树,直接覆盖旧记录来存储新更新。例如,在图1a中,为了将key k1的值从v1更新到v4,索引条目(k1, v1)被直接修改以应用该更新。这些结构通常是读优化的,因为只存储每个记录的最新版本。然而,这种设计牺牲了写性能,因为更新会导致随机I/O。此外,索引页可以被更新和删除所分割,从而减少空间利用率。

异位(out-of-place)的更新结构,例如LSM-tree总是将更新存储到新的位置,而不是覆盖旧的条目。例如在图1b中,更新(k1, v4)被存储到一个新的位置,而不是直接更新旧的条目(k1, v1)。这种设计提高了写性能,因为它可以利用顺序I/O来处理写。它还可以通过不覆盖旧数据来简化恢复过程。然而,这种设计的主要问题是牺牲了读取性能,因为记录可能存储在多个位置中的任何一个。此外,这些结构通常需要一个独立的数据重组过程,以不断提高存储和查询效率



2.2 Today's LSM-trees

2.2.1 Basic structure

今天的LSM树实现仍然应用异位更新来减少随机I/O。所有传入的写操作都被追加到内存组件中。插入或更新操作只是添加一个新条目,而删除操作则添加一个antimatter条目,表明key已被删除。然而,目前的LSM树实现通常利用磁盘组件(disk components)[5] 的不变性来简化并发控制和恢复。多个磁盘组件合并(merge)[6]成一个新的组件,无需修改现有组件。这与原来的LSM树[51]提出的滚动合并过程不同。

在内部,可以使用任何索引结构实现LSM树组件。今天的LSM树实现——通常使用跳表或B +树等并发数据结构来组织内存组件而使用B+树或排序字符串表(sorted-string tables, SSTables)来组织磁盘组件。SSTable包含一个数据块列表和一个索引块:数据块存储按键排序的键值对,索引块存储所有数据块的键范围

LSM树上的查询必须搜索多个组件以执行协调(reconciliation),即查找每个键的最新版本。获取特定键值的点查找查询(point lookup query)可以简单地逐个搜索所有组件(从最新到最老),并在找到第一个匹配项后立即停止。范围查询(range query)可以同时搜索所有组件,将搜索结果输入优先级队列以执行调整。


随着时间的推移,磁盘组件越来越多,LSM-tree的查询性能趋于下降,因为必须检查更多的组件。为了解决这个问题,磁盘组件逐渐合并,以减少组件的总数.


2.2.2 Some well-known optimizations

目前大多数LSM树实现都使用了两种众所周知的优化。

Bloom filter    Bloom过滤器[12]是一种空间效率高的概率数据结构,旨在帮助回答集合成员查询(set membership queries)。它支持两种操作,即插入键和测试给定键的成员关系。为了插入一个键,它应用多个哈希函数将键映射到位向量中的多个位置,并将这些位置上的位设为1。为了检查给定键是否存在,该键再次散列到多个位置。如果所有位都是1,则Bloom过滤器报告键可能存在。按照设计,Bloom过滤器可以报告假阳性,但不能报告假阴性[8]

由于Bloom过滤器非常小,通常可以缓存到内存中,因此使用它们可以大大减少点查找的磁盘I/O数量。

Partitioning。另一种常用的优化是将LSM树的磁盘组件范围划分为多个(通常是固定大小的)小分区。为了尽量减少由不同术语造成的混淆,我们使用术语SSTable来表示这样的分区,它遵循LevelDB[40]中的术语。这种优化有几个优点。首先,分区将一个大的组件合并操作分解为多个较小的操作,限制了合并操作的处理时间以及创建新组件所需的磁盘空间。此外,分区可以通过只合并具有重叠键范围的组件来优化具有顺序创建键或倾斜更新的工作负载。对于按顺序创建的键,基本上不执行合并,因为没有键范围重叠的组件。对于倾斜更新,冷更新范围的组件的合并频率可以大大降低。需要注意的是,原来的LSM-tree[51]会自动利用分区,因为它可以滚动合并。然而,由于滚动合并的实现复杂性,今天的LSM树实现通常选择实际的物理分区而不是滚动合并。

将分区应用到LSM树的一个早期建议是分区指数文件(partitioned exponential file,PE文件)[35]。一个PE文件包含多个分区,其中每个分区在逻辑上都可以看作一个独立的LSM树。当一个分区变得太大时,可以进一步将其分割为两个分区。然而,这种设计在分区之间强制执行严格的键范围边界,这降低了合并的灵活性。

现在我们讨论在当今的LSM树实现中使用的分区优化。需要注意的是,分区与合并策略是正交的;leveling merge和tiering merge(以及其他新兴的合并策略)都可以用于支持分区。据我们所知,只有基于LSM的工业存储系统(如LevelDB[40]和RocksDB[57])完全实现了分区水平合并策略(partitioned leveling merge policy)。最近的一些论文[6,49,58,76,79]提出了各种形式的分区分层合并策略(partitioned tiering merge policy),以获得更好的写性能[9]


在LevelDB[40]首创的分区leveling merge policy中,每个级别(Level)的磁盘组件被范围划分为多个固定大小的SSTable,如图4所示。每个SSTable在图中都有其key范围的标记。注意,Level 0的磁盘组件没有分区,因为它们是直接从内存中刷下的。这种设计还可以帮助系统吸收突发写(absorb write bursts),因为它可以在Level 0容忍多个未分区组件。为了将Level L的SSTable合并为Level L+1的SSTable,我们将选取其所有Level L+1的重叠的SSTable[10],并将这些重叠的SSTable与之合并,生成新的仍在Level L+1的SSTable。例如在图4中,Level 1标记为0-30的SSTable与Level 2标记为0-15和16-32的SSTable合并。这个合并操作产生在第2级标记为0-10、11-19和20-32的新的SSTables,然后旧的SSTable将被垃圾收集。可以使用不同的策略来选择接下来在每个Level合并哪个SSTable。例如,LevelDB使用循环策略(round-robin policy)以最小化总的写开销。[11]

分区优化也可以应用到tiering merge policy中。然而,这样做的一个主要问题是,每个级别可能包含多个具有重叠键范围的SSTables。这些SSTable必须根据它们的近代性(recency)进行适当的排序,以确保正确性。在每个层次上,可以采用两种可能的方案来组织SSTable,即垂直分组和水平分组。在这两种方案中,每一层的SSTable被组织成组。垂直分组方案将键范围重叠的SSTable分组在一起,使分组具有分离的键范围。因此,它可以被看作是partitioned leveling merge的一种扩展,以支持tiering。或者,在水平分组方案下,每个逻辑磁盘组件被范围划分为一组SSTable,直接作为一个组。这允许在SSTable单元的基础上增量地形成磁盘组件。下面我们将详细讨论这两种方案。


垂直分组方案示例如图5所示。在这种方案中,具有重叠键范围的SSTable被分组在一起,这样分组就具有不相交的键范围。在合并操作中,一个组中的所有SSTable被合并在一起,根据下一层重叠组的键范围产生最终的SSTable,然后将这些SSTable添加到这些重叠组中。例如在图中,level 1标记为0-30和0-31的SSTable被合并在一起,生成标记为0-12和17-31的SSTable,然后加入到2级重叠组中。请注意合并操作前后的SSTable之间的区别。在进行合并操作之前,标记为0-30和0-31的SSTable具有重叠的键范围,点查找查询必须一起检查它们。然而,在合并操作之后,标记为0-12和17-31的SSTables具有不相连的键范围,并且只有其中一个需要通过点查找查询进行检查。还应当指出,在这一办法下,SSTable的规模不再是固定的,因为它们是根据下一级重叠组的键范围产生的。


图6显示了水平分组方案的一个示例。在该方案中,每个组件被范围划分为一组固定大小的SSTable,直接作为一个逻辑组。每个level L进一步维护一个活跃组,这也是第一个组,接收从上一级别合并的新SSTable。这个活动组可以看作是由Level L-1的组件在未分区情况下合并而成的部分组件。合并操作从一个级别上的所有组中选择键范围重叠的SSTable,并将得到的SSTable添加到下一级别的活跃组中。例如在图中,Level 1标记为35-70和35-65的SSTable被合并在一起,Level 2标记为35-52和53-70的SSTable被添加到第一组。然而,尽管在水平分组方案下,SSTable的大小是固定的,但仍然有可能一个组中的一个SSTable与其他组中的大量SSTable重叠。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容