[Spring Cloud Task]4 Spring Batch批處理探究

概述

本文是Spring Cloud Task系列的第四篇文章,如果你尚未使用過Spring Cloud Task,請 移步spring cloud task1 簡介與示例。

本文主要講述的是Spring的另一個核心子項目 Spring Batch,一個輕量級的綜合的批處理框架??蚣苤饕獮橐?guī)范、簡化企業(yè)級具有健壯性要求的重要日常任務。

Spring Batch為大批量數據處理提供很多可重用的核心組件,包括日志、追蹤、事務管理、任務處理分析、任務重啟、跳讀以及資源管理器。另外它還提供了更為先進的技術服務與特性,如通過最優(yōu)和分區(qū)技術來支持超大規(guī)模數據的高性能批處理??傊?,無論是簡單的,還是復雜的大數據量的處理任務,都可以利用該框架為信息處理提供可擴展的支持。

Spring Batch有以下特性:

  • 事務管理器
  • 任務塊處理
  • 聲明式I/O
  • Start/Stop/Restart狀態(tài)控制
  • Retry/Skip 任務重試與跳過
  • 管理員web操作接口(需要依賴Spring Cloud Data Flow)

詳情

在企業(yè)級應用中許多關鍵任務都需要批處理操作,需求大致可以分為如下幾類:

  • 自動化對大批量數據進行復雜處理。這些任務大部分都是基于時間事件驅動的無人值守任務(如月度統(tǒng)計、通知、通信任務)。
  • 在超大數據集合中進行周期性重復的業(yè)務邏輯(比如借款利率計算)。
  • 對內部或外部系統(tǒng)進行消息集成,通常還需要在一個事務管理器中完成格式化、驗證以及處理并存儲幾率。批處理應用可以每天為企業(yè)處理數以億計的數據。

Spring Batch繼承了Spring框架的設計理念,強調基于POJO的開發(fā)方式并且促進創(chuàng)建可維護、可測試的代碼。在功能設計上它利用調度框架(如Quartz)工作,并非是一個調度框架。

Spring Batch提供了很多用于支持大批量數據處理的功能,例如失敗后的重試、跳過記錄、從最后一次失敗的位置重新開始工作、定期批量的提交給事務型數據庫、可重用的組件(如解析器、映射器、讀取器、處理器、寫入器和校驗器)以及工作流定義。

使用場景

下面是幾個典型的批處理程序的使用場景:

  • 需要從數據庫、文件或隊列中讀取大批量的數據
  • 以數據流的方式處理數據
  • 以修改的形式回寫數據

Spring Batch 能夠自動完成上述基礎批處理迭代,并將類似的事務抽象成一個集合視角來處理,故而其典型應用場景就是無人值守的批處理。

Spring Batch是一個完全開源的框架,它提供了穩(wěn)定的企業(yè)級批處理任務的解決方案,尤其適用于以下業(yè)務場景。

  • 周期性提交的批處理任務
  • 并行批處理
  • 消息過程驅動任務處理
  • 超大規(guī)模并行批處理
  • 失敗后手動或自動重啟任務
  • 支持任務工作流,按照指定步驟執(zhí)行任務
  • 任務分批機制和任務跳過功能
  • 事務支持

技術目標

  • 使用Spring的編程模型,開發(fā)者只需集中精力關心業(yè)務邏輯的研發(fā),所有的基礎設施的操作都完全交由框架來管理。
  • 使基礎架構設施,軟件執(zhí)行環(huán)境和批處理應用之間完全分離。
  • 以接口的方式提供公共核心服務的功能,業(yè)務系統(tǒng)可以根據需要實現(xiàn)所需的組件。
  • 提供公共核心服務接口的簡單默認實現(xiàn),整個框架開箱可用
  • 借助于Spring框架,可以很方便的完成框架的配置,定制化以及繼承服務。
  • 所有核心服務都應該在不影響基礎層的情況下能夠被替換和繼承

架構設計

Spring Batch在設計時充分考慮的不同類型的用戶需求,重視框架的可擴展性。其設計上的分層架構如下圖所示。

Spring Batch 分層架構

Spring Batch的分層架構將系統(tǒng)分為應用層,核心層和基礎組組件層。

應用層包含所有批處理任務以及開發(fā)者使用Spring Batch編寫的其它代碼。

核心層提供運行與管理批處理任務的能力。主要有 JobLauncher,Job以及Step接口的實現(xiàn)類組成。

應用層和核心層都依賴于公共基礎層?;A層由公共的輸入reader、輸出writer以及服務service。

通用批處理程序參考指南

