处理大量数据的建议

时间:2008-09-17 21:08:12

标签: java loading large-files large-data-volumes

所以我有一个“大”数字的“非常大”的数字数据(千兆字节)的ASCII文件,我的程序需要至少按顺序处理整个数据。

有关存储/加载数据的建议吗?我曾想过将文件转换为二进制文件以使它们变小并加快加载速度。

我应该一次性将所有内容加载到内存中吗? 如果没有,那么打开什么是部分加载数据的好方法? 什么是与Java相关的效率提示?

11 个答案:

答案 0 :(得分:6)

  

那么如果处理需要在多个文件和多个缓冲区的数据中跳转呢?二进制文件的不断打开和关闭会变得昂贵吗?

我是'内存映射i / o'的忠实粉丝,又名'直接字节缓冲区'。在Java中,它们被称为 Mapped Byte Buffers 是java.nio的一部分。 (基本上,这种机制使用操作系统的虚拟内存分页系统来“映射”你的文件,并以编程方式将它们作为字节缓冲区提供。操作系统将自动神奇且非常快速地管理磁盘和内存中的字节。

我建议这种方法,因为a)它对我有用,而b)它会让你专注于你的算法,让JVM,OS和硬件处理性能优化。他们经常知道什么是最好的,比我们低级程序员更好。 ;)

您将如何在您的上下文中使用MBB?只需为每个文件创建一个MBB,然后根据需要阅读它们。您只需要存储结果。

顺便说一句:你用多少数据来处理GB?如果它超过3-4GB,那么在32位计算机上这将不适合您,因为MBB实现是平台架构在可寻址内存空间上的被告。 64位机器&操作系统将带您到1TB或128TB的可映射数据。

如果您正在考虑性能,那么请了解Kirk Pepperdine(一位有点着名的Java性能大师。)他参与了一个网站www.JavaPerformanceTuning.com,它有更多的MBB细节: {{3} 和其他Java性能相关的东西。

答案 1 :(得分:2)

您可能需要查看Wide Finder Project中的条目(点击Google搜索"wide finder" java)。

Wide Finder涉及读取日志文件中的许多行,因此请查看Java实现,看看哪些有效,哪些无效。

答案 2 :(得分:1)

您可以转换为二进制文件,但如果您需要保留原文,则可以使用1+以上的数据副本。

在原始ascii数据之上构建某种索引可能是切实可行的,因此如果您需要再次浏览数据,可以在以后的时间内更快地完成。

按顺序回答您的问题:

  

我应该一次性将所有内容加载到内存中吗?

如果没有,则不是。对于某些文件,您可能会,但如果您只是按顺序处理,只需逐个进行某种缓冲读取,并在此过程中存储您需要的任何内容。

  

如果没有,是否打开了部分加载数据的好方法?

BufferedReaders / etc是最简单的,尽管您可以更深入地了解FileChannel / etc以使用内存映射I / O一次浏览数据窗口。

  

与Java相关的效率提示有哪些?

这真的取决于你对数据本身做了什么!

答案 3 :(得分:1)

如果没有进一步了解正在进行什么样的处理,这里有一些关于我做类似工作时的一般性想法。

  1. 编写应用程序的原型(甚至可能是“扔掉一个”),对数据集执行一些任意操作。看看它有多快。如果您能想到的最简单,最天真的事情是可以接受的快速,不用担心!

  2. 如果天真的方法不起作用,请考虑预处理数据,以便后续运行将在可接受的时间内运行。你提到必须在数据集中“跳转”很多。有没有办法预处理出来?或者,一个预处理步骤可以生成更多数据 - 索引数据 - 提供有关数据集的关键,必要部分的字节精确位置信息。然后,您的主要处理运行可以利用此信息直接跳转到必要的数据。

  3. 因此,总而言之,我的方法是立即尝试一些简单的事情,看看性能如何。也许会没事的。否则,请考虑分多步处理数据,为不经常的预处理节省最昂贵的操作。

    不要“将所有内容加载到内存中”。只需执行文件访问,让操作系统的磁盘页面缓存决定何时直接从内存中取出内容。

答案 4 :(得分:1)

这很大程度上取决于文件中的数据。大型大型机长期以来一直在进行顺序数据处理,但它们通常不会对数据使用随机访问。他们只是一次拉一行,然后继续处理。

对于随机访问,通常最好使用缓存包装器构建对象,这些包装器知道文件在何处需要构建的数据。需要时,他们会读取数据并自行构建。这样,当记忆力很紧的时候,你可以开始杀掉一些东西,而不必过于担心以后不能把它拿回来。

答案 5 :(得分:0)

你真的没有给我们足够的信息来帮助你。您是否需要完整地加载每个文件才能进行处理?或者你可以逐行处理吗?

一次加载整个文件可能会导致性能不佳,即使对于非常大的文件也是如此。最好的办法是定义一个适合您的缓冲区大小,一次读取/处理缓冲区数据。

答案 6 :(得分:0)

我发现Informatica是一个非常有用的数据处理工具。好消息是更新的版本甚至允许Java转换。如果您正在处理数TB的数据,那么可能需要时间来寻找最佳的ETL工具。

我假设你想对这里的处理结果做点什么,比如把它存放在某个地方。

答案 7 :(得分:0)

如果您的数字数据是定期采样的,并且您需要进行随机访问,请考虑将它们存储在quadtree中。

答案 8 :(得分:0)

我建议强烈利用正则表达式并查看“新”IO nio包以获得更快的输入。然后它应该尽可能快地实现期望千兆字节的数据。

答案 9 :(得分:0)

如果可能的话,将数据存入数据库。然后,您可以利用所有可用的索引,缓存,内存固定和其他功能。

答案 10 :(得分:0)

如果您需要多次访问数据,请将其加载到数据库中。大多数数据库都有某种批量加载实用程序。如果数据都可以放在内存中,并且您不需要经常保留它或者访问它,那么您可以用Perl或您喜欢的脚本语言编写简单的东西。