多线程与分区之间的Spring批处理差异

我无法理解Spring批处理中的多线程和分区之间的区别 . 实现当然是不同的:在分区中,您需要准备分区然后处理它 . 我想知道有什么区别,当瓶颈是物品处理器时,哪一种是更有效的处理方式 .

回答(1)

2 years ago

TL;DR;
当瓶颈在处理器中时,这两种方法都不是有用的 . 通过让多个项目同时通过处理器,您会看到一些好处,但是当您在I / O绑定的进程中使用时,您指出的两个选项都会获得全部好处 . AsyncItemProcessor / AsyncItemWriter 可能是更好的选择 .

Overview of Spring Batch Scalability
缩放Spring Batch作业有五种选择:

  • 多线程步骤

  • 平行步骤

  • 分区

  • 远程分块

  • AsyncItemProcessor / AsyncItemWriter

每个人都有自己的利弊 . 让我们来看看每个:

Multithreaded step
多线程步骤只需一步,并在单独的线程上执行该步骤中的每个块 . 这意味着每个批处理组件(读取器,编写器等)的相同实例在线程之间共享 . 在大多数情况下,这可以通过在步骤中添加一些并行性来提高性能,但代价是可重启性 . 您牺牲了可重启性,因为在大多数情况下,重启的能力取决于读取器/写入器/等中维护的状态 . 有多个线程更新该状态,它将变为无效并且无法重启 . 因此,您通常需要在单个组件上关闭保存状态,并在作业上将restartable标志设置为false .

Parallel steps
通过分割实现平行步骤 . 它允许您通过线程并行执行多个独立的步骤 . 这不会牺牲可重启性,但无助于提高单步或业务逻辑的性能 .

Partitioning
分区是通过主步骤将数据预先划分为较小的块(称为分区),然后让从站在分区上独立工作 . 在Spring Batch中,主服务器和每个从服务器都是一个独立的步骤,因此您可以在一个步骤中获得并行性的好处,而不会牺牲可重启性 . 分区还提供了扩展到单个JVM之外的能力,因为从属设备不必是本地的(您可以使用各种通信机制与远程从属设备通信) .

关于分区的一个重要注意事项是主站和从站之间的唯一通信是数据的描述而不是数据本身 . 例如,主设备可以告诉slave1处理记录1-100,slave2处理记录101-200等 . 主设备不发送实际数据,只发送从设备获取它应该处理的数据所需的信息 . . 因此,数据必须是从属进程的本地数据,并且主服务器可以位于任何位置 .

Remote chunking
远程分块允许您跨JVM扩展进程和可选的写入逻辑 . 在此用例中,主设备读取数据,然后通过线路将其发送到处理它的从设备,然后在本地写入从设备或返回到主设备以便在本地写入主设备 .

分区和远程分块之间的重要区别在于,远程分块不是通过线路进行描述,而是通过线路发送实际数据 . 因此,不是单个数据包说过程记录1-100,远程分块将发送实际记录1-100 . 这会对步骤的I / O配置文件产生很大影响,但如果处理器足够瓶颈,这可能很有用 .

AsyncItemProcessor/AsyncItemWriter
扩展Spring Batch进程的最终选项是 AsyncItemProcessor / AsycnItemWriter 组合 . 在这种情况下, AsyncItemProcessor 包装您的 ItemProcessor 实现并在单独的线程中执行对您的实现的调用 . 然后 AsyncItemProcessor 返回 Future ,该 Future 传递给 AsyncItemWriter ,在那里它被解包并传递给委托 ItemWriter 实现 .

由于数据如何通过此选项流动的性质,不支持某些侦听器场景(因为我们在 ItemWriter 内部之前不知道 ItemProcessor 调用的结果)但总的来说,它可以提供一个有用的工具来并行化 ItemProcessor 单个JVM中的逻辑,而不会牺牲可重启性 .