我正在阅读Martin Kleppmann的《设计数据密集型应用程序》中的LSM索引。
作者指出:
写入时,将其添加到内存中平衡的树数据结构中(用于例如红黑树(。这个内存中的树有时被称为内存表
当内存表变得大于某个阈值时——通常是几兆字节--将其作为SSTable文件写入磁盘。这可以有效地完成,因为树已经维护了按键排序的键值对。新的SSTable文件成为数据库的最新段。当SSTable写入磁盘后,可以继续写入新的memtable实例
为了提供读取请求,首先尝试在memtable中查找密钥,然后在磁盘上最近的段,然后是下一个较旧的段,等等。
不时在后台运行合并和压缩过程合并段文件并丢弃覆盖或删除的值。
我的问题是:考虑到磁盘上的SSTables是不可变的,当新数据进来时,如何保证排序,这可以改变SSTables(而不是内存中的memtable(中数据的顺序?
例如,假设我们在磁盘上有一个SSTable,它有像[{1:a},{3:c},{4,d}]
这样的键值对。内存中的Memtable包含[{5,e},{6,f}]
(使用AVL/RB树进行排序(。假设我们现在得到一个新条目:[{2,b}]
,它应该位于[{1:a}]
和[{3:c}]
之间。如果磁盘上的SSTable是不可变的,该如何处理?理论上,我们可以用[{2,b}]
创建一个新的SSTable,然后压缩可以合并它们,但这不是打破了我们在压缩发生之前执行的范围查询/读取吗?
谢谢!
如果新数据即将到来,它们将登录到新的SST表中,而不是修改现有的表。每个SSTables都是单独读取的,然后从所有SSTables和memtable中合并数据,然后在发送之前按正确的顺序放入内存。例如,请参阅本文档,了解如何读取数据。