在設計業務數據統計模塊時,注意到當中有大量讀寫數據庫的操作。出於提高模塊健壯性和性能的考慮,引入springbatch批處理框架。以下是對springbatch框架的調研筆記和使用心得。
Springbatch簡介
Spring Batch 是一個輕量級、全面的批處理框架,旨在支持開發對企業系統日常運營至關重要的強大的批處理應用程序。Spring Batch 提供了在處理大量記錄時必不可少的可重用功能,包括日志記錄/跟蹤、事務管理、作業處理統計、作業重啟、跳過和資源管理。它還提供更先進的技術服務和功能,通過優化和分區技術實現極高容量和高性能的批處理作業。
一個典型的批處理程序一般:
-
從數據庫、文件或隊列中讀取大量記錄。
-
以某種方式處理數據。
-
以修改后的形式寫回數據。
為什么用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的配置:這里配置了三步:
-
開始的getRecordBeforeYesterdayStep
-
接着getAccountNumStep
-
第三步是writeRecordStep
-
用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:作業步執行上下文表,用於存放每個作業步上下文的信息。