大容量XML文件处理如何解决性能问题

HI,ALL
需求:每天有一个非常大的XML文件过来,我需要将它解析入库,现在是单线程,性能不行,每天的文件处理不完,堆了很多
想法:我的想法是能不能把它拆分成多个小XML文件,然后交给多个线程去解析入库肯定比一个线程处理要快,问题是如果拆分?
请banq和各位高手给以建议或者提示一下如何解决这个需求?
[该贴被thinkjava于2009-12-02 14:29修改过]
[该贴被thinkjava于2009-12-02 14:30修改过]

因为XML是有固定格式,这个非常大XML格式应该是你们双方都能知道其Schema的,如果是这样,你就用一个线程接受,一个线程分割,然后交给多个线程并发进一步解析,提取数据,再入库。

你这个需求没有最终一致性要求,所以分割异步还是很方便的。

1、XML文件有多大?你如何读取XML文件的??不要使用DOM,用SAX。
2、怎样导入db的??每条insert??要批量导入。
3、现在的主流db都支持从XML文件中直接导入DB,不知道你是否考虑使用该功能。

多谢二位回复
1.XML文件有40G,如果把入库逻辑改为打印到控制台,性能如下:
1.1 StAX解析XML:1138.818秒/1.51G 40G/8小时
1.2 SAX解析XML:第一次:903.196秒/1.51G 40G/5小时
第二次:781.695秒/1.51G
第三次:792.517秒/1.51G
1.3 自己边拆分,边解析,拆分自己开发,解析使用DOM4J:1128.619/1.51G 40G/8小时,是目前采用的方案
1.4 拆分自己开发,把解析打印交给多线程处理:1493.736秒/1.51G
这个就是banq说的一个线程分割,多线程解析入库思路
2.现网上是500条入库,边拆分边解析入库,本地测试只打印到控制台
3.要使用quartz每天定时触发处理XML文件,一天一个XML,超大,不单单是入库,入库只是为了保留源始数据,
我们还要拿这些数据去更新一些状态,不过更新这块是通过MDB做的,所以更新状态就不用考虑性能问题了,
只是从解析-》入库(测试只打印到控制台) 这段逻辑性能不够 你的意思是
手动导入DB吧


所以说我考虑现在的程序有可能是拆分性能不高,想问一下如何拆分性能高,或者说换一种思路解决此性能问题

[该贴被xysniper于2009-12-03 13:32修改过]

那就是要分布式计算,一组计算机替代原来一个线程,这样性能会更快。

看看Map/reduce算法是否符合你要求,是一种切分计算的算法。
[该贴被banq于2009-12-03 13:44修改过]

To banq
如果公司允许,肯定采用,但问题是这么一个小小需求,要用一组计算机来分布式计算,成本上太大,架构上太复杂,以后要是还有类似的需求,那是不是还要搞这么复杂的架构呢?

首先确定系统的瓶颈在什么地方,是读取慢还是导入慢。
sax读取用5个小时应该还可以,可能还是导入慢,可以考虑多线程批量导入
不要使用DOM!!!DOM如果那一天你的数据暴增,会把你的机器搞死的。

也想说两句, 首先是找到性能最底下的地方在哪里然后才能对症下药。 举个例子如果是DB插入或者更新慢, 那么在XML上面浪费时间是不值得的, 或者说不能药到病除。 如果是XML读取或者说解析慢那么banq的方法应该是一个很好的方案。

楼主把各个阶段的性能数据都贴上来, 自己应该就能找到一个合理的解决办法了。 有问题不可怕, 可怕的是不知道问题是什么。


顺便问一下,你们公司怎么会有这种设计? 每天来一个40G的XML? 个人感觉良好的设计应该避免使用单一的过大的文件交换数据。数据上的设计也是很重要的设计, 将来如果业务增长十倍,是不是会更加麻烦?
[该贴被chabulier于2009-12-04 02:31修改过]

2009年12月03日 14:36 "xysniper"的内容
To banq
如果公司允许,肯定采用,但问题是这么一个小小需求,要用一组计算机来分布式计算,成本上太大,架构上太复杂,以后要是还有类似的需求,那是不是还要搞这么复杂的架构呢?

呵呵,不用一组计算机,其实你用两台双核便宜的PC机就可以了,我的意思表示这个方案的可伸缩性。你把会形成性能瓶颈的地方都分开执行,这样,不至于塞车,也是一种异步设计吧,不应该算复杂,实际生活中例子很多。

嗯,banq的意思我明白,但是一个公司不太可能把这么一个需求拿两台机器做分布,第一:公司需要增加廉价的PC,财务上行不通,第二:分布式架构解决这么一个小需求,leader通不过,因为公司需求很多,不可能个个都要分布,都要增加PC,项目上现网后,硬件机器数量都是固定的,所以不会因为增加新的需求,加PC或增加新的架构,会给项目维护增加难度,给项目部署增加难度,这个需求,我采用了多个线程处理,后来发现性能还不如单线程,请见贴子:http://www.jdon.com/jivejdon/thread/37797
希望大家讨论寻求解决方案

[该贴被xysniper于2009-12-07 22:24修改过]

能不能叫那边把xml分开了再给你传过来.这样比你自己去切快点,沟通下.或者改成传对象流试试.

呵呵,人家是大客户,不会理我们的,他们有他们的业务需求和实现方式,我们只能尽量解决,XML文件有可能是人家用shell搞出来的,直接FTP给我们了,不可能再用java传个对象过来

你用的是xerces么,里边有个properties
http://apache.org/xml/properties/input-buffer-size,设置过么
如果不行,只能自己写parser,因为sax是个通用解决方案