写放大优化
若数据库写入为10M/s,磁盘写入的30MB/s(如compaction时io导致),则写入放大为3(使用iostats
),[写入放大率会缩短闪存寿命](Optimizing Space Amplification in Rocksdb)。
kv分离
[WiscKey](separting keys from values in ssd-conscious storage)
专门为SSD设计,将键值分开,该论文时基于leveldb进行改造且已经开源
changlenges: GC, crash consistency, range scan(需要加随机读)
range scan
预取:readahead,vlog发现有顺序特征,则根据命中次数指数级增长预取量。
GC
- 脱机方案:遍历所有sst并记录value log大小,删除无引用部分。
- 在线方案:在vlog中多存储了键值,然后从vlog文件的尾部开始扫kv对,及时更新vlog,tail为文件尾部,head为追加点,扫到一个kv就从LSMtree中查找,如果该值尚未被覆盖或删除(偏移和LSMTree一致),则追加到head,扫描完vlog后清除tail往后的数据则完成压缩。
crash consistency
崩溃一致性是指FLUSH和COMPACTION的时候崩溃
- (vlog和lsm写)异步情况:LSMtree写好了,但是vlog只写了一部分,需要在LSM中增加校验,查找key时如果发现不一致(包括key和value大小),则从LSMTree删除该key,并且返回NOT FOUND。
- 同步情况:先写vlog再写LSMtree就没问题。
pingcap:titan
参考[WiscKey的论文](separting keys from values in ssd-conscious storage)做的一个Rocksdb插件,已经开源 减少写放大,适配rocksdb6.4 目前版本6.10,类似的产品还有ali的XEngine(for polardb)
特点
优点:当kv对值较大时,titan在写入,更新和点读取方案中的性能要明显优于rocksdb (主要是compaction加快了),较小时则一样(相当于没改)。
缺点:牺牲存储空间和范围查询性能,需要进行GC,可能有部分rocksdb接口不兼容
兼容性
不明确支持 Merge(类似于append功能, instead get put),SingleDelete(删除某个条目,有点像撤回)
实现
分离
在FLSUH和COMPACTION时进行分离
将值存在blob文件中 - 看结构就和sst没什么区别,只是少了index_block
blob file 使用LZ4进行压缩
TitanTableBuilder