【问题标题】:On-disk structure for storing a large set of 128-bit integers?用于存储大量 128 位整数的磁盘结构?
【发布时间】:2010-11-21 23:08:12
【问题描述】:

我有大约 5 亿个 128 位整数,每年增加大约 1 亿个。什么都不会被删除。这些数字在规模和时间上呈均匀分布。

基本上,我所需要的只是一个添加操作,该操作还返回该数字是否已存在于数据库中。另外,我不想为这个系统使用太多的 RAM,所以只将所有内容存储在内存中并不是我想要的。

到目前为止,我们已经在 MySQL 上使用了几个 MyISAM 表,使用两个 bigint 作为主键。这给了我们不错的性能,但我怀疑它不是这项工作的正确工具。我们在拆分表之前遇到了一些性能问题,并且我们在停电时遇到了损坏。此外,DB 为我们提供了更多我们不需要的功能。

我在 Linux 上使用 Python,但我愿意接受建议。

Similar question in C++.

更新:Marcelo 的评论提到了Bloom Filter,这对我来说似乎很有希望。由于我正在使用哈希,我已经放弃了完全的准确性,所以这可能是一个很好的精度/性能折衷。

【问题讨论】:

  • 你能告诉我们关于数字的分布吗?关于每年的新增内容?
  • 它(应该)是统一的,数字是哈希值。速度稳定,因此每秒大约 3 次添加操作。

标签: data-structures on-disk


【解决方案1】:

将每个整数插入到通过计算n - 整数的位散列。将一个表的一列设为主键,这样尝试插入现有数字就会失败。

假设整数已经足够随机,您可能只需选择最低有效字节作为“哈希”。

编辑:我做了一些测试。我在大约两个小时内插入了 2500 万个条目,但在此过程中它已经吞噬了超过 1 GB。这是通过生成随机数并将它们分配给 32 个子进程来完成的,每个子进程都有一个受其控制的 SQLite 数据库,并且每 100,000 次插入提交一次。目前插入的频率约为 1350 Hz,远远超出了您的问题所需的 3 Hz,但整个数据库仍然适合缓存(我有 8 GB RAM)。除非我接近您当前的数据库大小,否则我不会知道稳态性能。到那时,每次插入都会引起至少四次磁盘磁头移动(读取和写入索引和表,可能更多以深入 B+ 树),然后你就会知道你到底有多痛苦.

我开始认为这是一个真正有趣的问题,可以通过定制解决方案更有效地解决。但是,我怀疑要显着超越数据库引擎需要付出合理的努力。

【讨论】:

  • 这听起来与我已经在做的非常相似(n=4)。有什么理由比 MySQL 更喜欢 SQLite?我怀疑这些数字将被存储两次——一次用于索引,一次用于“数据”。知道这是不是真的吗?
  • 接受这个作为“没有答案”。有时感觉就像 B+ 树就是 CS 必须提供的一切......
  • 我喜欢 SQLite,而不是客户端-服务器设置,因为它不需要服务器并且维护开销为零。此外,我几乎总是使用 SQLite 数据库来代替简单文件。对于相同的编码工作量,它们更可靠,通常更快(取决于问题),并且更灵活。我不知道 SQLite 是否为索引存储了两次数据;我猜是这样,当你DROP INDEX 时,为了保持简单,但即便如此,你每年也只会增加 1 GB。你的硬盘应该可以应付得很好。
  • RE:B+ 树:不,它们并不是它所提供的全部。您可以寻求 Bloom 过滤器、前端编码、分布式哈希表等的帮助。但对于您的特定问题是否值得付出努力是一个问题。大多数情况下,从工程角度来看,“将其保存在数据库中”是最佳答案。
【解决方案2】:

散列你的哈希?

【讨论】:

  • 我不确定我是否理解你的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
  • 2015-10-13
  • 2017-11-11
  • 1970-01-01
  • 2010-09-20
  • 2017-12-02
相关资源
最近更新 更多