在設計批處理應用時,我們應慎重思考以下幾點。

  • 在同時具有批處理和實時處理的環(huán)境中,最好使用數據塊來作為整體操作對象,因為批處理架構和實時處理架構會相互影響。
  • 拒絕在單一批處理應用中使用復雜的邏輯結構,在設計應用時一定要遵守簡單至上的原則。
  • 保證在進行數據處理時有備份數據
  • 盡量減少系統(tǒng)資源占用,特別是應該大量使用內存計算以減少I/O操作。
  • 應謹慎檢查應用的I/O操作來確保應用沒有非必要的I/O(可通過分析SQL語句等方式),特別應仔細檢查是否存在以下四種缺陷:1. 當可以一次性讀取到所有數據,緩存在應用中時,卻在每個事務里都從物理磁盤讀取相關數據。2.在同一個事務中重復讀取數據。3.不必要的表或索引掃描。4.在where子句中使用非精確查找。
  • 必要情況下對計算的臨時結果值進行存儲,不要重復的進行相同的計算。
  • 在批處理應用開始時就申請足夠的內存空間,避免隨著時間的增加不斷的申請更多的內存空間。
  • 適當的檢查與記錄校驗以保證數據的完整性。
  • 進行周期性的校驗。例如在文件持續(xù)變動的場景下,需要從末尾計算總記錄數以及對關鍵字進行聚合統(tǒng)計。
  • 盡早的在與接近真實環(huán)境的條件下使用真實的數據進行壓力測試。
  • 在7*24小時高可用的大批量數據處理系統(tǒng)中,數據備份是一項有挑戰(zhàn)性的工作。運維都通常能設計好在線數據庫的備份,同樣重要文件的備份其實并不是那么容易操作。如果項目依賴于可變動的文件,那么文件的備份不但要關心適當的位置和文檔化,還應該定期的進行測試。

批處理策略

為了更好的設計和實現(xiàn)批處理系統(tǒng),基礎批處理應用的的構建塊和模式應該提供圖表式的框架以及編程接口給設計和研發(fā)人員。在設計批處理任務時,首重抽象分解階段,業(yè)務處理邏輯應該被分解為一連串的步驟,每一個步驟都是一個行為模塊。具體的步驟設計可參考下面的標準行為模塊。

  • 轉換型模塊:所謂轉換主要是在系統(tǒng)需要依賴外部數據時,將外部數據轉化為標準的輸入數據格式。在批處理系統(tǒng)中轉換模塊完全可以設計為公共可抽象的模塊。
  • 校驗型模塊:校驗組件用來確保輸入/輸出紀錄的正確性以及可持久化。比較有代表性的校驗如文件頭尾格式信息,行數校驗,校驗算法以及數據紀錄級別的反復核對。
  • 選取型應用:對批處理模塊的抽象的核心是精準定位應用的核心功能。如一個選取型模塊應該做的事是依照預定義的規(guī)則從文件或數據中選取數據作為輸入,然后輸出到目標位置。
  • 選取/更新型模塊:采用基于數據事件驅動的方式從文件或數據庫中讀取數據,進行更改之后將數據回寫持久化到數據庫或文件中。
  • 數據處理與更新模塊:數據處理型模塊的輸入事務源于外部數據源或檢驗型模塊。該行為模塊通常包含從數據庫中獲取需要進行處理的數據,然后更新數據庫或者創(chuàng)建若干新的數據。
  • 格式化輸出組件:輸出型組件從文件中讀取數據,依照標準去更改紀錄的數據結構后,將數據輸出到新的文件或者傳輸到其它系統(tǒng)中。

然而受復雜業(yè)務邏輯的影響,很多應用無法簡單的由上述標準行為模塊組成。此時或許可以嘗試將多個標準組件組合,以完成業(yè)務需求。除了上述標準模塊外,框架還提供了如下模塊。

  • 排序:從源文件中讀取數據,并依照指定的字段作為鍵進行排序。
  • 切分:從單個數據源中讀出數據,并依據參數規(guī)則將每條數據拆分輸出到多個目標地點。
  • 合并:與切分型模塊功能相反。

根據不同的數據源,批處理應用可被分為以下三類:

  1. 數據庫驅動型應用:數據依賴于由數據庫存儲的紀錄行或值。
  2. 文件驅動型應用:紀錄或值存儲在文件中
  3. 消息驅動型應用:數據紀錄由消息隊列維護

批處理策略的選擇

上述的批處理策略是批處理系統(tǒng)的基礎。在選用具體的批處理策略時要充分考慮很多因素。首先要估算數據量的大小,其次是批處理系統(tǒng)要面臨的并發(fā),再者還需要考慮系統(tǒng)的可用性要求(業(yè)務方希望系統(tǒng)7*24小時可用)。

下面是幾種典型的批處理模式(通常結合調度任務使用):

  • 離線普通批處理
  • 在線并發(fā)批處理
  • 并行運行多種批處理任務
  • 分區(qū)批處理(將一個批處理應用部署多個節(jié)點)
  • 綜合上述批處理模式

針對不同的模式,數據的提交和鎖定的策略非常重要,且在設計完成整體架構之后,批處理模式很難能獨立更改。鎖策略可以選用數據庫自帶的鎖,也可以自己自定義繼承框架中的鎖服務。鎖服務可以根據數據庫鎖狀態(tài)來判斷是否給予數據庫操作的權限。根據鎖服務的狀態(tài),也可以避免自己繼承實現(xiàn)的重試邏輯的無意義執(zhí)行。

