有关处理大数据量的建议

时间:2020-03-05 19:00:03  来源:igfitidea点击:

因此,我有大量的"非常大"的数字数据ASCII文件(共计千兆字节),并且我的程序需要至少顺序地依次处理整个文件。

关于存储/加载数据有什么建议吗?我曾考虑过将文件转换为二进制文件,以使其更小并更快地加载。

我是否应该一次将所有内容都加载到内存中?
如果不是,那么打开部分加载数据的好方法是什么?
与Java有关的效率技巧有哪些?

解决方案

回答

我们确实没有给我们足够的信息来。我们是否需要完整地加载每个文件才能进行处理?还是可以逐行处理?

一次加载整个文件可能会导致性能下降,即使文件不是很大也是如此。最好的选择是定义一个适合缓冲区大小,并一次读取/处理一个缓冲区中的数据。

回答

我发现Informatica是一个非常有用的数据处理工具。好消息是,最新版本甚至允许Java转换。如果我们要处理的数据量为TB,则可能是时候尝试使用最好的ETL工具了。

我假设我们想对此处的处理结果进行某些处理,例如将其存储在某个地方。

回答

如果我们定期对数字数据进行采样并且需要进行随机访问,请考虑将其存储在四叉树中。

回答

我们可以转换为二进制文件,但是如果需要保留原始数据,则可以拥有1+份数据副本。

在原始ascii数据之上建立某种索引可能是很实际的,因此,如果我们需要再次浏览数据,则可以在以后的时间中更快地进行处理。

要按顺序回答问题:

Should I load everything into memory all at once?

不必,不必。对于某些文件,我们也许可以,但是,如果我们只是按顺序处理,则可以逐个进行某种缓冲读取,并在存储过程中存储我们需要的所有内容。

If not, is opening what's a good way of loading the data partially?

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

What are some Java-relevant efficiency tips?

这实际上取决于我们对数据本身的处理方式!

回答

如果没有任何其他关于正在进行的处理的见解,这是我做类似工作时的一些一般想法。

  • 编写一个应用程序原型(甚至可以"扔掉"),以对数据集执行任意操作。看看速度有多快。如果我们能想到的最简单,最幼稚的事情是可以接受的快速,那就不用担心!
  • 如果天真的方法不起作用,请考虑对数据进行预处理,以使后续运行将在可接受的时间长度内运行。我们提到必须在数据集中"跳来跳去"很多。有什么办法可以对它进行预处理?或者,一个预处理步骤可以是生成更多数据-索引数据-提供有关数据集关键,必要部分的字节准确的位置信息。然后,主要处理运行可以利用此信息直接跳转到必要的数据。

因此,总而言之,我的方法是立即尝试一些简单的操作,看看性能如何。也许会没事的。否则,请考虑分多个步骤处理数据,从而节省了最昂贵的操作,以减少不频繁的预处理。

不要"将所有内容加载到内存中"。只需执行文件访问,然后让操作系统的磁盘页面缓存决定何时实际将内容直接从内存中拉出即可。

回答

我建议强烈利用正则表达式并研究"新的" IO nio包,以加快输入速度。然后,它应尽可能快地达到我们期望的千兆字节数据流。

回答

我们可能想看看Wide Finder项目中的条目(用Google搜索" wide finder" java)。

Wide finder涉及读取日志文件中的许多行,因此请查看Java实现,并查看在那里有效和不起作用的地方。

回答

So then what if the processing requires jumping around in the data for multiple files and multiple buffers? Is constant opening and closing of binary files going to become expensive?

我是"内存映射的I / O"(也称为"直接字节缓冲区")的忠实拥护者。在Java中,它们称为映射字节缓冲区,它们是java.nio的一部分。 (基本上,此机制使用操作系统的虚拟内存分页系统来"映射"文件,并以编程方式将它们显示为字节缓冲区。操作系统将自动快速地神奇地自动将字节移入磁盘和内存。

我建议采用这种方法,因为a)对我有用,b)让我们专注于算法,并让JVM,OS和硬件进行性能优化。所有人都经常比我们卑鄙的程序员更了解什么是最好的。 ;)

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

顺便说一句:我们正在处理多少数据(以GB为单位)?如果它大于3-4GB,则在32位计算机上将无法使用,因为MBB实现是平台体系结构可寻址内存空间的被保护者。 64位计算机和操作系统会将我们带到1TB或者128TB的可映射数据。

如果我们在考虑性能,那么可以去了解Kirk Pepperdine(一个有点出名的Java性能专家)。他参与了一个网站www.JavaPerformanceTuning.com,该网站包含更多MBB详细信息:NIO Performance Tips和其他与Java性能相关的东西。

回答

如果可能的话,将数据放入数据库中。然后,我们可以利用那里的所有索引,缓存,内存固定以及其他可用功能。

回答

这在很大程度上取决于文件中的数据。大型主机已经进行了很长时间的顺序数据处理,但是通常不对数据使用随机访问。他们只是一次将它拉成一条线,然后进行那么多的处理,然后再继续。

对于随机访问,通常最好使用缓存包装器来构建对象,该包装器知道它们需要构造的数据在文件中的位置。当需要时,他们读入这些数据并构造自己。这样,当内存紧张时,我们就可以开始删除内容,而不必担心以后无法将其取回。

回答

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