我正在寻找一个满足某些属性的节省空间的键值映射/字典/数据库:
- 格式:密钥将由 http(s) URI 表示。这些值将是可变长度的二进制数据。
- 大小:将有 1-1000 亿个唯一键(平均长度 60-70 字节)。值最初只有几十个字节,但最终可能会增长到几十千字节(如果我决定存储多个版本,可能会更多)。数据的总大小将以 TB 或 PB 为单位。
- 硬件:数据必须分布在多台机器上。此分布应确保来自特定域的所有 URI 最终位于同一台机器上。此外,机器上的数据必须根据访问频率在 RAM、SSD 和 HDD 之间分配。随着机器从集群中添加或删除,数据将不得不转移。最初不需要复制,但以后可能会有用。
- 访问模式:我需要对数据进行顺序访问和(某种程度上)随机访问。顺序访问将来自持续扫描数据的低优先级批处理。在这种情况下,吞吐量比延迟重要得多。理想情况下,迭代将按字典顺序(即字典顺序)进行。随机访问源于访问 HTML 页面中的 URI,我希望其中大多数将指向与页面相同域的 URI,因此将位于同一台机器上,而其他将位于不同的机器上。我预计每秒最多需要 100,000 到 1,000,000 次内存随机访问。数据不是静态的。读取将比写入多发生一到两个数量级。
最初,数据将由 1 亿到 10 亿个 url 组成,每个 url 有几十个字节的数据。它将托管在少量具有 10-20GB 内存和几 TB 硬盘驱动器的廉价商品服务器上。在这种情况下,大部分空间将被用于存储键和索引信息。出于这个原因,并且因为我的预算很紧,我正在寻找可以让我将这些信息存储在尽可能小的空间中的东西。特别是,我希望利用许多 URI 共享的公共前缀。通过这种方式,我相信可以将键和索引存储在比 URI 总长度更小的空间中。
我看过几种传统的数据结构(例如哈希映射、自平衡树(例如红黑、AVL、B)、尝试)。只有尝试(有一些技巧)似乎有可能减少索引和键的大小(除了索引之外,所有其他的都存储键)。我想到的最有希望的选择是将 URI 拆分为几个组件(例如 example.org/a/b/c?d=e&f=g 变成 [example, org, a, b, c, d=e , f = g])。各种组件将在树状结构的后续级别中分别索引一个子级,有点像文件系统。这似乎是有利可图的,因为许多 URI 共享相同的域和目录前缀。
不幸的是,我对各种数据库产品知之甚少。我知道他们中的很多人使用 B 树来索引数据。据我了解,索引和键所需的空间超过了 URL 的总长度。
因此,我想知道是否有人可以就任何可以利用 URI 中的冗余来节省空间的数据结构或数据库提供一些指导。其他的东西不太重要,但任何帮助也将不胜感激。
谢谢,对冗长感到抱歉;)