浅谈SpringBatch批处理框架

引言

在设计业务数据统计模块时,注意到当中有大量读写数据库的操作。出于提高模块健壮性和性能的考虑,引入springbatch批处理框架。以下是对springbatch框架的调研笔记和使用心得。

Springbatch简介

Spring Batch 是一个轻量级、全面的批处理框架,旨在支持开发对企业系统日常运营至关重要的强大的批处理应用程序。Spring Batch 提供了在处理大量记录时必不可少的可重用功能,包括日志记录/跟踪、事务管理、作业处理统计、作业重启、跳过和资源管理。它还提供更先进的技术服务和功能,通过优化和分区技术实现极高容量和高性能的批处理作业。

一个典型的批处理程序一般:

  1. 从数据库、文件或队列中读取大量记录。

  2. 以某种方式处理数据。

  3. 以修改后的形式写回数据。

为什么用springbatch(优点):

  • 批量处理:能够处理大批量数据的导入、导出、业务逻辑计算

  • 自动执行:无需人工干预,自动化执行批量操作

  • 灵活性 - Spring批处理应用程序非常灵活。只需更改XML文件即可更改应用程序中的处理顺序。

  • 可维护性 - Spring批量应用程序易于维护。 Spring Batch作业包括步骤,每个步骤都可以进行分离,测试和更新,而不影响其他步骤。

  • 可靠性 - 如果发生任何故障,可以通过拆除步骤来从停止的地方重新开始作业。

SpringBatch架构

SpringBatch的架构如下图。

一个Job可以配置多个Step,一个Step可各自定义其ItemReader用于读数据、ItemProcessor用于处理数据、ItemWriter用于写数据。而每个定义的Job,以及执行的相关参数和上下文都放在JobRepository里面。

 

 

 

而Step的执行又可以分块进行,一般来说,每个chunk对应n个itemReader,n个itemProcessor,1个itemWriter。

SpringBatch各组件的关系如下图

 

 

 

部署

maven配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-batch</artifactId>
</dependency>

 

application.yml配置

spring:
  batch:
    table-prefix:   #这里是设置spring batch数据库表的前缀
    initializer: 
      enabled: true  #这里是允许自动初始化spring batch的数据库
    job:
      enabled: false  #这里是设置不会自动先执行一次定义的job

 

Springbatch核心概念- Job

  • Job的概念

Job可以看作是Step的一个容器,下面是一个Job的配置:这里配置了三步:

  1. 开始的getRecordBeforeYesterdayStep

  2. 接着getAccountNumStep

  3. 第三步是writeRecordStep

  4. 用build结束构建

这里采用的是三步顺序执行的方式,springbatch也支持step的条件执行、分支执行等操作。

  • JobRepository概念

Job Repository来存储Job执行期的元数据(这里的元数据是指Job Instance、Job Execution、Job Parameters、Step Execution、Execution Context等数据)

  • JobLancher概念

Job Launcher(作业调度器)是Spring Batch框架基础设施层提供的运行Job的能力。通过给定的Job名称和作Job Parameters,可以通过Job Launcher执行Job。

SpringBatch核心概念-Step

  • Step

 

 

  • 此外,Spring Batch 在其最常见的实现中使用“面向块”的处理风格。面向块的处理是指一次读取一个数据并创建在事务边界内写出的“块”。一旦读取的项目数等于提交间隔,整个块由 写出 ItemWriter,然后提交事务。下图显示了该过程:

 

 

Spring Batch的一个基本层级结构:首先,Spring Batch运行的基本单位是一个Job,一个Job就做一件批处理的事情。一个Job包含很多Step,step就是每个job要执行的单个步骤。

Step里面,会有Tasklet,Tasklet是一个任务单元,它是属于可以重复利用的东西。然后是Chunk,chunk就是数据块,你需要定义多大的数据量是一个chunk。Chunk里面就是不断循环的一个流程,读数据,处理数据,然后写数据。Spring Batch会不断的循环这个流程,直到批处理数据完成

重试、退避机制

在处理百万级的数据过程过程中难免会出现异常。如果一旦出现异常而导致整个批处理工作终止的话那么会导致后续的数据无法被处理。Spring Batch内置了Retry(重试)和Skip(跳过)机制帮助我们轻松处理各种异常。我 们需要将异常分为三种类型。

  • 第一种是需要进行Retry的异常,它们的特点是该异常可能会随着时间推移而消失,比如数据库目前有锁无法写入、web服务当前不可用、web服务满载等。所以对它们适合配置Retry机制。

  • 第二种是需要Skip的异常,比如解析文件的某条数据出现异常等,因为对这些异常即使执行Retry每次的结果也都是相同,但又不想由于某条数据出错而停止对后续数据的处理。

  • 第三种异常是需要让整个Job立刻失败的异常,比如如果出现了OutOfMemory的异常,那么需要整个Job立刻终止运行。

一般来说需要Retry的异常也要配置Skip选项,从而保证后续的数据能够被继续处理。我们也可以配置SkipLimit选项保证当Skip的数据条目达到一定数量后及时终止整个Job。

具体配置

以下是我项目中一个其中一个Step的配置

  • faultTolerant()的配置表示可允许出错时进行重试跳过,而不会直接异常报错

  • retryLimit(RETRY_LIMIT) : RETRY_LIMIT表示最大重试次数,若重试多次依旧出错时,会根据是否配置了skip来跳过该异常或者报错抛出

  • retry(Exception.class): 这里配置的是需要重试的异常情况,可以对不同的异常情况设置不同的容忍。

  • skipLimit与skip的配置类似

  • 可以对reader、processor、writer灵活配置各自不同的重试、跳过次数以及异常类

SpringBatch元数据表

SpringBatch使用六张业务表存储了所有的元数据信息(包括Job、Step的实例,上下文,执行器信息,为后续的监控、重启、重试、状态恢复等提供了可能)。

  • BATCH_JOB_INSTANCE:作业实例表,用于存放Job的实例信息

  • BATCH_JOB_EXECUTION_PARAMS:作业参数表,用于存放每个Job执行时候的参数信息,该参数实际对应Job实例的。

  • BATCH_JOB_EXECUTION:作业执行器表,用于存放当前作业的执行信息,比如创建时间,执行开始时间,执行结束时间,执行的那个Job实例,执行状态等。

  • BATCH_JOB_EXECUTION_CONTEXT:作业执行上下文表,用于存放作业执行器上下文的信息。

  • BATCH_STEP_EXECUTION:作业步执行器表,用于存放每个Step执行器的信息,比如作业步开始执行时间,执行完成时间,执行状态,读写次数,跳过次数等信息。

  • BATCH_STEP_EXECUTION_CONTEXT:作业步执行上下文表,用于存放每个作业步上下文的信息。

posted @ 2022-04-01 16:40  BKYCZJ  阅读(930)  评论(0编辑  收藏  举报