1

我有以下格式的大型数据集:

总共有 3687 个目标文件。每个包含 2,000,000 条记录。每个文件大小为 42MB。

每条记录包含以下内容:

  • 一个 id(整数值)
  • 值 1(整数)
  • 值 2(整数)
  • 值 3(整数)

每个文件的内容不会以任何方式排序或排序,因为它们是在数据收集过程中观察到的。

理想情况下,我想为这些数据建立一个索引。(由 id 索引)这将意味着以下内容:

  1. 将一组 id 划分为可管理的块。

  2. 扫描文件以获取与当前工作组 id 相关的数据。

  3. 建立索引。

  4. 遍历下一个块并重复 1,2,3。

对我来说,这听起来不错,但来回加载 152GB 非常耗时,并且想知道最好的方法,甚至 Java 是否真的是用于此类过程的正确语言。

我的机器上有 256GB 的内存和 32 个内核。


更新: 让我修改一下,把 I/O 放在一边,假设文件在内存中的字节数组中。

解码具有 2,000,000 条记录且每条记录包含 4 个序列化的整数的 42MB 对象文件的最快方法是什么。

4

4 回答 4

2

您对文件格式的选择非常糟糕。我会将很多从序列化整数转换为使用 DataOutputStream.writeInt() 编写的二进制整数,并使用 DataInputStream.readInt() 读取它们。在这两种情况下都有缓冲流。您将节省大量磁盘空间,从而也节省了 I/O 时间,并且还节省了所有序列化开销时间。并在将来更改您的收藏软件以使用此格式。转换需要一段时间,但它只发生一次。

或者按照建议使用数据库,再次使用本机整数而不是序列化对象。

于 2013-01-29T01:09:20.757 回答
1

嗯..似乎更好的方法是使用某种 DBMS。将所有数据加载到数据库中,您可以利用其索引、存储和查询功能。当然,这取决于您的要求——以及现在的 DBMS 解决方案是否适合这个

于 2013-01-29T00:46:11.797 回答
1

所以,我要做的只是加载每个文件并将 id 存储到某种排序结构中 - std::map 可能 [或 Java 的等价物,但考虑到读取文件名可能需要大约 10-20 行代码然后将文件的内容读入地图,关闭文件并请求下一个文件,我可能只是编写 C++ 来做到这一点]。

我真的不知道你还能/应该做什么,除非你真的想把它加载到一个 dbms 中——我不认为这是一个不合理的建议。

于 2013-01-29T01:05:59.227 回答
0

鉴于您的可用内存大于数据集,并且您想要非常高的性能,您是否考虑过 Redis?它非常适合对简单数据结构的操作,并且性能非常快。

在存储值时,请注意让 java 进行默认序列化。我以前遇到过我的原语在序列化之前自动装箱的问题。

于 2013-01-29T00:59:30.130 回答