database - B+ 树节点大小

标签 database theory couchdb b-tree

我正计划使用类似于 CouchDB 的文件架构编写一个简单的键/值存储,即一个仅附加的 b+树。

我已经阅读了在 B+ 树上可以找到的所有内容以及在 CouchDB 内部可以找到的所有内容,但是我没有时间研究源代码(使用一种非常不同的语言使它成为一个独立的特殊项目)。

所以我有一个关于 B+ 树节点大小的问题:给定的 key 长度是可变的,是让节点保持相同的长度(以字节为单位)更好还是给定更好无论它们变得有多大,它们都有相同数量的键/子指针?

我意识到在传统数据库中,B+ 树节点以字节为单位保持固定长度(例如 8K),因为数据文件中的空间是在固定大小的页面中管理的。但是在文档可以是任意长度并且之后写入更新的树节点的仅附加文件方案中,拥有固定大小的节点似乎没有任何优势。

最佳答案

b 树的目标是最小化磁盘访问次数。如果文件系统簇大小为 4k,则节点的理想大小为 4k。此外,节点应正确对齐。未对齐的节点将导致读取两个集群,从而降低性能。

对于基于日志的存储方案,选择 4k 节点大小可能是最糟糕的选择,除非在日志中创建间隙以改进对齐。否则,99.98% 的时间一个节点存储在两个集群上。对于 2k 节点大小,发生这种情况的几率略低于 50%。然而,小节点尺寸存在一个问题:b-tree 的平均高度增加并且读取磁盘簇所花费的时间没有得到充分利用。

较大的节点大小会降低树的高度,但也会增加磁盘访问次数。较大的节点还会增加维护节点内条目的开销。想象一个 b 树,其中节点大小足以封装整个数据库。您必须在节点本身内嵌入更好的数据结构,也许是另一个 b 树?

我花了一些时间在仅附加日志格式上设计了一个 b 树实现的原型(prototype),并最终完全拒绝了这个概念。为了补偿由于节点/集群未对齐造成的性能损失,您需要有一个非常大的缓存。更传统的存储方法可以更好地利用 RAM。

最后一击是在我评估随机排序插入的性能时。这会降低任何磁盘支持的存储系统的性能,但基于日志的格式受到的影响要大得多。即使是最小条目的写入也会强制将多个节点写入日志,并且内部节点在写入后不久就会失效。结果,日志迅速填满了垃圾。

BerkeleyDB-JE(BDB-JE)也是基于日志的,我也研究了它的性能特点。它遇到了与我的原型(prototype)相同的问题——垃圾迅速堆积。 BDB-JE 有几个“更干净”的线程,它们将幸存的记录重新附加到日志中,但保留了随机顺序。结果,新的“干净”记录已经创建了充满垃圾的日志文件。系统的整体性能下降到唯一运行的是更清洁的东西,并且它正在占用所有系统资源。

基于日志的格式非常有吸引力,因为可以快速实现一个健壮的数据库。致命弱点是清洁器,这是非常重要的。缓存策略也很难做到正确。

关于database - B+ 树节点大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2678559/

相关文章:

mapreduce - 为什么 CouchDB 减少函数接收 'keys' 作为参数

Django 和 CouchDB - 通用身份验证后端

MySQL:回滚时间更长?

python - 操作错误 : database is locked

algorithm - 基本编程/算法概念

algorithm - 最重要的算法是什么?

ember.js - 扩展 Ember RESTAdapter 以与 CouchDB 配合使用

database - 对所有数据库使用单个查询

python - 如何在 Python 中获取 SQLite 结果/错误代码

java - 定义中的初始化与构造函数中的初始化