简介
SpringBatch主要是一个轻量级的大数据量的并行处理(批处理)的框架。
作用和Hadoop很相似,不过Hadoop是基于重量级的分布式环境(处理巨量数据),而SpringBatch是基于轻量的应用框架(处理中小数据)。
1.2 批处理的核心场景
从某个位置读取大量的记录,位置可以是数据库、文件或者外部推送队列(MQ)。
根据业务需要实时处理读取的数据。
将处理后的数据写入某个位置,可以第一条一样,可是数据库、文件或者推送到队列。
1.3 Spring Batch能解决的批处理场景
Spring Batch为批处理提供了一个轻量化的解决方案,它根据批处理的需要迭代处理各种记录,提供事物功能。
但是Spring Batch仅仅适用于"脱机"场景,在处理的过程中不能和外部进行任何交互,也不允许有任何输入。
1.3 Spring Batch的目标
开发人员仅关注业务逻辑,底层框架的交互交由Spring Batch去处理。
能够清晰分离业务与框架,框架已经限定了批处理的业务切入点,业务开发只需关注这些切入点(Read、Process、Write)。
提供开箱即用的通用接口。
快速轻松的融入Spring 框架,基于Spring Framework能够快速扩展各种功能。
所有现有核心服务都应易于更换或扩展,而不会对基础架构层产生任何影响。
1.4 Spring Batch结构
如下图,通常情况下一个独立的JVM程序就是仅仅用于处理批处理,而不要和其他功能重叠。 在最后一层基础设置(Infrastructure)部分主要分为3个部分。JobLauncher、Job以及Step。每一个Step又细分为ItemReader、ItemProcessor、ItemWirte。使用Spring Batch主要就是知道每一个基础设置负责的内容,然后在对应的设施中实现对应的业务。
1.5 Spring Batch 批处理原则与建议
当构建批处理过程时,必须注意以下原则:
- 通常情况下,批处理的过程对系统和架构的设计要够要求比较高,因此尽可能使用通用架构来处理批量数据处理,降低问题发生的可能性。Spring Batch是一个是一个轻量级的框架,适用于处理一些灵活并没有到海量的数据。
- 批处理应该尽可能的简单,尽量避免在单个批处理中去执行过于复杂的任务。我们可以将任务分成多个批处理或者多个步骤去实现。
- 保证数据处理和物理数据紧密相连。笼统的说就是我们在处理数据的过程中有很多步骤,在某些步骤执行完时应该就写入数据,而不是等所有都处理完。
- 尽可能减少系统资源的使用、尤其是耗费大量资源的IO以及跨服务器引用,尽量分配好数据处理的批量。
- 定期分析系统的IO使用情况、SQL语句的执行情况等,尽可能的减少不必要的IO操作。优化的原则有:
- 尽量在一次事物中对同一数据进行读取或写缓存。
- 一次事物中,尽可能在开始就读取所有需要使用的数据。
- 优化索引,观察SQL的执行情况,尽量使用主键索引,尽量避免全表扫描或过多的索引扫描。
- SQL中的where尽可能通过主键查询。
- 不要在批处理中对相同的数据执行2次相同的操作。
- 对于批处理程序而言应该在批处理启动之前就分配足够的内存,以免处理的过程中去重新申请新的内存页。
- 对数据的完整性应该从最差的角度来考虑,每一步的处理都应该建立完备的数据校验。
- 对于数据的总量我们应该有一个和数据记录在数据结构的某个字段上。
- 所有的批处理系统都需要进行压力测试。
- 如果整个批处理的过程是基于文件系统,在处理的过程中请切记完成文件的备份以及文件内容的校验。
1.6 批处理的通用策略
和软件开发的设计模式一样,批处理也有各种各样的现成模式可供参考。当一个开发(设计)人员开始执行批处理任务时,应该将业务逻辑拆分为一下的步骤或者板块分批执行:
- 数据转换:某个(某些)批处理的外部数据可能来自不同的外部系统或者外部提供者,这些数据的结构千差万别。在统一进行批量数据处理之前需要对这些数据进行转换,合并为一个统一的结构。因此在数据开始真正的执行业务处理之前,可以先搭建批处理任务将这些数据统一转换。
- 数据校验:批处理是对大量数据进行处理,并且数据的来源千差万别,所以批处理的输入数据需要对数据的完整性性进行校验(比如校验字段数据是否缺失)。另外批处理输出的数据也需要进行合适的校验(例如处理了100条数据,校验100条数据是否校验成功)
- 提取数据:批处理的工作是逐条从数据库或目标文件读取记录(records),提取时可以通过一些规则从数据源中进行数据筛选。
- 数据实时更新处理:根据业务要求,对实时数据进行处理。某些时候一行数据记录的处理需要绑定在一个事物之下。
- 输出记录到标准的文档格式:数据处理完成之后需要根据格式写入到对应的外部数据系统中。
以上五个步骤是一个标准的数据批处理过程,Spring batch框架为业务实现提供了以上几个功能入口。
概念
JobRepository
从字面上可以理解为"任务仓库",如果把一个批处理比作一个任务的话,这个仓库存储了很多这种任务。JobRepository 会将任务包括其状态等数据持久化,存储到许多数据库中。Spring Batch 默认会提供一个 SimpleJobRepository 仓库,方便我们开启批处理。
Job
“任务”。每个批处理都是一个任务,除了任务本身之外,任务也存在成功和失败等等状态,所以可以引出两个概念 JobInstance 与 JobExecution 。job 是一个接口,JobInstance 是其实现,代表了“任务”本身,提供了 getJobName、getInstanceId 等方法供我们获取任务本身的一些属性。JobExecution 代表任务的状态,如创建时间、结束时间、结束状态、抛出的异常等等。
Step
“步骤”。批处理任务肯定有非常多的步骤,如一个最基本的数据库同步,从 A 数据库读取数据,存入到 B 数据库中,这里就分为了两个步骤。在 Spring Batch 中,一个任务可以有很多个步骤,每个步骤大致分为三步:读、处理、写,其对应的类分别就是 Item Reader,Item Processor,Item Writer。
JobLauncher
“任务装置”。如火箭发射装置就是用来操作火箭发射的,这里的任务装置就是用来执行任务的。
Spring Batch批处理的核心概念
如图所示,在一个标准的批处理任务中组要涵盖的核心概念有JobLauncher、Job、Step,一个Job可以涵盖多个Step,一个Job对应一个启动的JobLauncher。一个Step中分为ItemReader、ItemProcessor、ItemWriter,根据字面意思它们分别对应数据提取、数据处理和数据写入。此外JobLauncher、Job、Step也称之为批处理的元数据(Metadata),它们会被存储到JobRepository中。
SpringBatch结构
- Spring Batch运行的基本单位是一个Job,一个Job就做一件批处理的事情。
- 一个Job 通常由一个或多个Step组成(基本就像是一个工作流);step就是每个job要执行的单个步骤。
- 一个Step通常由三部分组成(读入数据 ItemReader,处理数据 ItemProcessor,写入数据 ItemWriter)
- Step里面,会有Tasklet,Tasklet是一个任务单元,根据 Spring Batch 的设计,在一个 Step 中只能执行一个 Tasklet, 如果要按照顺序执行多个 Tasklet ,我们需要设置不同的 Step。
- chunk:数据块,构造器入参指定了数据块的大小, 如指定为2时表示 每当读取2组数据后, 做一次数据输出处理,Chunk里面就是不断循环的一个流程,读数据,处理数据,然后写数据, Spring Batch会不断的循环 这个流程,直到批处理数据完成。
数据处理注意事项
4.1 数据额外处理
某些情况需要实现对数据进行额外处理,在进入批处理之前通过其他方式将数据进行处理。主要内容有:
- 排序:由于批处理是以独立的行数据(record)进行处理的,在处理的时候并不知道记录前后关系。因此如果需要对整体数据进行排序,最好事先使用其他方式完成。
- 分割:数据拆分也建议使用独立的任务来完成。理由类似排序,因为批处理的过程都是以行记录为基本处理单位的,无法再对分割之后的数据进行扩展处理。
- 合并:理由如上。
4.2 常规数据源
批处理的数据源通常包括:
- 数据库驱动链接(链接到数据库)对数据进行逐条提取。
- 文件驱动链接,对文件数据进行提取
- 消息驱动链接,从MQ、kafka等消息系统提取数据。
4.3 典型的处理过程
- 在业务停止的窗口期进行批数据处理,例如银行对账、清结算都是在12点日切到黎明之间。简称为离线处理。
- 在线或并发批处理,但是需要对实际业务或用户的响应进行考量。
- 并行处理多种不同的批处理作业。
- 分区处理:将相同的数据分为不同的区块,然后按照相同的步骤分为许多独立的批处理任务对不同的区块进行处理。
- 以上处理过程进行组合。