LMDB的内部设计有什么特别之处?

10

不考虑LMDB的所有功能(如事务、隔离、共享访问等),一些C++实现的内存B-Tree(例如google btree)与LMDB之间的性能差异将会是什么(读取/写入)?

1个回答

16
这个2014年的lmdb设计演示文稿是由其架构师Howard Chu撰写的,涵盖了lmdb的设计和权衡。
总结一下:lmdb是一个复制-写入、从下到上更新、双缓冲区B树,实现始终优先考虑简单性,遇到其他因素时会做出妥协。
智能的设计选择使它成为最高性能和抗损坏B树实现之一。
  • 复制-写入意味着数据永远不会被覆盖,避免了许多可能的损坏场景
  • 从叶子到根的自底向上更新使得根更新等同于提交
  • 过去版本的双重缓冲仅保留了数据库文件中的最后两个根
  • 避免了复杂的多级缓存方案——lmdb依靠底层操作系统进行缓存
  • 与其他数据库相比,整个代码库非常小,避免了CPU缓存未命中
显然,这些选择意味着lmdb并不适用于复杂情况,如:
  • 多版本数据库回滚(仅可用于最后2个版本)
  • 长期事务和延迟提交:这些会导致只能进行添加操作,并且数据库文件可能无限增长
  • 多个并发写入者:lmdb倾向于更简单的多读单写方案
完整演示文稿有超过100页,内容更加详细。以上是lmdb精神的概括。 lmdb作为Open LDAP和Memcached等知名开源项目的核心存储引擎使用,在这些情况下,与替代方案相比观察到了数量级的速度提升,可以在微基准测试结果中看到。

你能解释一下为什么LMDB在写入方面更快,考虑到需要(在lmdb中)在实际写入之前复制许多页面吗?在经典的B-Tree中,我不需要为页面复制花费CPU(直接修改数据)。 - pavelkolodin
1
根据幻灯片,我的理解是lmdb简单地优化了最常见的情况并避免了复杂性。就地修改数据(而不是COW)是不免费的:它涉及:1)复杂的锁定机制2)维护用于恢复等的事务日志,这些都是lmdb所避免的。基于lmdb的经验,这种复杂性最终会超过好处(对于最常见的情况,当然不是所有情况)。作者还提到代码规模小可以提高速度(完整代码适合当前典型CPU的L1缓存)。 - arielf
第一个链接已失效,可以在这里找到它:http://schd.ws/hosted_files/buildstuff14/96/20141120-BuildStuff-Lightning.pdf。 - wuxb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接