为啥 CouchDB 使用仅附加 B+ 树而不是 HAMT

Posted

技术标签:

【中文标题】为啥 CouchDB 使用仅附加 B+ 树而不是 HAMT【英文标题】:Why does CouchDB use an append-only B+ tree and not a HAMT为什么 CouchDB 使用仅附加 B+ 树而不是 HAMT 【发布时间】:2014-01-15 23:46:08 【问题描述】:

我正在阅读数据结构,尤其是像 CouchDB 中使用的 append-only B+ tree 和 Clojure 以及其他一些函数式编程语言中使用的 Hash array mapped trie 这样的不可变数据结构。

在内存中运行良好的数据结构在磁盘上运行不佳的主要原因似乎是由于碎片导致的磁盘寻道所花费的时间,就像普通的二叉树一样。

但是,HAMT 也很浅,因此不需要比 B 树更多的搜索。

另一个建议的原因是从数组映射树中删除比从 B 树中删除更昂贵。这是基于我们谈论的是密集向量的假设,并且在将任何一个用作哈希映射时都不适用。

此外,B 树似乎做了更多的重新平衡,因此以仅附加的方式使用它会产生更多的垃圾。

那么为什么 CouchDB 以及几乎所有其他数据库和文件系统都使用 B 树?

[编辑] 分形树?日志结构的合并树?头脑=炸毁

[edit] 现实生活中的 B 树使用以千计的度数,而 HAMT 的度数为 32。度数为 1024 的 HAMT 是可能的,但由于 popcnt 一次处理 32 或 64 位而速度较慢。

【问题讨论】:

它不会回答你的直接问题,但我建议阅读Purely Functional Data Structures。 【参考方案1】:

使用 B 树是因为它们是一种易于理解的算法,可以实现“理想的”排序顺序读取成本。因为键是排序的,所以移动到下一个或上一个键非常便宜。

HAMT 或其他散列存储以随机顺序存储密钥。键是通过它们的确切值来检索的,并且没有有效的方法来找到下一个或上一个键。

关于程度,通常是通过选择页面大小来间接选择的。 HAMT 最常用于内存,页面大小适合缓存行,而 btree 最常用于辅助存储,其中页面大小与 IO 和 VM 参数相关。

日志结构化合并 (LSM) 是一种不同的排序顺序存储方法,它通过权衡一些读取效率来实现更优化的写入效率。对于读取-修改-写入工作负载而言,读取效率的下降可能是一个问题,但未缓存的读取越少,LSM 提供的总体吞吐量就越多,而 btree 的整体吞吐量就越高 - 以更高的最坏情况读取延迟为外衣。

LSM 还承诺提供更广泛的性能范围。将新数据放入适当的位置是“延迟”的,通过控制延迟清理工作与实时工作的比例,提供了调整读写效率的可能性。理论上,零延迟的理想 LSM 是 btree,100% 延迟的理想 LSM 是日志。

但是,LSM 更像是一个算法“家族”,而不是像 btree 这样的特定算法。它们的使用越来越受欢迎,但由于缺乏事实上的最优 LSM 设计而受到阻碍。 LevelDB/RocksDB 是更实用的 LSM 实现之一,但远非最优。

实现写入吞吐量效率的另一种方法是通过写入延迟对 btree 进行写入优化,同时尝试保持其最佳读取吞吐量。

Fractal-trees、shuttle-trees、stratified-trees 就是这种设计,代表了 btree 和 LSM 之间的混合灰色区域。它们不是将写入延迟到离线进程,而是以固定方式摊销写入延迟。例如,这样的设计可能代表固定的 60% 写入延迟分数。这意味着它们无法实现 LSM 的 100% 写入延迟性能,但它们还具有更可预测的读取性能,这使得它们成为 btree 的更实用的替代品。 (与商业 Tokutek mysql 和 MongoDB 分形树后端一样)

【讨论】:

【参考方案2】:

Btrees 按它们的键排序,而在哈希映射中,相似的键具有非常不同的哈希值,因此彼此存储得很远。现在考虑一个执行范围扫描“给我昨天的销售额”的查询:使用哈希映射,您必须扫描所有映射才能找到它们,使用 sales_dtm 列上的 btree,您会发现它们很好地聚集在一起,您完全知道从哪里开始和停止阅读。

【讨论】:

以上是关于为啥 CouchDB 使用仅附加 B+ 树而不是 HAMT的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Haskell Maps 实现为平衡二叉树而不是传统的哈希表?

为啥有一个监督树而不是一个集中的监督者?

为啥大公司使用 Mnesia 而不是使用 Riak 或 CouchDB [关闭]

数据库为什么使用B+树而不是B树

用于数据库索引的排序字符串表 (SSTable) 或 B+ 树?

JDK8的HashMap为啥要引入红黑树?