技术开发 频道

基于LevelDB存储引擎的Tair系统实战

   ①Tair中会有桶迁移或者namespace清理的操作,废弃的数据并不会立刻清理,依靠后续的compact进程清理。但同时桶又可能被迁移回来,namespace也可能继续使用。leveldb中的SequnceNumber恰好可以标识数据的时间点,所以在做数据清理的时候,记录下当时的SequnceNumber(sequnce_),在做判断的时候,只有小于sequnce_的数据才认为可以被丢弃。

  ②filenumber_是为了缩小主动compact的范围。

  leveldb自身进行compact的过程中,加入自实现 comparator 的 ShouldDropMaybe()/ShouldDrop() 判断逻辑,会将对应的gc数据清理。但leveldb自身的compact进程并不能保证将所有的数据清理掉,所以添加compact的定时线程,主动触发compact做数据清理。对于清理的bucket或者namespace,根据key的格式,可以构造出需要compact的key-range,但直接使用leveldb提供的CompactRange有以下问题:

  ①如果某个sstable在记录gc之后已经被compact过,所要清理的数据就已经丢弃掉了,并不需要再做compact。

  ②主动触发的compact并不是基于均衡db状态,所以造成的level迁移可能会有反作用。

  对于①、②的问题,做以下策略:

  ①FileNumber全局递增可以用来标识时间点,gc时,记录下当时的FileNumber,主动compact时,只需要选取符合key-range并且FileNumber小于记录的filenumber_的sstable即可,缩小需要compact的sstable范围。

  ②主动触发的compact只选取level-n中的sstable,compact后,也只生成level-n中的sstable,level之间的均衡,仍由内部compact进程负责。

  3)基于上述①②,为leveldb添加CompactRangeSelfLevel()逻辑,实现1) 2)中的策略,主动触发compact以清理数据,整个db的均衡仍由内部的机制保证。

  gc信息会同时记binlog,在server重启时replay。

  2)过期的数据

  因为过期是一个持续的时间状态,如果要完全回收过期的数据,只能对全db做compact,这样做的性能比不合算,所以目前对过期数据不做特别的主动清理,依靠内部以及外部触发的compact进程中回收空间。

  6. 上层cache

  leveldb内部有sstable元信息和block数据的cache,优化读的效率,在leveldb上层再嵌入Tair自带的mdb做KV层面的cache,并添加cache的信息统计。当前统计看到,热点数据的读基本落在mdb中。

  7. 后续的优化

  ①leveldb本身的一些优化(参见leveldb的实现解析)。

  ②优化网络的使用,使用新的网络框架。

  ③ssd使用优化。leveldb内部做的一些细节优化针对于sas盘的IO性能,当前使用的ssd IO能也未充分利用。后续针对提升ssd使用性能做相应的IO优化(dio)。

  ④内存的优化使用。大内存的使用有很大的优化余地,避免swap的使用,pagecache的相应回写策略配置。

  ⑤对不存在数据查找的优化,采用mock value处理或者添加bloomilter。

  ⑥range 以及数据dump功能的实现。

0
相关文章