【发布时间】:2019-04-02 03:46:42
【问题描述】:
我正在设计Content-addressable storage,所以我正在寻找一个哈希函数来生成对象标识符。每个对象都应该以这种方式根据其内容获得短 ID:object_id = hash(object_content)。
先决条件:
- 散列函数应该很快。
- 碰撞概率必须尽可能低。
- 最佳 ID 长度为
32字节,以便最多寻址256^32对象(但此要求可能会放宽)。
考虑到这些要求,我选择了SHA256 哈希,但不幸的是它对我的目的来说不够快。我能够进行基准测试的SHA256 的最快实现是openssl 和boringssl:在我的桌面上Intel Core I5 6400 它为每个内核提供了大约420 MB/s。其他实现(如 Go 中的 crypto/rsa)甚至更慢。我想用其他哈希函数替换 SHA256,它提供与 SHA256 相同的冲突保证,但提供更好的吞吐量(每个内核至少 600 MB/s)。
请分享您对解决此问题的可能选项的意见。
我还想指出,硬件更新(例如购买带有AVX512 指令集的现代 CPU)是不可能的。重点是找到能够在商品硬件上提供更好性能的哈希函数。
【问题讨论】:
-
在这里查看哈希值:github.com/rurban/smhasher。顺便说一句,我真的不知道你所说的“地址”是什么意思,但是一个 32 字节的 ID 可以有 256^32 个不同的值(不是 8^32)。
-
@geza,谢谢,那是个错误。 “地址”是指系统中可能存在的对象总数的上限。
-
1.一个系统中可能存在的对象总数的上限为 256^32 确实很大,大约 10^76!考虑到已知的可观测宇宙中只有大约 10^78 到 10^82 个原子,我想知道您将如何存储这些对象。 2. SHA256 不是无冲突的。
-
3.当用于索引的散列通常使用快速散列并期望发生冲突时,可以通过使用列表或重新散列来感受冲突。 4. 如果'如果两个具有不同内容的对象获得相同的ID,身份系统将被彻底破坏'仅使用哈希时系统被设计破坏。
-
@zaph 1. 我同意这个数量的密钥太大并且不可能达到。但是由于某些原因,成熟的键值存储倾向于使用长键。例如,github.com/reverbrain/elliptics 使用 SHA512 作为内部存储密钥; 2. 是的,SHA256 不是无冲突的,但发生冲突的概率接近于零。 SHA256 是 ZFS 内置重复数据删除系统的默认哈希,据我所知,启用 SHA256 时没有任何冲突检查技术(它们仅在使用 Fletcher4 等弱哈希时检查冲突)。跨度>