我无法理解Spring批处理中多线程和分区之间的区别。实现当然是不同的:在分区中,您需要准备分区然后处理它。我想知道有什么区别,当瓶颈是物品处理器时,哪一种是更有效的处理方式。
答案 0 :(得分:12)
<强> TL; DR; 强>
当瓶颈在处理器中时,这两种方法都不是有用的。通过让多个项目同时通过处理器,您会看到一些好处,但是当您在I / O绑定的进程中使用时,您指出的两个选项都会获得全部好处。 AsyncItemProcessor
/ AsyncItemWriter
可能是更好的选择。
Spring批量可伸缩性概述
缩放Spring Batch作业有五种选择:
AsyncItemProcessor
/ AsyncItemWriter
每个人都有自己的利弊。让我们逐一介绍:
多线程步骤
多线程步骤只需一步,并在单独的线程上执行该步骤中的每个块。这意味着每个批处理组件(读取器,编写器等)的相同实例在线程之间共享。在大多数情况下,这可以通过在步骤中添加一些并行性来提高性能,但代价是可重启性。您牺牲了可重启性,因为在大多数情况下,重新启动的能力取决于读取器/写入器/等中维护的状态。有多个线程更新该状态,它将变为无效并且无法重启。因此,您通常需要在单个组件上关闭保存状态,并在作业上将restartable标志设置为false。
平行步骤
通过分割实现平行步骤。它允许您通过线程并行执行多个独立的步骤。这不会牺牲可重启性,但无助于提高单步或业务逻辑的性能。
<强>分区强>
分区是通过主步骤将数据预先划分为较小的块(称为分区),然后让从站在分区上独立工作。在Spring Batch中,主服务器和每个从服务器都是一个独立的步骤,因此您可以在一个步骤中获得并行性的好处,而不会牺牲可重启性。分区还提供了扩展到单个JVM之外的能力,因为从属设备不必是本地的(您可以使用各种通信机制与远程从属设备通信)。
关于分区的一个重要注意事项是主站和从站之间的唯一通信是数据的描述,而不是数据本身。例如,主设备可以告诉slave1处理记录1-100,slave2处理记录101-200等。主设备不发送实际数据,只发送从设备获取它应该处理的数据所需的信息。 。因此,数据必须是从属进程的本地数据,并且主服务器可以位于任何位置。
远程分块
远程分块允许您跨JVM扩展进程和可选的写入逻辑。在这个用例中,主设备读取数据然后通过线路将其发送到处理它的从设备,然后在本地写入从设备或返回到主设备以便在本地写入主设备。
分区和远程分块之间的重要区别在于,远程分块不是通过线路进行描述,而是通过线路发送实际数据。因此,不是单个数据包说过程记录1-100,远程分块将发送实际记录1-100。这会对步骤的I / O配置文件产生很大影响,但如果处理器足够瓶颈,这可能很有用。
<强> AsyncItemProcessor
/ AsyncItemWriter
强>
扩展Spring Batch流程的最终选项是AsyncItemProcessor
/ AsycnItemWriter
组合。在这种情况下,AsyncItemProcessor
包装您的ItemProcessor
实现,并在单独的线程中执行对您的实现的调用。 AsyncItemProcessor
然后返回Future
,传递给AsyncItemWriter
,然后将其解包并传递给委托ItemWriter
实施。
由于数据如何通过此选项流动,因此不支持某些侦听器方案(因为我们在ItemProcessor
内部之前不知道ItemWriter
调用的结果)但是总的来说,它可以提供一个有用的工具,用于在单个JVM中并行化ItemProcessor
逻辑,而不会牺牲可重启性。