rocksdb系列delete a range of keys

个人理解: delete a range of keys 就删除一定范围内的key, 比如删除所有以userid为前缀的keys

简单粗暴的方法

一种显而易见的方式就是遍历DB, 遇到特定范围里的key,直接调用Delete就可以了,这种方法适合于要删除的keys数量小的情况。另一方面, 这种方法有两个显著问题:

  • 问题一: 不能立刻收回资源,得等compaction完成后在能真正收回资源
  • 问题二: 大量的tombstones(也就是标记为del的key) 会减缓迭代器效率。

问题一的解决方法

  • 对要删除range key使用DeleteFilesInRange, 这个方法会直接删除只包含range keys的文件, 对于大块的range, 这个方法可以直接回收资源,值得注意的是:
    • 即使做完这个操作,一些在range keys范围内的数据依然存在于db中, 这个时候还需要一点的其他的opera
    • 这个操作直接忽视了snapshots, 导致可能通过snapshot 读不到本该可以读到的数据
  • compaction filter + compactRange, 一旦写个compaction filter, 做完compaction的时候,该删除的数据也没了。 在使用的时候, 可以设置CompactionFilter::IgnoreSnapshots = true, 这样的话, 就可以保证删除range keys,否则的话, 不能删除所有的keys , 这种方法也能很好的回收资源, 唯一的缺点是可能会增加I/O压力
  • 上述两种方法各有优缺点, 其实可以把他们综合起来, DeleteFilesInRange + compaction filter + compactRange

问题二的解决方法

这个问题比较难解决,可以仍然沿用问题一的解决方法。 但是,对大范围的range, 这种方法很有效, 如果range范围小,这种方法代价太高: 范围小导致DeleteFilesInRange可能并不能删除文件, CompactRange会对所有的包含delete range中的SST文件进行compaction,导致代价太高,这里有两种方法减轻这种代价

  • 如果你从来不改写已经存在的keys,使用DB::SingleDelete而不是Delete就可以很快消灭tombstones, 这种Tombstone可以很快被清除而不是被一直推到last level (笔者这里这不是很清楚, 待会看看)
  • 使用NewCompactOnDeletionCollectorFactory(), 可以在有大量tombstones的时候加快compaction
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容