最佳Spring批量扩展策略

时间:2015-03-17 19:04:44

标签: spring parallel-processing spring-batch scalability

我们有简单的批处理工作,工作正常。最近,我们有新的需求来实现新的批处理以生成报告。我们有差异的数据源来阅读以准备此报告。具体来说,我们可能会为每个报告提供一个视图。

现在我们想要以这样的方式扩展这个过程,它可以扩展并尽早完成。

我熟悉多线程步骤但不确定其他策略(远程分块和分区步骤)以及何时使用。

在我们的案例中,处理+写入文件是更多的资源激励,然后阅读。

在这种情况下哪种方法最适合。

或者,如果我们发现db中的读取数据与写入+处理到文件的资源激励相同,那么我们必须改进/扩展此过程的最佳选择。

1 个答案:

答案 0 :(得分:27)

<强> TLDR;

根据您的描述,我认为您可以尝试使用同步阅读器进行多线程步骤,因为您提到处理和写入是您步骤中更昂贵的部分。

然而,看到您的读者是一个数据库,我认为配置分区步骤并且正常工作将非常有益。设置需要更多的工作,但从长远来看会更好地扩展。

Multi-threaded Step

用于:

  • 加快个人步伐
  • 当读取器(即JMS或AMQP)可以处理负载平衡时
  • 使用自定义阅读器时,手动分区正在阅读的数据

不要用于:

  • 有状态项目读者

多线程步骤使用Spring Batch使用的chunk-oriented processing。当您对一个步骤进行多线程处理时,它允许spring批处理在其自己的线程中执行整个。请注意,这意味着您的数据块的整个读取 - 写入 - 写入周期将并行发生。这意味着没有保证处理您的数据的订单。另请注意,可以使用有状态的ItemReaders(JdbcCursorItemReaderJdbcPagingItemReader都是有状态的。)

带有同步阅读器的多线程步骤

用于:

  • 加快处理和编写单个步骤
  • 阅读时是有状态的

不要用于:

  • 加快阅读

有一种方法可以解决无法使用有状态项目阅读器的多线程步骤的问题。您可以synchronize使用read()方法。这实质上会导致读取连续发生(尽管仍然无法保证顺序),但仍然允许处理和写入并行发生。当阅读不是瓶颈而处理或写作时,这可能是一个很好的选择。

Partitioning

用于:

  • 加快个人步伐
  • 阅读时是有状态的
  • 输入数据可以分区时

不要用于:

  • 输入数据无法分区时

对一个步骤进行分区的行为与多线程步骤略有不同。使用分区步骤,您实际上具有完全不同的StepExecutions。每个StepExecution都在它自己的数据分区上工作。这样,读取器在读取相同数据时就没有问题,因为每个读取器只查看特定的数据片段。这种方法非常强大,但设置起来比多线程步骤更复杂。

Remote Chunking

用于:

  • 加快处理和编写单个步骤
  • 有状态读者

不要用于:

  • 加快阅读

远程分块是非常先进的Spring Batch使用方法。它需要具有某种形式的持久中间件来发送和接收消息(即JMS或AMQP)。通过远程分块,读取仍然是单线程的,但是当读取每个块时,它将被发送到另一个JVM进行处理。在实践中,这与多线程步骤的工作方式非常相似,但远程分块可以使用多个进程而不是多个线程。这意味着远程分块允许您水平缩放应用程序,而不是垂直缩放它。 (TBH我认为如果你正在考虑实现远程分块,你应该考虑看看像Hadoop这样的东西。)

Parallel Step

用于:

  • 加快整体工作执行
  • 当存在不依赖于彼此的独立步骤时

不要用于:

  • 加快步骤执行
  • 依赖步骤

当您有一个或多个可以独立执行的步骤时,并行步骤非常有用。 Spring批处理可以轻松地允许步骤在单独的线程中并行执行。