【问题标题】:Data too big for int indexing数据太大,无法进行 int 索引
【发布时间】:2014-07-17 18:11:51
【问题描述】:

假设我正在研究大数据(如生物信息学),并且我选择使用 HPC 上出色的 Collections Map-Reduce 框架在 Java 中对其进行分析。如何处理超过2 31 ^ 1 - 个项目的数据集?例如,

final List<Gene> genome = getHugeData();
profit.log(genome.parallelStream().collect(magic);

【问题讨论】:

  • 当然不是List,可能是List&lt;List&gt;?您是如何读取数据的?
  • 您需要一个分布式解决方案。没有人会立即将庞大的数据集加载到内存中进行分析,只是内存不足(更不用说所需的计算能力了)。
  • @Kayaman 这不是真的。有针对分析具有数百 GB RAM 的内存单机中的大量数据的方案。是的,2^31 - 1 对于该内存量是非常可行的限制(假设单个记录大小为几个字节长)。
  • 超过 2^31 个项目会消耗大量 RAM。部分加载。假设一个项目只是一个整数,它是每个项目 24 个字节(8 个用于引用,12 个字节用于对象头,4 个字节用于 int 值)。 2^31 个这样的整数项将占用 48 GB 的 RAM。
  • 记住问题的关键部分...... OP 想要对他的数据使用 Collections Map-Reduce(这就是为什么我没有投票关闭作为我上面链接的问题的副本)。这可能会使某些建议不太可行。

标签: java data-structures


【解决方案1】:

包装您的数据,使其包含许多块——一旦超过 2 ^ 31 - 1,您将进入下一个。草图是:

class Wrapper {
  private List<List<Gene>> chunks;
  Gene get(long id) {
    int chunkId = id / Integer.MAX_VALUE;
    int itemId = id % Integer.MAX_VALUE;
    List<Gene> chunk = chunks.get(chunkId);
    return chunk.get(itemId);
  }
}

【讨论】:

    【解决方案2】:

    在这种情况下,您会遇到多个问题。你的数据有多大?

    最简单的解决方案是使用另一种结构,例如 LinkedList(仅当您对串行访问感兴趣时)或可能具有高插入成本的 HashMap。 LinkedList 不允许任何随机访问。如果要访问第 5 个元素,则还必须首先访问所有之前的 4 个元素。

    这是另一个想法: 让我们假设每个基因都有一个 id 号(长)。您可以使用索引结构(例如 B+-tree)并使用该树索引您的数据。索引不必存储在磁盘上,它可以保留在内存中。它也没有太多开销。你可以在网上找到它的许多实现。

    另一种解决方案是创建一个包含其他容器类或基因的容器类。为了实现这一点,两者都应该实现一个名为例如的接口。可容纳。这样,Gene 和 Container 类都是 Containable(s)。一旦容器达到其最大值。大小它可以插入另一个容器等等。您可以通过这种方式创建多个关卡。

    如果您不熟悉 B+-tree,我建议您在网上(例如 Wikipedia)查找 B+-tree。

    【讨论】:

      【解决方案3】:

      包含 2^31 个对象的数组将消耗大约 17 GB 内存...

      您应该将数据存储在数据库中。

      【讨论】:

        猜你喜欢
        • 2011-09-16
        • 2015-03-03
        • 1970-01-01
        • 2020-10-06
        • 1970-01-01
        • 2017-06-04
        • 1970-01-01
        • 1970-01-01
        • 2019-01-13
        相关资源
        最近更新 更多