LMDB封装的本地持久化队列与BDB持久化队列性能对比
文章首发于:clawhub.club
这几天一直研究怎么将LMDB作为持久化队列,今儿终于出来了一个简单的版本,以前用到的本地持久化队列是BDB封装的,虽然已经很稳定了,但是技术就应该有好的点子就去尝试一下,万一真的很不错呢。
经过简单的测试,效果真的还是可以的:
入队文件:110,592 字节;时间单位为纳秒。
//不手动执行 bdbQueue.sync()方法,测试结果
bdb offer 耗时:303738
lmdb offer 耗时:323650
bdb poll 耗时:446820
lmdb poll 耗时:42868
//手动执行 bdbQueue.sync()方法,测试结果
bdb offer 耗时:6290361
lmdb offer 耗时:386631
bdb poll 耗时:432605
lmdb poll 耗时:67527
从结果中可以看出,lmdb的读性能确实很好,写性能与BDB基本持平(当然是不手动执行DBD的sync命令,同步写入磁盘)。
封装的队列源码已经上传至github:https://github.com/ClawHub/queue-db,感兴趣的话可以看看,欢迎评论交流,互相学习。
简单介绍一下LMDB持久化队列封装的思路:
- 采用Kryo序列化框架
- 通过lmdb维护一个首指针(当前我只建了一个lmdb库,其实可以建另一个库专门存储一些和用户数据无关的元数据,比如首指针)
- lmdb时key-val数据库,值肯定是序列化之后的队列元素,键为Long类型的整数
- 系统启动后,首先查看lmdb中所有元素的数量,再将首指针的值与首指针所占用的一个位置考虑进来,维护一个内存变量:尾指针,这个用来作为插入数据的key。
- offer使用了AtomicLong所封装的尾指针来标记key的位置,所以不需要上锁。
- poll与peek使用了synchronized修饰。
- 操作lmdb时要应用事务,需要手动提交(封装好了)。
- 项目中也简单的写了几个单元测试,可以用来参考。
贴一段代码吧:
1 | /** |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ClawHub的技术分享!