LSM -Log Structured Merge Trees 算法原理

为什么需要LSM算法

LSM被设计来提供比传统的B+树或者ISAM更好的写操作吞吐量,通过消去随机的本地更新操作来达到这个目标。
设计LSM算法的本质是:磁盘随机操作慢,顺序读写快。磁盘随机操作与顺序操作存在这巨大的差距,无论是磁盘还是SSD。
这里写图片描述
上图很好的说明我们要避免随机读写,最好设计成顺序读写。
如果我们对写操作敏感,最好的办法是采用顺序写,将数据直接添加到文件。这种策略通常被使用日志文件或者堆文件中。可以提供非常好的写操作性能。

因为简单和高效,基于日志的策略在大数据之间越来越流行,同时他们也有一些缺点,从日志文件中读一些数据将会比写操作需要更多的时间,需要倒序扫描,直接找到所需的内容。

这说明日志仅仅适用于一些简单的场景:
1. 数据是被整体访问,像大部分数据库的WAL(write-ahead log)
2. 知道明确的offset,比如在Kafka中。

所以,我们需要更多的日志来为更复杂的读场景(比如按key或者range)提供高效的性能,这儿有4个方法可以完成这个,它们分别是:

  1. 二分查找: 将文件数据有序保存,使用二分查找来完成特定key的查找。
  2. 哈希:用哈希将数据分割为不同的bucket
  3. B+树:使用B+树 或者 ISAM 等方法,可以减少外部文件的读取
  4. 外部文件: 将数据保存为日志,并创建一个hash或者查找树映射相应的文件。

所有的方法都可以有效的提高了读操作的性能(最少提供了O(log(n)) ),但是,却丢失了日志文件超好的写性能。上面这些方法,都强加了总体的结构信息在数据上,数据被按照特定的方式放置,所以可以很快的找到特定的数据,但是却对写操作不友善,让写操作性能下降。

所以这就是 LSM 被发明的原理, LSM 使用一种不同于上述四种的方法,保持了日志文件写性能,以及微小的读操作性能损失。本质上就是让所有的操作顺序化,而不是像散弹枪一样随机读写。

LevelDB 中SSTable 和Log Structured Storage

SSTable 和MemTable

SSTable本质上是一个文件。文件里的键值对都是有序的, SSTable一旦创建就是不可变的。为了能够快速访问SSTable,可以通过索引进行访问。MemTable顾名思义,是存放在内存里的key-value键值对。SSTable和MemTable的关系图如下:
这里写图片描述

  • SSTable的索引文件总是加载到内存里。
  • SSTable存放在磁盘文件里。
  • 所有的写操作直接写到MemTable里。
  • 读操作时先检查MemTable里是否存放数据。如果没有则在SSTable indexs中进行搜索。
  • 定时的把MemTable中的数据刷新到磁盘中的SSTable中。
  • 定时的,磁盘中的SSTable做merge操作合并为大的SSTable。
LSM & SSTables:update 和delete 维护

LSM算法有很多有趣的特性,写总是很快的无论数据集多大。写操作是(append-only),写操作在内存中完成,然后flush到disk。读操作先是从Memtable中查找,当一个读操作请求时,系统首先检查内存数据(memtable),如果没有找到这个key,就会逆序的一个一个检查sstable文件,直到key 被找到。因为每个sstable都是有序的,所以查找比较高效(O(logN)),但是读操作会变的越来越慢随着sstable的个数增加,因为每一个 sstable都要被检查。

LSM的更新操作存放在Memtable中。删除操作也存放在Memtable中,记录中标记为已删除记录。

所以系统会周期的执行合并操作(compaction)。 合并操作选择一些文件,并把他们合并到一起,移除重复的更新或者删除纪录,同时也会删除上述的冗余。更重要的是,通过减少文件个数的增长,保证读操作的性 能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值