如何在JSR352中定义一个好的分区计划来确保CPU平衡



JSR 352-Java平台的批处理应用程序使用分区提供并行功能。批处理运行时可以在不同的分区中执行一个步骤,以加快进度。JSR352还引入了threads定义:我们可以定义要使用的线程数,例如

<step id="Step1">
    <chunk .../>
        <partition>
            <plan partitions="3" threads="2"/>
        </partition>
    </chunk>
</step>

然后我感到困惑:如何给出一个令人赞赏的分区计划,使每个线程都被占用,并确保CPU平衡?

例如,有表A、B、C要做,它们的行分别为10亿、100万、1000。该步骤旨在将这些实体处理为文档,一个实体处理为一个文档。文件制作的顺序并不重要。这些表实体的CPU时间分别为1s、2s、5s。线程数为4。

如果有3个分区,每个表类型一个,那么该步骤将需要1 * 10^9秒才能完成,因为:

  • 分区A将使用1 * 10^9 * 1s = 1 * 10^9s,在线程2上运行
  • 分区B将使用1 * 10^6 * 2s = 2 * 10^6s,在线程3上运行
  • 分区C将使用1 * 10^3 * 5s = 5 * 10^3s,在线程4上运行

然而,当线程2被占用时,线程3由于2 * 10^6s而空闲,线程4由于5 * 10^3s而空闲。很明显,这不是一个好的分区计划。

我的问题是:

  • 在上面的例子中,是否有更好的分区计划需要完成
  • 我可以考虑:分区是一个要使用的队列,线程使用这个队列吗
  • 一般来说,我可以/应该使用多少个线程?这是相同数量的CPU核心吗
  • 一般来说,如何给出一个令人满意的分区计划,以便每个线程都被占用并确保CPU平衡

答案。。。

在上面的例子中,是否有更好的分区计划需要完成?

是的,有。见答案4…

我可以考虑:分区是一个要使用的队列,线程使用这个队列吗?

事情就是这样!

一般来说,我可以/应该使用多少个线程?这是相同数量的CPU核心吗?

这取决于情况。这个问题有很多观点从JSR-352规范视图,"线程":

指定要在其上执行分区的最大线程数这一步骤。请注意,批处理运行时不能保证所请求的线程数可用;它将尽可能多地使用,直到请求的最大值。这是一个可选属性。默认值是分区数。

因此,仅从这个角度来看,您应该将该值设置得尽可能高(批处理运行时将根据其资源设置实际限制!)。

从批处理运行时的角度(JSR352实现):任何合适的实现都将使用线程池来执行分区步骤。所以,如果这样的池有一个固定的N大小,无论你设置多大的线程数,你永远不会同时执行超过N个分区。

JBeret是JSR352规范的一个实现,由wildfly服务器使用(这是我使用过的实现)。在Wildfly,它的默认线程池设置为最多10个线程。此池不仅在分区步骤之间共享,而且在批处理作业之间共享。因此,如果您同时运行2个作业,那么您将少使用2个线程。除此之外,当您进行分区时,一个线程将扮演协调器的角色,将分区分配给其他线程并等待结果。。。因此,如果您的分区计划说它使用2个线程,那么实际上它将使用3个!(两名工人,一名协调员)。。。所有这些资源(线程)都来自同一个池!!

无论如何,这一切的重要之处在于:调查您使用的JSR325实现是什么,并相应地进行设置

从硬件视图,您的CPU有线程最大限制。在这种情况下(根据经验),将"threads"值设置为等于这样的值。

从性能视图分析您正在做的工作。如果您正在访问多个线程之间的共享资源(如DB),则可能会产生导致线程阻塞的瓶颈。如果你面临这种问题,你必须考虑降低"theads"的价值。

在摘要中,将"threads"值设置为与CPU最大线程限制一样高。然后,检查该值是否不会导致阻塞问题;如果是,则减小该值。此外,请验证是否相应地配置了批处理运行时,它允许您执行任意数量的线程。

一般来说,如何给出一个令人满意的分区计划,以便每个线程都被占用并确保CPU平衡?

避免使用静态分区计划(至少对于您的情况)。相反,请使用分区映射器。分区映射器是一个实现javax.batch.api.partition.PartitionMapper接口的类,它允许以编程方式定义分区计划(有多少个分区、有多少个线程、每个分区的属性)。因此,对于您的情况,取您的表(A、B、C),并将它们拆分为N块(其中N=1000)。。。每个块将是一个分区。您应该从C类型的分区开始,并在实体分区(表)之间进行循环:C0B0A0B1A1。。。,B999A999A1000。。。,A999999。。。使用这个方案,实体C将首先完成,留下一个线程来解析更多的A和B分区。稍后,B将完成,留下更多的资源来攻击剩余的A分区。

希望这个帮助。。。

最新更新