1. 典型LSM Tree架构图

2. LSM Tree特点
LSM树的特点是利用顺序写来提高写性能,因为内存结构和磁盘文件的分层设计会降低读性能,但是通过牺牲小部分读性能换来提供写性能,使得LSM树成为非常流行的一种存储结构。
与传统的基于 B 树的实现相比,LSM 提供高写入吞吐量的主要原因是每个写入请求实际上仅在内存中执行,而基于B树的更新在磁盘上完成,这可以触发对索引的更新,但非常昂贵。
3. LSM组成部分
3.1 WAL
WAL用于在系统故障期间提供数据的持久性,当写入请求进来时,数据首先写入到 WAL 文件并且在更新内存结构之前刷新到磁盘(使用Direct IO)。允许系统在将内存数据结构持久化到磁盘之前宕机时从 WAL 中恢复。
为什么不直接更新写入磁盘而不是更新WAL?这是因为 WAL 更新更便宜,因为它是仅附加的,不需要对磁盘上的数据进行任何重组。
3.2 MemTable
内存中的数据结构称为Memtable,Memtable有多种实现,但为了简单起见可以将Memtable视为二叉搜索树。所以现在对于每个写请求,数据被附加到 WAL 并更新 Memtable,并向客户端返回一个成功的响应。
3.3 SSTable(Sorted Strings Table)
随着Memtable膨胀,会不定期刷新到磁盘SSTable结构。SSTable是一个存储在磁盘上的有序键数组,对它进行排序的原因是为了便于查找读取的数据。
WAL、MemTable和SSTable,是提供高吞LSM Tree吐量的本质。
3.4 Compactor
当不断将SSTable刷新到磁盘时,同一个键可能会出现在多个 SSTable 中,尽管一个键的最新数据存在于最近的 SSTable 中,但它在所有以前的 SSTable 中都需要清理。这是通常在后台运行的压缩器的工作,它通过删除冗余和删除的键并创建压缩/合并的 SSTable 来合并 SSTable。压缩器还负责更新索引(典型的基于 B 树的索引)以定位存在键的 SSTable。
3.5 Index
创建的索引数据结构用于为键定位正确的 SSTable,一旦定位到 SSTable,就很容易在 SSTable 内部找到实际的键,因为它已排序,内存中的二进制搜索就足够了。
此外,SSTables 的大小是这样选择的,即它对应于操作系统页面大小(通常是磁盘块大小的倍数),从而更容易更快地将数据加载到内存中。
尽管索引和 SSTable 有助于更快地查找键,但首先在 Memtable 中查询所有读取请求,因为它应该包含最近的更改。如果键不在内存表中,则使用索引来识别键可能存在的可能 SSTable,然后在内存中的 SSTable 中进行搜索。
3.6 BloomFilter
由于每次读取都必须检查内存表、索引和 SSTable 以查找键,因此读取请求非常昂贵,尤其是对于不存在的键!对于最近更新的键,读取请求将很容易在内存表中找到它,但是对于最近没有更新的键,对于系统中不存在的键,读取路径是昂贵的!
布隆过滤器一种概率数据结构,它可以帮助您检查系统中是否存在键,内存中的复杂度为 O(1),用于提高读取性能,特别是对于系统中不存在键的情况。
布隆过滤器存在误报,如果报一个键存在,实际可能并不存在。但如果报一个键不存在,那实际一定不存在。
布隆过滤器提高了系统中不存在键的读取性能,但对于系统中存在的键,读取仍然很昂贵,因为我们必须查看内存表、索引和 SSTable。
4 LSM Tree应用
- Hbase
- LevelDb
- Kudu
- ClickHouse
- Kafka
参考
https://medium.com/swlh/log-structured-merge-trees-9c8e2bea89e8
8672

被折叠的 条评论
为什么被折叠?



