随笔 - 171  文章 - 0  评论 - 0  阅读 - 62154

LSMT(Log-Structured Merge-Tree)

LSM简介Log Structured Merge Tree,下面简称 LSM。2006年,Google 发表了 BigTable 的论文。这篇论文提到 BigTable 单机上所使用的数据结构就是 LSM。目前,LSM 被很多存储产品作为存储结构,比如 Apache HBase, Apache Cassandra, MongoDB 的 Wired Tiger 存储引擎, LevelDB 存储引擎, RocksDB 存储引擎等。简单地说,LSM 的设计目标是提供比传统的 B+ 树更好的写性能。LSM 通过将磁盘的随机写转化为顺序写来提高写性能 ,而付出的代价就是牺牲部分读性能、写放大(B+树同样有写放大的问题)。LSM 相比 B+ 树能提高写性能的本质原因是:外存,其随机读写都要慢于顺序读写,无论磁盘还是 SSD。
  1. 追加写日志,顺序写提高写入效率。
  2. 构建SSTables(sorted string tables)。
    1. 写入时,首先写入Memtable内存表(排序结构,保存键和磁盘偏移位置)。当内存表大于某个阈值,作为SSTables写入磁盘。防止数据库崩溃,导致写入内存表,但还未写入磁盘的数据丢失,可以进行wal,类似于redo log。
    2. 读取时,首先在内存表中查找键,然后是最新的磁盘段文件,接下来是次新的磁盘段文件,直到找到目标(或为空)。防止查找数据库中某个不存在的键很慢,引入布隆过滤器。对于数据库中不存在的某个键,会很快告诉你结果。
  3. 压缩SSTables
    1. 后台进程周期性地合并与压缩磁盘段。这个阶段可以用旧段继续正常读取、写入,合并完成后切换新段。
0

对比 B-tree与LSM-tree

尽管 B-tree的 实现比 LSM-tree的实现更为成熟,然而由于 LSM-tree的性能特点, LSM­ tree目前很有吸引力 。根据经验,LSM-tree通常对于写入更快,而B-tree被认为对于读取更快。读取通常在LSM-tree上较慢,因为它们必须在不同的压缩阶段检查多个不同的数据结构和SSTable。

然而,基准测试通常并不太确定, 而且取决于很多工作负载的具体细节。最好测试特定工作负载 ,这样方便进行更有效的比较 。

LSM-tree的优点

B tree索引必须至少写两次数据 : 一次写入预写日志,一次写入树的页本身(还可能发生页分裂)。即使该页中只有几个字节更改,也必须承受写整个页的开销。 一 些存储引擎甚至覆盖相同的页两次,以避免在电源故障的情况下最终出现部分更新的。

由于反复压缩和SSTable的 合井, 日志结构索引也会重写数据多次。这 种影响(在数据库内,由于一次数据库写入请求导致的多次磁盘写)称为写放大。对于SSD, 由于只能承受有限次地擦除覆盖,因此尤为关注写放大指标

对于大量写密集的应用程序,性能瓶颈很可能在于数据库写入磁盘的速率。在这种情况下,写放大具有直接的性能成本: 存储引擎写入磁盘的次数越多,可用磁盘带宽中 每秒可以处理的写入越少。

此外, LSM-tree通常能够承受比B-tree更高的写入吞吐量, 部分是因为它们有时具有较低的写放大(尽管这取决于存储引擎的配置和工作负载),部分原因是它们以顺序方式写入紧凑的SSTable文件, 而不必重写树中的多个页。这种差异对于磁盘驱动器尤为重要 ,原因是磁盘的顺序写比随机写要快得多。

LSM-tree可以支持更好地压缩,因此通常磁盘上的文件比 B-tree小很 多。由于碎片, B-tree存储引擎使某些磁盘空间无陆使用,当页被分裂或当一行的内容不能适合现 有页时,页中的某些空间无能使用。由于 LSM tree不是面向页的,并且定期重写SSTables,以消除碎片化,所以它们具有较低的存储开销,特别是在使用分层压缩时。

在许多SSD上,固件内部使用日志结构化算位将随机写入转换为底层存储芯片上的顺序写入,所以存储引擎写入模式的影响不那么明显。然而,更低的写放大和碎片减少对于SSD上仍然有益,以更紧凑的方式表示数据,从而在可用的 1/0带宽中支持更多的读写请求。

LSM-tree的缺点

日志结构存储的缺点是压缩过程有时会干扰正在进行的读写操作。即使存储引擎尝试 增量地执行压缩,并且不影响并发访问,但由于磁盘的井发资源有限,所以当磁盘 执行昂贵的压缩操作时,很容易发生读写请求等待的情况 。这对吞吐量和平均响应 时间的影响通常很小,但是如果观察较高的百分位数日志结构化存储引擎的查询晌应时间有时会相当高,而 B-tree的响应延迟则更具确定性。

高写入吞吐量时, 压缩的另一个问题就会冒出来:磁盘的有限写入带宽需要在初始写入(记录井刷新内存表到磁盘)和后台运行的压缩线程之间所共享。写 入空数据库时,全部的磁盘带宽可用于初始写入,但数据库的数据量越大,压缩所需的磁盘带宽 就越多。

如果写入吞吐量很高井且压缩没有仔细配置,那么就会发生压缩无法匹配新数据写入速率的情况。在这种情况下,磁盘上未合并段的数量不断增加,直到磁盘空间不足,由于它们需要检查更多的段文件,因此读取速度也会降低 。通常,即使压缩不能跟上,基于 SSTable的存储引擎也不会限制到来的写入速率,因此需要额外的监控措施来及时发现这种情况。

B-tree的优点则是每个键都恰好唯一对应于索引 中的某个位置,而日志结构的存储引 擎可能在不同的段中具有相同键的多个副本。如果数据库希望提供强大的事务语义, 这方面 B-tree显得更具有吸引力:在许多关系数据库中, 事务隔 离是通过键范围上的 锁来实现的,井且在 B-tree索引中,这些锁可以直接定义到树中。

B tree在数据库架构中已经根深蒂固,为许多工作负载提供了 一贯良好的性能,所以 不太可能在短期内会消失。对于新的数据存储,日志结构索引则越来越受欢迎。不存在快速和简单的规则来确定哪种存储 引擎更适合你的用例 , 因此, 实地的测试总是需要的。

 

posted on   zhengbiyu  阅读(992)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示