Java:处理大数据量的建议(第二部分)

4
好的。我有大量二进制数据(假设为10GB),分布在许多不同长度文件中(假设为5000个)。我正在编写一个Java应用程序来处理这些数据,并希望为数据访问设计一个良好的方案。通常情况下会发生以下情况:
- 在处理过程中,所有数据都将被读取。 - 每个文件(通常)按顺序读取,每次仅需要几千字节。但是,通常需要同时拥有每个文件的前几千字节或其中间的几千字节等。 - 有时,应用程序需要随机访问一两个字节。
目前,我正在使用RandomAccessFile类读入字节缓冲区(和ByteBuffer)。我的最终目标是将数据访问封装到某个类中,使其快速且无需再次担心。基本功能是我将要求它从指定的文件中读取数据帧,并在考虑上述情况的情况下最小化I/O操作。
典型访问示例:
- 给我所有文件的前10KB! - 给我文件F的0到999字节,然后给我1到1000字节,然后给我2到1001字节,以此类推...... - 给我从特定字节开始的文件F中的1MB数据!
有没有关于良好设计的建议?
9个回答

9
使用Java NIO和MappedByteBuffers,并将文件视为字节数组列表。然后,让操作系统自动处理缓存、读取、刷新等细节。

2

@Will

结果相当不错。读取大型二进制文件的快速比较:

  • 测试1 - 使用RandomAccessFile进行基本的顺序读取。 2656毫秒

  • 测试2 - 缓存的基本顺序读取。 47毫秒

  • 测试3 - 使用MappedByteBuffers进行基本顺序读取,并进一步进行帧缓冲优化。 16毫秒


1

哇,你基本上是在从头开始实现一个数据库。有没有可能将数据导入到实际的关系型数据库管理系统中,并只使用SQL?

如果你自己做,最终会想要实现某种缓存机制,这样你需要的数据就可以从RAM中出来,而你正在读写较低层的文件。

当然,这也涉及到许多复杂的事务逻辑,以确保你的数据保持一致。


1

我原本想建议你跟进Eric的数据库想法,学习数据库如何管理缓存——有效地实现自己的虚拟内存管理。

但是当我更深入地思考后,我得出结论:大多数操作系统已经比你在Java中没有低级访问权限时能做到更好地实现文件系统缓存。

不过,有一个来自数据库缓存管理的教训你可以考虑。数据库使用查询计划的理解来优化管理策略。

在关系型数据库中,通常最好从缓存中驱逐最近使用的块。例如,在连接中持有子记录的“年轻”块将不再被查看,而包含其父记录的块仍在使用中,即使它“更老”。

另一方面,操作系统文件缓存被优化为重用最近使用的数据(并预读最近使用的数据之前的数据)。如果你的应用程序不符合这种模式,可能值得自己管理缓存。


1

你可能想要看一下一个名为jdbm的开源、简单的对象数据库——它已经开发了很多这样的东西,包括ACID功能。

我对该项目做出了许多贡献,如果仅仅是为了看看我们如何解决你可能正在处理的许多相同问题,那么审查源代码就值得了。

现在,如果你的数据文件不在你的控制之下(即你正在解析由他人生成的文本文件等),那么jdbm使用的页面结构类型的存储可能不适合你——但如果所有这些文件都是你创建和处理的文件,那么它可能值得一看。


0

@Eric

但是我的查询将比我可以使用SQL做的任何事情都要简单得多。而且,数据库访问难道不比二进制数据读取更昂贵吗?


我认为如果数据适合关系模型(可能不适合),其中一个轻量级的内部数据库会非常适用。我不想打击你的积极性,这听起来像是一个有趣的项目,但如果你想避免大量编码工作,你可能想选择一个已经建立好的代码库。 - Eric Z Beard

0
这是关于最小化I/O流量的答案。在Java方面,你真正能做的就是将读取器包装在BufferedReaders中。除此之外,你的操作系统会处理其他优化,比如将最近读取的数据保留在页面缓存中,并在文件上执行预读以加快顺序读取速度。在Java中进行额外缓冲没有意义(尽管你仍需要一个字节缓冲区来将数据返回给客户端)。

你不能仅靠操作系统来正确地进行预读取。Linux做得相当好,但Windows则无用。为了在Windows下充分发挥硬盘IO带宽的最大值,你需要约1MB的缓冲区。 - Noel Grandin

0

就在前几天,有人向我推荐了Hadoop(http://hadoop.apache.org)。它看起来非常不错,可能会有一些市场上的影响力。


0

我建议您退后一步,问问自己为什么要使用文件作为记录系统,以及相比使用数据库,这给您带来了什么好处。数据库当然可以让您结构化数据。考虑到 SQL 标准,从长远来看,它可能更易于维护。

另一方面,您的文件数据可能不容易在数据库的限制条件下进行结构化。全球最大的搜索公司 :) 并没有将数据库用于其业务处理。请参见 此处此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接