前段时间在做大数据的KV引擎应用,测试了leveldb的性能,感觉挺好的,美中不足的是他是基于磁盘读写。在我们的场景里,IO频率预计会远远超出磁盘的承受能力,并且太频繁的读取可能也会引发磁盘恶化的速度。
所以考虑再三,决定使用leveldb+memory的形式。
具体的实时方法很简单了,有很多前辈写过leveldb+kt的封装、启动说明。[bluecase:kyoto tycoon + leveldb存储的性能优化]
需要注意的是,如果像我们一样,要启用kt的expire字段,那么是不用加上“#ktopts=p”的。
后面的操作就是挂载内存了,64G Server,挂载32G tmpfs,优点是读写性能达到内存IO水平,进程重启无丢失;缺点是机器关机后会丢失数据。
接下来的使用封装都比较简单。
后面比较难的地方在于,内存中的空间是有限的(32G),不能无休止的让leveldb使用,这部分我查了一些文档,推荐这篇[leveldb]中 Compaction 一章,如壶灌顶,清楚了目标是调整 size_compacion 和 seek_compacion。
目前还没有比较好的成果,但是原理上已经可以预见就是这个方法了,compation最难的地方在于会损耗大量随机磁盘IO,但是在memory情况下是没关系的。
另外就是最后一个考虑的地方,kt如果封装了expire time,那么到期后是否会调用delete删除呢?从技术上看他是不会这样做的,因为kt层不会记录所有的expire情况,所以所有的leveldb中保存的key:value 都是有效key:value,就算有compation也不能挽救空间的耗尽,只是kt在封装leveldb的时候会没有考虑这一点吗?
---- update 15:57
对于这种极限情况,也是有办法的,根据leveldb源码的 DBUmpl:: BackgroundCompaction 函数的操作,我们是有机会把kt的expire time检查加入到有效key检查的过程里,判断超过expire time大于2小时,其实就可以删除了。
这样的改动优点是不用影响现有架构,缺点是研究/自测成本的额外投入:绕过kt查看leveldb存储,得出expire time字段转换时间的方法;修改leveldb代码,根据expire time再判断一次key是否可以删除。
最后做一次测试。
如果如愿的话很容易就完成内存空间的拯救了。加油。