【问题标题】:Horizontal scaling with Spring Batch使用 Spring Batch 进行水平缩放
【发布时间】:2021-03-12 23:57:00
【问题描述】:

我有一个应用程序,它利用 Spring Batch 从公共数据库中读取和处理记录。该作业在固定时间从调度程序触发,并在单个应用程序实例上正常工作。我想水平扩展这个应用程序以提高处理时间,同时使用相同的数据库。 Spring Batch(信号量)中是否有任何东西可以管理多个实例正在访问的数据,从而防止它们访问和修改相同的记录?

我已经进行了搜索,并且只设法在同一个应用实例中找到了多线程。

非常感谢

【问题讨论】:

  • 我也在寻找这个问题的具体答案。到目前为止提供的答案没有用。

标签: spring spring-boot parallel-processing spring-batch scalability


【解决方案1】:

你可以在架构层面解决它,

通过使用负载均衡器,您可以将请求分成多个块,它会通过将这些请求发送到不同的节点/实例来并行处理。

例如:Mysql 有 1m 条记录,你可以从 0-100k .. 900k-1m 的块中获取数据,通过 Ribbon 或其他负载均衡器将数据发送到处理器微服务。

每次它都会自动将它按顺序发送到不同的节点。

祝你好运

【讨论】:

    【解决方案2】:

    Spring Batch(信号量)中是否有任何东西来管理多个实例正在访问的数据,从而防止它们访问和修改相同的记录?

    不,不是跨实例。您可以确保每个实例都适用于不同的数据集。

    我已经进行了搜索,并且只设法在同一个应用实例中找到了多线程。

    除了多线程步骤之外,Spring Batch 还提供了partitioned steps,其中每个工作人员都被分配了一个不同的分区。 Worker 可以是本地线程或远程 JVM。您可以根据需要创建任意数量的远程工作人员,因此这种方法可以让您横向扩展您的工作。

    【讨论】:

      【解决方案3】:

      您可以使用单独的数据库表(所有实例均可访问)来保存每个页面中处理的最后一个唯一排序键(假设您使用的是 PagingReader)。 然后从 db 表中读取最高键,并在您的 SQL 查询中使用它(例如,WHERE value > key)进行页面读取,这样当任何实例中的下一页运行 SQL 查询时,它都会获取记录键值大于其他页面中处理的键值。

      【讨论】:

        【解决方案4】:

        Spring Batch(信号量)中是否有任何东西来管理数据 被多个实例访问,以防止它们访问 并修改相同的记录?

        不,不是跨实例。由您来确保每个实例 适用于不同的数据集。

        关于这一点,我已经通过使用分布式锁(使用 dynamodb 锁客户端)完成了跨实例分布数据集的 POC。

        我在这里使用的方法是启动应用程序的多个实例,这些实例将争夺数据集锁(或春季批处理世界中的作业),它必须在启动时运行。通过足够的监控,您可以确保将所有数据集分配给某个实例。

        更多细节在我的仓库:https://github.com/vinodhinic/scale-spring-batch

        【讨论】:

          【解决方案5】:

          这可以通过http://www.quartz-scheduler.org/ 完成 一个常见的组合是使用 Quartz 作为使用 Cron 表达式的 Spring Batch 作业的触发器。它将允许您同时仅在 1 个实例上运行 Spring Batch 作业。看看https://www.baeldung.com/spring-quartz-schedule的例子

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-20
            • 2016-04-22
            • 1970-01-01
            • 2012-01-30
            • 2020-01-18
            • 1970-01-01
            相关资源
            最近更新 更多