之前寫過關(guān)于基于SpringBatch框架來實(shí)現(xiàn)批量的文章,有些同學(xué)反應(yīng)希望寫寫關(guān)于批量設(shè)計(jì)的文章,畢竟筆者以前也在國有大銀行寫過3年的后臺OLAP批量系統(tǒng),在批量程序方面還是掉過很多坑琼富,同時也學(xué)到了很多批量優(yōu)化方面的經(jīng)驗(yàn),本篇文章就是總結(jié)了我自己批量的經(jīng)驗(yàn)和原先行里總結(jié)的一些批量設(shè)計(jì)經(jīng)驗(yàn)啊送,以前我們批量都是使用大量的存儲過程來實(shí)現(xiàn)功能,使用存儲過程的問題就在于擴(kuò)展性非常差欣孤,對某個數(shù)據(jù)庫的依賴非常高馋没,工作中會遇到各種因?yàn)閿?shù)據(jù)庫產(chǎn)品導(dǎo)致的bug,對程序員SQL要求非常高降传,優(yōu)秀的SQL和爛SQL性能可能會差幾十倍篷朵,所以目前除了一些傳統(tǒng)公司還在使用老式的存儲過程來實(shí)現(xiàn)批量,大部分互聯(lián)網(wǎng)公司的批量都已經(jīng)改為使用一些類似Springbatch的框架,通過這樣的框架可以減少很多開發(fā)工作声旺,而且對于一般能夠?qū)慾ava的同學(xué)都可以去寫批量了笔链,但是做聯(lián)機(jī)和做批量在設(shè)計(jì)思想上還是有很大差別,本文就給大家梳理下批量設(shè)計(jì)思路腮猖。文章開頭說下批量的設(shè)計(jì)核心思想就是“減少IO”鉴扫,這是所有批量系統(tǒng)優(yōu)化性能的核心思路,做批量的同學(xué)請牢記這一條8抗弧a7痢!
1. 批量系統(tǒng)使用場景
- 定期提交批處理任務(wù)
- 并發(fā)批處理:并行執(zhí)行任務(wù)
- 分階段谍椅,企業(yè)消息驅(qū)動處理
- 高并發(fā)批處理任務(wù)
- 失敗后手動或定時重啟
- 按順序處理任務(wù)依賴(使用工作流驅(qū)動的批處理插件)
- 局部處理:跳過記錄(例如在回滾時)
- 完整的批處理事務(wù):因?yàn)榭赡苡行?shù)據(jù)量的批處理或存在存儲過程/腳本
2. 批量設(shè)計(jì)原則
- 批處理架構(gòu)通常會影響在線服務(wù)的架構(gòu),反之亦然。設(shè)計(jì)架構(gòu)和環(huán)境時請盡可能將聯(lián)機(jī)數(shù)據(jù)資源和批量數(shù)據(jù)資源分開古话。
- 盡可能的簡化,避免在單個批處理應(yīng)用中構(gòu)建復(fù)雜的邏輯結(jié)構(gòu)雏吭。
- 盡可能在數(shù)據(jù)存放的地方處理這些數(shù)據(jù),反之亦然(即各自負(fù)責(zé)處理自己的數(shù)據(jù))。
- 盡可能少的使用系統(tǒng)資源,尤其是I/O陪踩。盡可能多地在內(nèi)存中執(zhí)行大部分操作杖们。
- 審查應(yīng)用程序I/O(分析SQL語句)以避免不必要的物理I/O。特別是以下四個常見的缺陷需要避免:
- 在每個事務(wù)中都將(所有并不需要的)數(shù)據(jù)讀取,并緩存起來;
- 多次讀取/查詢同一事務(wù)中已經(jīng)讀取過的數(shù)據(jù);
- 引起不必要的表或索引掃描;
- 在SQL語句的WHERE子句中不指定過濾條件肩狂。
- 在同一個批處理不要做兩次一樣的事摘完。例如,如果你需要報表的數(shù)據(jù)匯總,請?jiān)谔幚砻恳粭l記錄時使用增量來存儲,盡可能不要再去遍歷一次同樣的數(shù)據(jù)。
- 在批處理程序開始時就分配足夠的內(nèi)存,以避免運(yùn)行過程中再執(zhí)行耗時的內(nèi)存分配傻谁。
- 總是將數(shù)據(jù)完整性假定為最壞情況孝治。插入適當(dāng)?shù)臋z查和數(shù)據(jù)校驗(yàn)以保持?jǐn)?shù)據(jù)完整性(integrity)。
- 如有可能,請為內(nèi)部校驗(yàn)實(shí)現(xiàn)checksum审磁。例如,平面文件應(yīng)該有一條結(jié)尾記錄,說明文件中的總記錄數(shù)和關(guān)鍵字段的集合谈飒。
- 盡可能早地在模擬生產(chǎn)環(huán)境下使用真實(shí)的數(shù)據(jù)量,進(jìn)行計(jì)劃和執(zhí)行壓力測試态蒂。
- 在大型批處理系統(tǒng)中,備份會是一個很大的挑戰(zhàn),特別是 7x24小時不間斷的在線服務(wù)系統(tǒng)杭措。數(shù)據(jù)庫備份通常在設(shè)計(jì)時就考慮好了,但是文件備份也應(yīng)該提升到同養(yǎng)的重要程度。如果系統(tǒng)依賴于文本文件,文件備份程序不僅要正確設(shè)置和形成文檔,還要定期進(jìn)行測試钾恢。
3. 批量設(shè)計(jì)策略
為了輔助批處理系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)手素、應(yīng)該通過結(jié)構(gòu)示意圖和代碼實(shí)例的形式為設(shè)計(jì)師和程序員提供基礎(chǔ)的批處理程序構(gòu)建模塊和以及處理模式. 在設(shè)計(jì)批處理Job時,應(yīng)該將業(yè)務(wù)邏輯分解成一系列的步驟,使每個步驟都可以利用以下的標(biāo)準(zhǔn)構(gòu)建模塊來實(shí)現(xiàn):
- 轉(zhuǎn)換程序(Conversion Applications): 由外部系統(tǒng)提供或需要寫入到外部系統(tǒng)的各種類型的文件,我們都需要為其創(chuàng)建一個
- 轉(zhuǎn)換程序, 用來將所提供的事務(wù)記錄轉(zhuǎn)換成符合要求的標(biāo)準(zhǔn)格式.這種類型的批處理程序可以部分或全部由轉(zhuǎn)換工具模塊
- 驗(yàn)證程序(Validation Applications): 驗(yàn)證程序確保所有輸入/輸出記錄都是正確和一致的.驗(yàn)證通常基于文件頭和結(jié)尾信息,
- 校驗(yàn)和(checksums)以及記錄級別的交叉驗(yàn)證算法.
- 提取程序(Extract Applications): 這種程序從數(shù)據(jù)庫或輸入文件讀取一堆記錄,根據(jù)預(yù)定義的規(guī)則選取記錄,并將選取的記錄
- 寫入到輸出文件.
- 提取/更新程序(Extract/Update Applications): 這種程序從數(shù)據(jù)庫或輸入文件讀取記錄,并將輸入的每條記錄都更新到數(shù)據(jù)庫或記錄到輸出文件.
- 處理和更新程序(Processing and Updating Applications): 這種程序?qū)?提取或驗(yàn)證程序 傳過來的輸入事務(wù)記錄進(jìn)行處理.這些處理通常包括 從數(shù)據(jù)庫讀取數(shù)據(jù),有可能更新數(shù)據(jù)庫,并創(chuàng)建輸出記錄.
- 輸出/格式化程序(Output/Format Applications): 這種程序從輸入文件中讀取信息,將數(shù)據(jù)重組成為標(biāo)準(zhǔn)格式,并打印到輸出文件,或者傳輸給另一個程序或系統(tǒng).
因?yàn)闃I(yè)務(wù)邏輯不能用上面介紹的這些標(biāo)準(zhǔn)模塊來完成, 所以還需要另外提供一個基本的程序外殼.
除了這些主要的模塊,每個應(yīng)用還可以使用一到多個標(biāo)準(zhǔn)的實(shí)用程序環(huán)節(jié)(standard utility steps),如:
- Sort 排序,排序程序從輸入文件讀取記錄,并根據(jù)記錄中的某個key字段重新排序,然后生成輸出文件. 排序通常由標(biāo)準(zhǔn)的系統(tǒng)實(shí)用程序來執(zhí)行.
- Split 拆分,拆分程序從單個輸入文件中讀取記錄,根據(jù)某個字段的值,將記錄寫入到不同的輸出文件中. 拆分可以自定義或者由參數(shù)驅(qū)動的(parameter-driven)系統(tǒng)實(shí)用程序來執(zhí)行.
- Merge 合并,合并程序從多個輸入文件讀取記錄,并將組合后的數(shù)據(jù)寫入到單個輸出文件中. 合并可以自定義或者由參數(shù)驅(qū)動的(parameter-driven)系統(tǒng)實(shí)用程序來執(zhí)行.
批處理程序也可以根據(jù)輸入來源分類:
- 數(shù)據(jù)庫驅(qū)動(Database-driven)的應(yīng)用程序, 由從數(shù)據(jù)庫中獲取的行或值驅(qū)動.
- 文件驅(qū)動(File-driven)的應(yīng)用程序,是由從文件中獲取的值或記錄驅(qū)動的.
- 消息驅(qū)動(Message-driven)的應(yīng)用程序由從消息隊(duì)列中檢索到的消息驅(qū)動.
所有批處理系統(tǒng)的基礎(chǔ)都是處理策略.影響策略選擇的因素包括: 預(yù)估的批處理系統(tǒng)容量, 在線并發(fā)或與另一個批處理系統(tǒng)的并發(fā)量, 可用的批處理時間窗口(隨著越來越多的企業(yè)想要全天候(7x24小時)運(yùn)轉(zhuǎn),所以基本上沒有明確的批處理窗口).
典型的批處理選項(xiàng)包括:
- 在一個批處理窗口中執(zhí)行常規(guī)離線批處理
- 并發(fā)批處理/在線處理
- 同一時刻有許多不同的批處理在并行執(zhí)行
- 分區(qū)(即同一時刻,有多個實(shí)例在處理同一個job)
- 上面這些的組合
上面列表中的順序代表了批處理實(shí)現(xiàn)復(fù)雜性的排序,在同一個批處理窗口的處理最簡單,而分區(qū)實(shí)現(xiàn)最復(fù)雜,分區(qū)實(shí)現(xiàn)雖然并發(fā)性能高能夠充分利用IO資源瘩蚪,但是缺點(diǎn)是對數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)和批量設(shè)計(jì)要求很高泉懦,弄不好就會出很多多線程或資源死鎖問題導(dǎo)致批量加工數(shù)據(jù)錯誤或中斷,所以如果數(shù)據(jù)量不是非常巨大就不要用分區(qū)批量實(shí)現(xiàn)方案了募舟,當(dāng)你數(shù)據(jù)量足夠大了祠斧,并且自己已經(jīng)能力提高并能夠充分理解批量精髓后,自然就會靈活使用批量分區(qū)實(shí)現(xiàn)方案了.
總結(jié)
本文主要是從各個角度講訴了下批量設(shè)計(jì)的思路拱礁,真的只是思路琢锋,估計(jì)很多同學(xué)看完了很多條tips都不知道在說啥或者不知道如何實(shí)踐辕漂,如果具體展開講這些tips要寫太多字了,本人比較懶不想寫了吴超,如果感興趣的人比較多后續(xù)可能會對于大家感興趣的一些tips展開講講后面的故事钉嘹。