Java 在30GB XML数据集上搜索正则表达式模式。利用16gb内存

Java 在30GB XML数据集上搜索正则表达式模式。利用16gb内存,java,xml,Java,Xml,我目前有一个JavaSAX解析器,它从一个30GB的XML文件中提取一些信息 目前是: 读取每个XML节点 将其存储到字符串对象中 在字符串上运行一些正则表达式 将结果存储到数据库中 为了几百万个元素。我在一台有16GB内存的计算机上运行这个程序,但是内存没有被充分利用 有没有一种简单的方法可以从输入文件中动态“缓冲”大约10gb的数据 我怀疑我可以手动使用“生产者”“消费者”多线程版本(一边加载对象,一边使用对象,另一边丢弃对象),但该死的是,XML现在已经过时了,没有有效的库来处理它们吗

我目前有一个JavaSAX解析器,它从一个30GB的XML文件中提取一些信息

目前是:

  • 读取每个XML节点
  • 将其存储到字符串对象中
  • 在字符串上运行一些正则表达式
  • 将结果存储到数据库中
为了几百万个元素。我在一台有16GB内存的计算机上运行这个程序,但是内存没有被充分利用

有没有一种简单的方法可以从输入文件中动态“缓冲”大约10gb的数据


我怀疑我可以手动使用“生产者”“消费者”多线程版本(一边加载对象,一边使用对象,另一边丢弃对象),但该死的是,XML现在已经过时了,没有有效的库来处理它们吗?

没有Java经验,抱歉,但也许你应该更改解析器?SAX应该按顺序工作,并且不需要缓冲大部分文件…

我真的不明白您想用这么多XML做什么,但我得到的印象是

  • 对存储的数据使用XML是错误的
  • 您的缓冲远远超出了您应该做的(这样做将放弃SAX解析的所有优势)

除此之外,XML并不是古老的,并没有被大量和积极地使用。你认为所有这些互动网站都在使用什么作为互动元素

我建议首先将您的海量XML文件导入到本地XML数据库中(例如,如果您正在寻找开源的东西,我从来没有测试过),然后执行迭代分页查询,一次处理一小块数据。

SAX本质上是“事件驱动的”,因此,您应该在元素之间保持的唯一状态是与该元素相关的状态,而不是整个文档。你还保持什么样的状态,为什么?当每个“完整”节点(或一组节点)出现时,您应该丢弃它们。

您是否因为对数据库的多个小提交而减慢了速度?听起来您几乎一直在从程序中向db写入数据,确保不经常提交数据可以提高性能。可能还需要准备语句和其他标准批量处理技巧


除了这个早期的评论,我们需要更多的信息-您是否手头有一个分析器,可以找出使事情运行缓慢的原因

您可能想尝试代替SAX,我听说它更适合这种类型的事情(我自己没有使用过)。

首先,尝试找出是什么让您慢下来

  • 从内存解析时,解析器的速度要快多少
  • 使用大尺寸的
    BufferedInputStream
    是否有帮助

拆分XML文件容易吗?一般来说,在任何类型的30 GiB数据中进行随机扫描都需要一些时间,因为您必须首先从硬盘加载数据,因此您总是受到这种速度的限制。您可以将负载分配到多台机器上吗?也许可以使用类似的方法?

您可以使用Jibx库,并将XML“节点”绑定到表示它们的对象上。您甚至可以重载ArrayList,然后在添加x个对象时,一次执行所有正则表达式(可能使用对象上执行此逻辑的方法),然后将它们保存到数据库中,然后再允许“add”方法再次完成

Jibx托管在SourceForge上:

详细说明:您可以将XML绑定为这些专用字符串持有者的“集合”。因为您将其定义为集合,所以必须选择要使用的集合类型。然后可以指定自己的ArrayList实现

按如下方式重写add方法(忘记返回类型,例如假定为void):

要在arraylist中存储多少对象,直到将其刷新到数据库。flushObjects();只是执行此逻辑的方法。该方法将阻止从XML文件添加对象,直到该过程完成。不过,这没关系,无论如何,数据库的开销可能比文件读取和解析要大得多

  • 仅就基本情况而言,Java能够使用您的16GB吗?您(显然)需要在64位操作系统上运行,并且需要使用-d64-XMx10g(或者您希望分配给它的内存量)运行Java

  • 记忆不太可能是你所做事情的一个限制因素,所以你真的不应该看到它被充分利用。您应该是IO或CPU绑定的。很可能是IO。如果是,IO,请确保您正在缓冲您的流,然后您就差不多完成了;你唯一能做的就是买一个更快的硬盘

  • 如果您确实受到CPU的限制,那么很可能您在正则表达式方面遇到了瓶颈,而不是XML解析

    请参阅(哪些参考资料)

  • 如果瓶颈在SAX,可以尝试其他实现。在我的脑海中,我可以想到以下备选方案:

    • StAX(有多种实现;是最快的实现之一)
    • 使用自己的
    • 使用您自己的特别设置,例如使用正则表达式
    对于最后两种情况,XML子集的约束越强,生成它的效率就越高

  • 很难说,但正如其他人提到的,XML本机数据库可能是一个很好的选择。我在这些方面的经验有限,但我知道至少支持基于XPath的索引


  • 如果XML中的数据是顺序独立的,您可以多线程处理该进程以拆分文件,还是从文件中的不同位置开始运行多个进程?如果不受I/O限制,这将有助于加快速度。

    我会用Perl来完成。就我的0.02美元。你能澄清一下“动态缓冲区”是什么意思吗?应该缓冲什么?我
    public void add(Object o) {
        super.add(o);
        if(size() > YOUR_DEFINED_THRESHOLD) {
            flushObjects();
        }
    }
    
    YOUR_DEFINED_THRESHOLD