3

这是一个艰难的过程,但我相信它并非闻所未闻。

我有两个数据集,国家和人口统计。国家数据集包含国家名称和其人口统计数据的 ID。

人口统计数据集是从国家到郊区的分层数据集。

这两个数据集都是每周从第 3 方提取的。

我需要将人口统计数据分成文件,每个国家/地区一个。

到目前为止,我所拥有的步骤是 1)拉国家 2)拉人口 3)(这是必需的)循环国家数据集,调用“将国家人口统计数据写入文件”

是否有可能以某种方式重复通过当前国家/地区ID的步骤?

编辑:添加了 PartitionHandler 示例的链接

谢谢杰布里斯托。下面的链接显示了使用 JavaTask 对象的 addArgument 覆盖 PartitionHandler 来传递参数的用法,但它看起来像开发人员的大量繁重工作,而不是 Spring 批处理的目标“特定于业务问题”。 http://www.activeeon.com/blog/all/integration/distribute-a-spring-batch-job-on-the-proactive-scheduler

我还在您的原始链接第 7.4.3 节中看到了。将输入数据绑定到步骤这是在 7.4.2 的上下文中。分区器,这个看起来很刺激

<bean id="itemReader" scope="step"
    class="org.spr...MultiResourceItemReader">
  <property name="resource" value="#{stepExecutionContext[fileName]}/*"/>
</bean>

我不认为有人在玩这个的一些示例 XML 配置吗?

  1. 分区器
  2. 将动态值传递给分区内的步骤

提前致谢。

4

1 回答 1

12

是的,看看 spring-batch 的分区功能!http://static.springsource.org/spring-batch/reference/html-single/index.html#partitioning

基本上,它允许您使用“分区器”来创建新的执行上下文以传递给处理程序,然后处理程序对该信息进行处理。

虽然分区是为并行化而设计的,但其默认并发数为 1,因此您可以从小处着手,然后逐步提高以匹配您可以使用的硬件。由于我假设每个国家/地区的数据不依赖于其他国家/地区(至少在下载人口统计步骤中),因此您的工作可以利用基本的并行化。

/编辑:添加示例。

这是我所做的(或多或少):首先,XML:

<beans>
  <batch:job id="jobName">
    <batch:step id="innerStep.master">
      <batch:partition partitioner="myPartitioner" step="innerStep"/>
    </batch:step>
  </batch:job>
  <bean id="myPartitioner" class="org.lapseda.MyPartitioner" scope="step">
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
    <property name="runDate" value="#{jobExecutionContext['runDate']}"/>
    <property name="recurrenceId" value="D"/>
  </bean>
  <batch:step id="summaryDetailsReportStep">
    <batch:tasklet>
      <batch:chunk reader="someReader" processor="someProcessor" writer="someWriter" commit-interval="10"/>
    </batch:tasklet>
  </batch:step>
</beans>

现在一些Java:

public class MyPartitioner implements Partitioner {
  @Override 
  public Map<String, ExecutionContext> partition(int gridSize) {
    List<String> list = getValuesToRunOver();
    /* I use treemap because my partitions are ordered, hashmap should work if order isn't important */
    Map<String, ExecutionContext> out = new TreeMap<String, ExecutionContext>(); 
    for (String item : list) {
      ExecutionContext context = new ExecutionContext();
      context.put("key", "value"); // add your own stuff!
      out.put("innerStep"+item, context);
    }
    return out;
  }
}

然后,您只需从上下文中读取,就像从步骤中的正常步骤或工作上下文中读取一样。

于 2012-05-14T22:59:00.987 回答