spring batch:处理大文件

时间:2016-03-14 15:27:02

标签: jms datasource spring-batch

我有10个大文件正在制作中,我们需要从文件中读取每一行并将逗号分隔值转换为某个值对象并将其发送到JMS队列并插入到数据库中的3个不同表中

如果我们拿10个文件,我们将有3300万行。我们使用spring batch(MultiResourceItemReader)来读取earch行并写入以将其写入db并将其发送到JMS。完成所有操作大约需要25小时。

尽管我们有10个系统正在生产中,但目前我们只使用一个系统来运行这个工作(我是初级批处理的新手,并且不知道弹簧如何支持负载平衡)

由于我们只有一个系统,因此我们将数据源配置为连接到db,并将max connection指定为25.

为了提高性能,我们考虑使用spring多线程支持。开始使用5个线程。我们可以看到性能的提高,并且可以在10个小时内完成所有工作。

我在这里有以下问题: 1)如果我使用5个线程进行处理,我们会将大量数据发布到JMS队列中。队列将支持大量数据。注意我们有10个系统在生产中从队列中读取JMS消息。 2)使用线程(5)和1生产系统是好的方法(或)而不是弹簧批量插入数据到db我可以创建一个休息服务和spring批处理调用其余的api将数据插入db并让spring api insert数据进入JmS队列(再次,如果弹簧批处理文件和使用rest将数据插入db,每秒我将读取4或5行并将调用其余的api。注意我们有10个生产系统)。如果使用rest API方法将我的系统支持(其余可以使用负载均衡器处理大量请求,并且JMS可以处理巨大而巨大的消息)或使用线程在Spring批处理app中使用1个生产系统是更好的方法。

1 个答案:

答案 0 :(得分:0)

不同的JMS提供商将有不同的限制,但一般情况下,消息传递可以在很短的时间内轻松处理数百万行。

消息传递比直接插入数据库更快,因为消息只需要很少的数据来管理(除了JMS属性),而不是完整的RDBMS或NoSQL数据库的开销,等等,消息传递执行它们。

假设可以按任何顺序处理各个行,那么将所有数据发送到同一个队列并让n个消费者在后端工作是一个合理的解决方案。

然而,您的大瓶颈是将数据导入数据库。如果目标表上有m /任何键/索引,则会出现严重争用,因为每次插入/更新/删除都需要重建索引,因此即使您有n个不同的消费者试图更新数据库随着交易的完成,他们会互相打击。

我看到的一个解决方案是在开始并在最后启用之前禁用所有数据库约束,并且希望如果事情有效,数据是一致且可用的;当然,风险是您没有捕获到的错误数据,现在您需要清理或重新尝试负载

更好的解决方案可能是将文件转换为单个文件,可以使用特定于平台的工具批量加载到数据库中。这些工具通常会禁用索引,禁止检查以及其他任何会减慢速度的事情 - 通常会绕过SQL本身 - 以获得性能。