有多少选项可以快速,多次处理大型文件?
我有一个文件(最小1.5 GB,但可以超过10-15 GB),需要多次读取 - 大约数百到数千次。服务器有大量的RAM(64+ GB)和大量的处理器(24 +)。
该文件将是顺序的,只读的。文件在磁盘上加密(敏感数据)。我还使用MessagePack在读取过程中将它们反序列化为对象。
我无法将从文件创建的对象存储到内存中 - 太大的扩展(1.5 GB文件变成35 GB的内存中对象数组)。文件不能存储为字节数组(受Java的数组长度2 ^ 32-1限制)。
我最初的想法是使用内存映射文件,但它有自己的一组限制。
这个想法是将文件从磁盘上移到内存中进行处理。
大量数据用于机器学习算法,需要多次读取。在计算每个文件传递期间,算法本身有相当多的堆使用量,这是不可避免的,因此需要多次读取它。
答案 0 :(得分:4)
你遇到的问题是你不能mmap()
同名系统调用的方式;系统调用最多可映射2 ^ 64,FileChannel#map()
无法可靠地映射超过2 ^ 30。
但是,您可以做的是将FileChannel
包装到一个类中并创建几个"映射范围"覆盖所有文件。
我已经完成了#34;几乎"这样的事情除了更复杂:largetext。更复杂,因为我必须执行解码过程才能启动,并且加载的文本必须是内存,不像你读取字节。不那么复杂,因为我有一个定义JDK接口来实现,你不会。
然而,您可以使用几乎相同的技术使用Guava和RangeMap<Long, MappedByteBuffer>
。
我在上面的这个项目中实现了CharSequence
;我建议你实现一个LargeByteMapping
界面,你可以从中读取你想要的任何部分;或者,嗯,适合你的任何事情。您的主要问题是定义该接口。我怀疑CharSequence
做的不是你想要的。
largetext
是一个令人兴奋的项目,看起来像是同样的事情;除了不那么复杂,最终!
人们甚至可以想象一个LargeByteMapping
实现,其中工厂将创建这样的映射,其中只有一小部分映射到内存中,其余部分写入文件;并且这样的实现也将使用局部性原则:文件中最新查询的部分将被保存到内存中以便更快地访问。
另见here。
编辑我觉得这里需要更多解释...... MappedByteBuffer
不会吃太空!!
它只会吃地址空间;它几乎相当于ByteBuffer.allocateDirect()
,除了它由文件支持。
这里需要做出非常重要的区分;上面的所有文字都假设您正在阅读字节,而不是字符!
答案 1 :(得分:0)
弄清楚如何构建数据。获取一本关于NoSQL的好书,并为您的场景找到合适的数据库(宽列,图形等)。这就是我要做的。您不仅可以对数据使用复杂的查询方法,还可以使用分布式地图缩减实现来执行您想要的任何操作。也许这就是你想要的(你甚至放弃了 bigdata 炸弹)
答案 2 :(得分:0)
如何创建“字典”作为程序和目标文件之间的桥梁?你的程序会调用字典然后字典会引用你的大文件。