LSM树并发的难点
LSM树中的并发挑战主要与切换表视图(在刷写和压缩过程中更改的内存驻留表和磁盘驻留表的集合)和日志同步有关。memtable通常也是并发访问的。
LSM树并发需要遵守的原则
1.新的memtable必须对读写可用。
2. 旧的(正在刷写的)memtable必须对读保持可见。
3. 正在刷写的memtable必须写到磁盘上。
4. 丢弃已经刷写的memtable与创建刷写磁盘驻留表这两个操作必须被原子地执行。
5. 预写日志中,记录之前曾应用于被刷写memtable的操作的日志段必须被丢弃。
LSM实现原理
- memtable切换在此之后,所有的写操作都去到新的memtable,使其成为主memtable,而旧的memtable仍可用于读操作。
- 刷写完成在表视图中用刷写完的磁盘驻留表来替换旧的memtable。
- 预写日志截断丢弃持有与被刷写memtable相关联的记录的日志段。
这些操作隐含着严苛的正确性要求。继续写入旧的memtable可能导致数据丢失(例如,如果写入已被刷写的memtable段)。
类似地,在驻留磁盘的对应部分准备就绪之前,如果旧的memtable不提供读取,则将导致读取到不完整的结果。
在compatition期间,表视图也会更改,但这里的过程稍微简单一些:旧的磁盘驻留表被丢弃,而被compatition的版本则被添加进来。旧表必须保持可访问性,直到新表完全写入并准备好代替它进行读操作。同一个表参与多个并行压实的情况也必须避免
日志截断异常引起的数据丢失或错误
不将日志截断与刷盘同步也会导致数据丢失:如果在刷盘完成之前丢弃了日志段,并且在此时节点崩溃,那么这些日志内容将不会被重放,从而导致该段的数据也不会被恢复。