spring batch框架主要應(yīng)用于批處理數(shù)據(jù)量較大的后臺(tái)業(yè)務(wù),使用這個(gè)框架能夠更靈活司抱,使用各種姿勢(shì)對(duì)數(shù)據(jù)進(jìn)行花樣的操作莉炉,但是數(shù)據(jù)量到達(dá)千萬(wàn)級(jí)別之后驻呐,單機(jī)的處理任務(wù)效率明顯下滑,并行和分區(qū)就是面對(duì)這個(gè)問(wèn)題的靈丹妙藥践磅。
通過(guò)查閱中文官網(wǎng)单刁,對(duì)Spring Bacth有了更深層次的理解,強(qiáng)裂推薦府适,文檔寫(xiě)的真心不錯(cuò)羔飞,對(duì)于多種分布式實(shí)現(xiàn)提供了很好思路。
https://www.bookstack.cn/read/SpringBatchReferenceCN/13_integration-README.md
首先來(lái)了解并行和分區(qū):
什么時(shí)候使用并行檐春,多個(gè)任務(wù)不使用同一個(gè)文件逻淌,數(shù)據(jù)表,索引空間時(shí)可以使用并行疟暖,這很簡(jiǎn)單卡儒。
什么時(shí)候使用分區(qū),如果確實(shí)存在共享和競(jìng)爭(zhēng)俐巴,那么這個(gè)服務(wù)就應(yīng)該使用分區(qū)數(shù)據(jù)來(lái)實(shí)現(xiàn)朋贬,另一種選擇是使用控制表來(lái)構(gòu)建一個(gè)架構(gòu)模塊以維護(hù)他們之間的相互依賴(lài)關(guān)系,控制表應(yīng)該為每個(gè)共享資源分配一行記錄窜骄,不管這些資源是否被某個(gè)程序所使用锦募,執(zhí)行并行作業(yè)的批處理架構(gòu)或程序隨后將查詢(xún)這個(gè)控制表,來(lái)確定是否可以訪(fǎng)問(wèn)所需的資源邻遏。
工作中值得一探究竟是就是Spring Batch的分區(qū)糠亩,分區(qū)又分為本地分區(qū)和遠(yuǎn)程分區(qū)。我個(gè)人理解這本地和遠(yuǎn)程的分別在于:
本地分區(qū)准验,一個(gè)完整的reader赎线,processor,writer執(zhí)行步驟step被切割成多線(xiàn)程同時(shí)執(zhí)行
遠(yuǎn)程分區(qū):一個(gè)完整的reader糊饱,processor垂寥,writer執(zhí)行步驟step被切割后分發(fā)到多節(jié)點(diǎn)執(zhí)行
先從比較簡(jiǎn)單的本地分區(qū)上手。
本地分區(qū):
通過(guò)查看spring batch官方文檔,了解到分區(qū)的核心思想是master-slave:
把一個(gè)步驟滞项,拆分成多個(gè)步驟執(zhí)行:
上代碼進(jìn)行解析狭归,step步驟所需的reader,processor文判,writer
1过椎、本文讀取數(shù)據(jù)的方式,使用的是框架提供的API實(shí)現(xiàn)數(shù)據(jù)庫(kù)分頁(yè)讀取MybatisPagingItemReader戏仓,工作中常用ItemReader自定義實(shí)現(xiàn)
2疚宇、自定義處理類(lèi)實(shí)現(xiàn)ItemProcessor
3、文件寫(xiě)入赏殃,使用框架自帶的API實(shí)現(xiàn)寫(xiě)入csv文件敷待,F(xiàn)latFileItemWriter,工作中常用ItemWriter自定義實(shí)現(xiàn)
4仁热、啟動(dòng)類(lèi)代碼實(shí)現(xiàn)
5讼撒、本地分區(qū)分割器實(shí)現(xiàn)
執(zhí)行分區(qū)效果如下:
文件個(gè)數(shù)對(duì)應(yīng)分區(qū)線(xiàn)程數(shù),由參數(shù)gridSize決定股耽,本文gridSize=10根盒,對(duì)應(yīng)生成10個(gè)文件
以上實(shí)現(xiàn)的是單節(jié)點(diǎn)多線(xiàn)程處理文件,但只能一定限度上提升批處理的執(zhí)行效率物蝙,對(duì)于千萬(wàn)級(jí)的數(shù)據(jù)處理還遠(yuǎn)遠(yuǎn)不夠炎滞,如過(guò)能做到多節(jié)點(diǎn)多線(xiàn)程才是真正能夠更好提升效率的解決方法,這就是接下來(lái)要說(shuō)的遠(yuǎn)程分區(qū)诬乞。通過(guò)看完中文官方文檔册赛,發(fā)現(xiàn)真正想實(shí)現(xiàn)遠(yuǎn)程分區(qū)的代碼實(shí)現(xiàn),過(guò)分復(fù)雜震嫉,并非是通過(guò)少量的偽代碼就能實(shí)現(xiàn)功能森瘪,所以本文著重在于提供遠(yuǎn)程分區(qū)的一種實(shí)現(xiàn)思路,并不拓展開(kāi)講票堵。
想明白遠(yuǎn)程分區(qū)就必須以深刻理解以下幾個(gè)組件為前提扼睬,為什么呢,因?yàn)楸镜胤謪^(qū)可以直接使用框架自己帶實(shí)現(xiàn)悴势,僅僅需要去實(shí)現(xiàn)Partitioner接口即可窗宇,但是遠(yuǎn)程分區(qū)涉及多節(jié)點(diǎn)之間的通信,往往需要自定義實(shí)現(xiàn):
1特纤、遠(yuǎn)程分區(qū)處理器(PartitionHandler)军俊,PartitionHandler組件知道遠(yuǎn)程網(wǎng)格環(huán)境的組織結(jié)構(gòu)。 它可以發(fā)送step的上下文StepExecution請(qǐng)求給遠(yuǎn)端Steps,采用某種具體的數(shù)據(jù)格式捧存,通過(guò)自定義實(shí)PartitionHandler接口粪躬,實(shí)現(xiàn)消息的遠(yuǎn)程分發(fā)担败,PartitionHandler接口可以有各種結(jié)構(gòu)的實(shí)現(xiàn)類(lèi): 如RMI遠(yuǎn)程方法調(diào)用,EJB遠(yuǎn)程調(diào)用,自定義web服務(wù)、JMS镰官、Java Spaces, 共享內(nèi)存網(wǎng)格(如Terracotta或Coherence)提前、網(wǎng)格執(zhí)行結(jié)構(gòu)(如GridGain)。不論是哪一種選型都是為了實(shí)現(xiàn)網(wǎng)絡(luò)通信朋魔。
2岖研、分割器卿操,Partitioner警检,分割器在本地分區(qū)也同樣會(huì)使用,上面有相關(guān)代碼貼圖害淤,它的職責(zé)就是為新的step實(shí)例生成執(zhí)行環(huán)境(contexts),作為輸入?yún)?shù)
3扇雕、各個(gè)從節(jié)點(diǎn)接收到分區(qū)的消息,將輸入數(shù)據(jù)綁定到 Steps窥摄,并立即執(zhí)行镶奉,將實(shí)現(xiàn)多節(jié)點(diǎn)處理文件