【问题标题】:spring batch: process large filespring batch:处理大文件
【发布时间】:2016-06-29 17:29:09
【问题描述】:

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

如果我们取 10 个文件,我们将有 3300 万行。我们正在使用spring批处理(MultiResourceItemReader)来读取搜索行并写入将其写入数据库并将其发送到JMS。全部完成大约需要 25 小时。

尽管我们有 10 个系统在生产中,但目前我们只使用一个系统来运行这个工作(我是 spring batch 的新手,不知道 spring 如何支持负载平衡)

由于我们只有一个系统,我们将数据源配置为连接到 db,并将最大连接数指定为 25。

为了提高性能,我们想到了使用 spring 多线程支持。开始使用 5 个线程。我们可以看到性能的提升,并且可以看到一切都在 10 小时内完成。

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

【问题讨论】:

    标签: jms datasource spring-batch


    【解决方案1】:

    不同的 JMS 提供者会有不同的限制,但总的来说,消息传递可以在短时间内轻松处理数百万行。

    消息传递将比直接插入数据库更快,因为消息需要管理的数据非常少(JMS 属性除外),而不是完整的 RDBMS 或 NoSQL 数据库或其他任何东西的开销,消息传递执行所有这些。

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

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

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

    更好的解决方案可能是将文件转换为单个文件,该文件可以使用特定于平台的工具批量加载到数据库中。这些工具通常会禁用索引、约束检查和其他任何会减慢速度的东西(通常会绕过 SQL 本身)以提高性能。

    【讨论】:

      猜你喜欢
      • 2018-05-22
      • 2018-01-21
      • 2012-05-23
      • 1970-01-01
      • 2020-04-27
      • 2012-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多