使用哈希来管理大型远程csv

时间:2014-07-24 14:28:30

标签: java hashmap

我们正在尝试索引3gb csv的内容(不在运行应用程序的框中)。我们能够使用BufferedReader读取文件,但是当我们尝试有效读取时,我们遇到了问题。有人建议我们用行的内容哈希一个id字段。

这似乎是一个好主意,但我无法弄清楚我们如何“缓冲写入”我们的哈希映射到文件。看起来像对象编写器只需要一个巨大的“转储”对象......

任何人都知道我们可以不断将条目放入相同的外部哈希映射,然后从这些内容中读取?

谢谢!

3 个答案:

答案 0 :(得分:2)

考虑使用数据库, 那么您将不需要将索引保留在内存中(假设您没有使用内存数据库)。

用于本地数据库(在您的情况下)

  1. 让数据库维护索引。
  2. 您可以将更改缓存到外部哈希映射,并且更新频率低于“始终”。这假设您不需要使外部哈希映射始终保持最新。
  3. 如果没有关于你的情况的任何细节,当你可以使用数据库并且不必为解决方案自己滚动时,将东西存储在巨型哈希映射中似乎是一个可怕的想法。

答案 1 :(得分:1)

我认为你想要的POC是这样的:

Map<Integer, String> cache;

void readCache(BufferedReader br) {
    cache = new HashMap<Integer, String>();
    int line = 1;
    for (;;) {
        String l = br.readLine();
        if (l == null) break;
        cache.put(line, l);
        line++;
    }
}

String getLine(int line) { return cache.get(line); }

请注意,这将比3GB的JVM内存占用更多​​,因此-Xmx5G是值得推荐的:)

如果可能,将CSV导入数据库并使用SQL读取特定行可能更有效;这样可以提高性能,而无需在您的盒子上缓存,并且只需要为此单个进程提供> 3GB RAM。

答案 2 :(得分:0)

解决方案是使用(轻量级)数据库。查看this SO问题以获取轻量级数据库和基于磁盘的哈希映射列表:MapDBjdbm2JavaDBBerkeleyDB是推荐内容。这将为您解决大部分问题,之后您可以轻松索引或查询数据。

那说:如果你真的只想使用一个hashmap,你也可以试试partitioning。您可以创建多个哈希映射并按ID进行分区(水平分区),也可以为每个ID创建多个哈希映射(垂直分区)。这应该允许您解决内存问题,尽管您可能需要多次读取CSV文件。