離線普通批處理

在數據不被線上客戶修改訪問,沒有并發(fā)處理的需求,也沒有其它批處理任務一同對這些數據進行更改時,當前任務處理完成后就可以簡單的對結果進行提交。

誠然最簡單的邏輯是最有效的。但是隨著時間的發(fā)展和產品迭代,要處理的數據關系會愈加復雜,數據量也會變得越來越大。如果沒有設計鎖服務,此時批處理模型的數據單次提交邏輯就顯得相形見絀。

實時并發(fā)批處理

實時并發(fā)批處理程序需要同時滿足多個并發(fā)請求,且任務處理可能占用數秒時間,任務結束后還需要在同一事物中提交數據,故而并發(fā)批處理不應該鎖定任何數據。整體鎖定的數據越少,數據對于其它進程不可用的時間越少,整個系統(tǒng)就越健壯。

合理選擇樂觀鎖或悲觀鎖來實現(xiàn)邏輯行級鎖是減少物理鎖定的好思路。下面分別對樂觀鎖和悲觀鎖進行介紹。

樂觀鎖: 適用于數據很少發(fā)生鎖競爭的情況。在使用數據庫時具體實現(xiàn)方案為在批處理程序需要用到的數據表的添加一個版本號或者時間戳字段。當應用讀取數據一行數據時,同時也會讀取到此列。且當應用處理完成要更新數據時,會將這個時間戳或版本作為WHERE子句的條件。如果數據庫中該行當前的時間戳字段與WHERE條件一樣,這條數據才會被更新。否則的話就意味著這條數據已經被其它應用修改過了,應用此時應該去嘗試其它策略。

悲觀鎖: 適用于數據會發(fā)生很多競爭的情況,在檢索時需要取得物理或者邏輯鎖。使用數據庫時可以借助數據庫默認的行級鎖來實現(xiàn)。當應用需要更新數據時,首先檢索該行并將鎖標識為已鎖定。這時其它應用嘗試檢索相同數據時會發(fā)生邏輯失敗。直到應用將數據更新完成,鎖標志才會被釋放,其它應用才能重新獲取數據。使用悲觀鎖有兩點情況需要注意:1.在鎖的鎖定和釋放的時間范圍內,應當保證數據的完整性。2. 應當對鎖設置超時機制。

上述知識尤其適用于高并發(fā)程序。一般情況下,樂觀鎖適用于實時處理應用,而互斥鎖在批處理應用中能夠大展拳腳。無論具體使用哪種鎖,其根本目的都是為了保證數據的安全。

不過這些鎖只能對單條數據定位鎖定。當需要對一組數據進行鎖定時,你所面臨的最大的挑戰(zhàn)是死鎖的發(fā)生。怎么避免呢?有了邏輯鎖,或許可以再設計一個邏輯鎖管理器,管理器應該是一致的、非死鎖的且應該能理解你想保護的數據組。邏輯鎖管理器常常有自己的一張自己的表,如此便能提供鎖管理、競爭報告、超時機制以及其它用戶關注的功能。

并行處理

并行批處理的意思是多個批處理應用或任務并行工作,從而減少整體處理時間。 如果多個應用間沒有共享同一個文件、數據庫表或者索引空間,多個應用并行處理,各自只關注自己的數據,其間沒有數據沖突,也不會發(fā)生什么問題。當應用間有共享資源時,一般情況我們會通過自定義數據分片策略來決定每個應用應該去處理哪些數據。在這里引入另一個新思路,數據管理表。數據管理表是一個維護數據相互依賴性的管理模型,它記錄者每行可共享資源以及正在被使用與否,如此批處理程序就能知道自己可以訪問哪些共享資源。

解決了數據訪問方面的問題,可以配合使用多線程來實現(xiàn)對數據的并行處理。大型機環(huán)境下CPU資源豐富,能夠保證每個處理任務都能分配到足夠的cpu時間片,并行作業(yè)處理技術也相對成熟。

再者,我們需要考慮并行處理資源的高可用和負載均衡問題。這些可能用到的技術有連接池、緩存等等。最后需要注意,超大的并行處理中數據管理表本身可能會成為資源瓶頸。

關于

示例源碼

Spring Cloud Task learning 的 task-demo-with-datasource 子項目

后記

Spring Cloud Task是一個優(yōu)秀的項目,但是我找遍網絡,也難以找出系統(tǒng)的、準確的中文相關文檔。本系列文章以保證對Spring Cloud Task相關概念和設計理解的正確性為標準,盡量采用通俗易懂的語言,希望能給各位帶來一些便捷。

本文內容主要是對 Spring Cloud Task 1.2.2-RELEASE 官方文檔的翻譯,不過作者水平有限,有不盡然的地方敬請指出。本項目和文檔中所用的內容僅供學習和研究之用,轉載或引用時請指明出處。如果你對文檔有疑問或問題,請在項目中給我留言或發(fā)email到
weiwei02@vip.qq.com 我的github:
https://github.com/weiwei02/ 我相信技術能夠改變世界 。

鏈接

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容