【发布时间】:2017-12-21 22:32:33
【问题描述】:
我有一个可能包含 10 亿到 50 亿条记录的大文件。我打算使用面向块的处理,我的想法是
1) 根据计数将大文件拆分为较小的文件,假设每个文件中有 10K。
2) 如果有 10 亿条记录,那么我将获得 10000 个文件,每个文件包含 10K 条记录
3) 我想对这 10000 个文件进行分区,并希望使用 10 个线程进行处理。我使用了自定义 MultiResourcePartioner
4) 10 个线程应该处理拆分过程中创建的所有 10000 个文件。
5) 我不想创建与文件数相同的线程数,因为在这种情况下我可能会遇到内存问题。我正在寻找的是我想仅使用 10 个线程处理的文件数量。
专家您能告诉我这可以使用弹簧批处理来实现吗?如果是,请您分享指针或参考实现。
示例:
<bean id="transformPartitioner"
class="com.example.transformers.partition.TransformerPartitioner">
<property name="outputPath" value="${output.directory}" />
</bean>
<bean id="loadTransformData" class="com.example.transformers.step.LoadTransformData"
factory-method="reader" scope="step">
<constructor-arg value="#{stepExecutionContext[outputFile]}" />
</bean>
<bean id="processTransformData" class="com.example.transformers.step.ProcessTransformData"
scope="step">
<property name="threadName" value="#{stepExecutionContext[threadName]}" />
<property name="sourceFileName" value="#{jobParameters[filename]}" />
</bean>
<bean id="notifyToJMS" class="com.example.transformers.step.NotifyToJMS"
scope="step">
<property name="fileName" value="#{stepExecutionContext[outputFile]}" />
</bean>
<bean id="outputFileDeletingTasklet"
class="com.example.transformers.step.OutputFileDeletingTasklet"
scope="step">
<property name="directory" value="file:${output.directory}" />
</bean>
<bean class="org.springframework.batch.core.scope.StepScope" />
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
自定义多资源分区:
public Map<String, ExecutionContext> partition(int gridSize) {
int index = 0;
File directory = new File(outputPath);
File[] fList = directory.listFiles();
Map result = new HashMap(gridSize);
for (File file : fList) {
if (file.isFile()) {
ExecutionContext exContext = new ExecutionContext();
logger.info(loggerClassName+" Starting : Thread [" + index + "] for file : " + file.getName());
exContext.put(constants.THREAD_NAME, "Thread" + index);
exContext.put(constants.OUTPUT_FILE, outputPath + file.getName());
exContext.put(constants.OUTPUT_FILE_NAME, file.getName());
result.put(constants.PARTITION + index, exContext);
index++;
}
}
感谢您的回复。
【问题讨论】:
-
我认为处理过这么大数字的人数很少。世界可能会使用更多的专家来使用 Spring Batch 处理数十亿条记录,所以尝试一下,看看会发生什么......然后报告:)
-
我不知道如何解决这个问题。没有办法控制分区?有没有可能作为批次明智的。例如,第一批 100 个分区用于 100 个文件,第二批 100 个分区用于下一个 100 个文件.. 等等.. 我的要求是有 10 亿到 50 亿条记录作为平面文件数据
-
@Sai:对不起,我很忙。您的回答应该是对我的回答的评论,而不是回答本身。很高兴您的问题得到解决。
-
我是这个应用程序的新手。展望未来,我将遵循同样的原则。非常感谢萨比尔。
标签: spring-batch