关于提高春季批处理作业的重新启动速度有任何想法吗?

时间:2019-02-12 16:12:14

标签: spring-batch

我有一个春季批处理作业,该作业将表中的数据从一个Oracle模式复制到另一个。 为此,我编写了分区作业。 例如:

案例A:

我有一个具有100000行的表A,我分成100个步骤,每个步骤1000行。所有这些插入都是使用ThreadPool任务执行程序并行完成的。如果4个步骤由于某些问题而失败。我重新启动了作业,它按预期在几秒钟内成功运行了失败的4个步骤。

情况B:

说一张包含3200万行的表A将从源复制到目标。 因此,我将这项工作分为1000行,因此创建了32000个步骤。

由于某些数据库问题,在这32000个步骤中,有4个步骤失败。当我尝试重新启动此作业时,Spring批处理只是挂起,或者我不知道重新启动后正在进行什么处理,所以它什么也没做。我等了5个小时,然后杀死了工作。

所以有人可以帮助我了解重启后发生的情况,步骤总数如何影响重启?我该怎么做才能提高速度?

请让我知道是否需要更多信息。

更新

我能够通过实现PartitionNameProvider来加快案例B的速度,并在重新启动期间通过getPartitionNames单独返回失败步骤的名称。大。我正在用更多的失败次数来测试这种重新启动,而我现在又有一种情况。

情况C:

如果我有20000个步骤,而所有20000个步骤均失败。当我尝试重新启动这种情况。 getPartitionNames返回所有20000步骤。在这种情况下,我正面临我上面提到的问题。该过程挂起。

我试图通过启用spring调试日志来了解工作背后的情况(这花了我很长时间才发现,但值得)。我看到了一组特定的查询正在运行。他们是:


2019-02-22 06:40:27 DEBUG ResourcelessTransactionManager:755 - Initiating transaction commit
2019-02-22 06:40:27 DEBUG ResourcelessTransactionManager:39 - Committing resourceless transaction on [org.springframework.batch.support.transaction.ResourcelessTransactionManager$ResourcelessTransaction@5743a94e]
2019-02-22 06:40:27 DEBUG ResourcelessTransactionManager:367 - Creating new transaction with name [org.springframework.batch.core.repository.support.SimpleJobRepository.getLastStepExecution]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2019-02-22 06:40:27 DEBUG JdbcTemplate:682 - Executing prepared SQL query
2019-02-22 06:40:27 DEBUG JdbcTemplate:616 - Executing prepared SQL statement [SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION, JOB_CONFIGURATION_LOCATION from COPY_JOB_EXECUTION where JOB_INSTANCE_ID = ? order by JOB_EXECUTION_ID desc]
2019-02-22 06:40:27 DEBUG DataSourceUtils:110 - Fetching JDBC Connection from DataSource
2019-02-22 06:40:27 DEBUG DataSourceUtils:114 - Registering transaction synchronization for JDBC Connection
2019-02-22 06:40:27 DEBUG JdbcTemplate:682 - Executing prepared SQL query
2019-02-22 06:40:27 DEBUG JdbcTemplate:616 - Executing prepared SQL statement [SELECT JOB_EXECUTION_ID, KEY_NAME, TYPE_CD, STRING_VAL, DATE_VAL, LONG_VAL, DOUBLE_VAL, IDENTIFYING from COPY_JOB_EXECUTION_PARAMS where JOB_EXECUTION_ID = ?]
2019-02-22 06:40:27 DEBUG JdbcTemplate:682 - Executing prepared SQL query
2019-02-22 06:40:27 DEBUG JdbcTemplate:616 - Executing prepared SQL statement [SELECT STEP_EXECUTION_ID, STEP_NAME, START_TIME, END_TIME, STATUS, COMMIT_COUNT, READ_COUNT, FILTER_COUNT, WRITE_COUNT, EXIT_CODE, EXIT_MESSAGE, READ_SKIP_COUNT, WRITE_SKIP_COUNT, PROCESS_SKIP_COUNT, ROLLBACK_COUNT, LAST_UPDATED, VERSION from COPY_STEP_EXECUTION where JOB_EXECUTION_ID = ? order by STEP_EXECUTION_ID]
2019-02-22 06:40:27 DEBUG JdbcTemplate:682 - Executing prepared SQL query
2019-02-22 06:40:27 DEBUG JdbcTemplate:616 - Executing prepared SQL statement [SELECT STEP_EXECUTION_ID, STEP_NAME, START_TIME, END_TIME, STATUS, COMMIT_COUNT, READ_COUNT, FILTER_COUNT, WRITE_COUNT, EXIT_CODE, EXIT_MESSAGE, READ_SKIP_COUNT, WRITE_SKIP_COUNT, PROCESS_SKIP_COUNT, ROLLBACK_COUNT, LAST_UPDATED, VERSION from COPY_STEP_EXECUTION where JOB_EXECUTION_ID = ? order by STEP_EXECUTION_ID]
2019-02-22 06:40:30 DEBUG JdbcTemplate:682 - Executing prepared SQL query
2019-02-22 06:40:30 DEBUG JdbcTemplate:616 - Executing prepared SQL statement [SELECT SHORT_CONTEXT, SERIALIZED_CONTEXT FROM COPY_STEP_EXECUTION_CONTEXT WHERE STEP_EXECUTION_ID = ?]
2019-02-22 06:40:30 DEBUG JdbcTemplate:682 - Executing prepared SQL query
2019-02-22 06:40:30 DEBUG JdbcTemplate:616 - Executing prepared SQL statement [SELECT SHORT_CONTEXT, SERIALIZED_CONTEXT FROM COPY_JOB_EXECUTION_CONTEXT WHERE JOB_EXECUTION_ID = ?]
2019-02-22 06:40:30 DEBUG DataSourceUtils:327 - Returning JDBC Connection to DataSource

以此类推...

我了解到Spring对每个失败的步骤都一步一步执行 getLastStepExecution 。但是为什么getLastStepExecution用这种方式完成?还是有什么方法可以配置这个?例如批量读取所有步骤执行并开始处理,以减少重新启动时间。

谢谢。

0 个答案:

没有答案