0

我有大量的报告加载到块分区步骤中。每个报告将被进一步处理以生成单独的报告。但是,如果我在分区步骤中加载 50k 的报告,这会使服务器过载并且速度会变得很慢。而不是我更喜欢,分区步骤加载 3k 的报告列表,处理它,然后在分区步骤上加载另一个 3k 报告.. 继续相同,直到 50k 报告得到处理。

    <step id="genReport" next="fileTransfer">
        <chunk  item-count="1000">
            <reader ref="Reader" >
            </reader>
            <writer
                ref="Writer" >
            </writer>
        </chunk>
      <partition>
            <mapper ref="Mapper">
                <properties >
                    <property name="threadCount" value="#{jobProperties['threadCount']}"/>
                    <property name="threadNumber" value="#{partitionPlan['threadNumber']}"/>
                </properties>
            </mapper>
      </partition>
    </step> 
public PartitionPlan mapPartitions() {
        PartitionPlanImpl partitionPlan = new PartitionPlanImpl();
        int numberOfPartitions = //dao call to load the reports count
        partitionPlan.setThreads(getThreadCount());
        partitionPlan.setPartitions(numberOfPartitions); //This numberOfPartitions is comes from the database, huge size like 20k to 40k
        Properties[] props = new Properties[numberOfPartitions];

        for (int idx = 0; idx < numberOfPartitions; idx++) {
            Properties threadProperties = new Properties();
            threadProperties.setProperty("threadNumber", idx + "");
            GAHReportListData gahRptListData = gahReportListManager.getPageToProcess(); //Data pulled from PriorityBlockingQueue 
            String dynSqlId = gahRptListData.getDynSqlId(); 

            threadProperties.setProperty("sqlId", dynSqlId);
            threadProperties.setProperty("outFile", fileName);

            props[idx] = threadProperties;
        }
        partitionPlan.setPartitionProperties(props);
        return partitionPlan;
    }

一旦分区映射器处理了 3k 个数据报告,则它必须检查下一个可用列表。如果可用,则应使用下一组要处理的 3k 报告重置分区。

4

1 回答 1

1

没有办法重置分区。当 partitionMapper 定义的所有分区都完成后,这一步就结束了。您可以进行第二个分区步骤,就像我猜的第一个(第三个和第四个)一样,直到您完成所有操作。那很乱。而且您不能在 JSL 中循环并再次重新执行相同的步骤。

您可以拥有同时运行多个这些步骤的拆分/流,但您不能动态设置流的数量。那是在 JSL 中。而且您最终会获得您的环境可能处理的更多并发性。

我假设您的块读取器/处理器/写入器正在迭代现在分配给分区的一个 SQLid 的结果。要创建一个 sqlid 列表,我想您需要一种方法来判断一个何时完成以及下一个何时在同一个块循环中开始。读者可能可以管理列表并知道转换何时发生。您可能需要向作者发出一个信号,即块结束是一个报告的结束,它应该移动到下一个报告。您可能需要一个自定义检查点算法,这样您就可以确保在报告末尾进行检查点,而不是希望在每个 sqlid 用完要处理的记录时点击检查点。

我将其作为答案而不是另一条评论,因为这里提出的问题的答案似乎是“不”。剩下的只是讨论可能的替代方法。

于 2019-06-19T20:43:51.220 回答