金石聲 李玨
[摘要]本省自動(dòng)氣象觀測(cè)系統(tǒng)根據(jù)觀測(cè)要素的不同分為單雨量系統(tǒng)、兩要素系統(tǒng)和六要素系統(tǒng)。三類觀測(cè)系統(tǒng)分別接收各自站點(diǎn)采集的報(bào)文進(jìn)行解碼入庫(kù),同時(shí)通過FTP將數(shù)據(jù)報(bào)文發(fā)送到綜合處理系統(tǒng)再次進(jìn)行解碼入庫(kù)。這樣的處理流程不僅增加網(wǎng)絡(luò)負(fù)擔(dān),還進(jìn)行了重復(fù)的解碼工作,資源利用率低。為此本文采用基于Spring Batch的框架,定時(shí)對(duì)三個(gè)不同觀測(cè)系統(tǒng)的后臺(tái)數(shù)據(jù)庫(kù)的實(shí)時(shí)數(shù)據(jù)向綜合處理系統(tǒng)的數(shù)據(jù)庫(kù)進(jìn)行遷移。該流程采用數(shù)據(jù)分區(qū)技術(shù),多線程并行處理,在減少了對(duì)網(wǎng)絡(luò)帶寬的占用量的同時(shí),降低了各個(gè)系統(tǒng)CPU使用量,提高了工作效率。
[關(guān)鍵詞]Spring Batch 數(shù)據(jù)遷移 數(shù)據(jù)分區(qū) 多線程
引言
本省的氣象自動(dòng)站綜合系統(tǒng)需要對(duì)已經(jīng)進(jìn)行過解碼入庫(kù)的單雨量、兩要素和六要素觀測(cè)報(bào)文進(jìn)行集中,再次進(jìn)行解碼后插入綜合數(shù)據(jù)庫(kù),并以此對(duì)外提供服務(wù)。這樣的處理流程不僅在資源利用、網(wǎng)絡(luò)帶寬的占用都產(chǎn)生了很大的浪費(fèi)。
通過分別讀取單雨量、兩要素和六要素的數(shù)據(jù)庫(kù),對(duì)已經(jīng)入庫(kù)的數(shù)據(jù)進(jìn)行準(zhǔn)實(shí)時(shí)的遷移,在降低網(wǎng)絡(luò)帶寬占用的同時(shí),也能降低綜合處理系統(tǒng)的資源占用。但是基于大量的數(shù)據(jù)讀寫,且重復(fù)性高工作,傳統(tǒng)的編程方式處理不僅繁瑣,且維護(hù)性低。已經(jīng)Spring Batch的出現(xiàn)無(wú)疑是解決這種問題的一種有效工具。由于目前已經(jīng)有比較成熟的開源框架支持批處理的需求,所以本方案擬選用開源框架Spring Batch。這樣可以借助開源框架比較成熟的代碼,減少研究的難度,加強(qiáng)框架擴(kuò)展性,減少研發(fā)周期,加快實(shí)際應(yīng)用進(jìn)度,并且保證程序的穩(wěn)定性。
一、Spring Batch簡(jiǎn)介
Spring batch是Spring的一個(gè)子項(xiàng)目,由Spring Source與Accenture(埃森哲)合作開發(fā)的批處理框架。Springhatch對(duì)編寫批處理程序本身的特性進(jìn)行了抽象。將批處理程序分為Job和Job Step兩個(gè)部分,將處理環(huán)節(jié)定義為數(shù)據(jù)讀、數(shù)據(jù)處理和數(shù)據(jù)寫三個(gè)步驟。提供Job Repository來(lái)存儲(chǔ)Job執(zhí)行期間的元數(shù)據(jù),可以在處理大量的數(shù)據(jù)時(shí),提供日志記錄/跟蹤,事務(wù)管理,處理統(tǒng)計(jì),資源管理等特性。此外,還提供了分區(qū)技術(shù)采用多線程方式并行處理作業(yè)。
二、系統(tǒng)總體架構(gòu)設(shè)計(jì)
考慮到系統(tǒng)可能出現(xiàn)的單店故障,為減少處理這類故障的開發(fā)難度。開發(fā)三個(gè)獨(dú)立的程序分別對(duì)單雨量、兩要素和六要素三個(gè)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行遷移。本文以遷移兩要素?cái)?shù)據(jù)為例進(jìn)行介紹。
Spring bath的核心思想是將讀取到的數(shù)據(jù)轉(zhuǎn)化為Java對(duì)象,然后對(duì)對(duì)象進(jìn)行操作。首先需要根據(jù)表中的字段建立相應(yīng)的實(shí)體類,然后Spring Batch把從源數(shù)據(jù)庫(kù)中讀取的每條數(shù)據(jù)映射為對(duì)應(yīng)的Java對(duì)象,由于本文只是對(duì)數(shù)據(jù)進(jìn)行遷移,不需要對(duì)對(duì)象進(jìn)行處理,所以將Java對(duì)象的值通過寫步驟寫入目標(biāo)數(shù)據(jù)庫(kù)。實(shí)際應(yīng)用中只關(guān)注兩張表中存儲(chǔ)的數(shù)據(jù):小時(shí)數(shù)據(jù)表(tabHourData)和分鐘數(shù)據(jù)表(tabMinuteData),由于遷移這兩張表沒有具體的先后順序,將這兩部分工作并行處理。
Spring batch提供了XML方式進(jìn)行業(yè)務(wù)流程配置,通過spht元素來(lái)提供并行作業(yè)流的定義,通過task-execution屬性來(lái)定義執(zhí)行的線程池,從而提高Job的執(zhí)行效率。其中要定義兩個(gè)不同的作業(yè)步(transferHottrTab_step和transferMinuteTab_step),每個(gè)作業(yè)步下定義了兩個(gè)具體的子Job分別來(lái)完成對(duì)兩張數(shù)據(jù)表的數(shù)據(jù)遷移。子Job中又分別定義了讀、寫兩個(gè)過程來(lái)完成數(shù)據(jù)的遷移。其中為了保證執(zhí)行效率定義了commit-interval,指定了從數(shù)據(jù)庫(kù)讀入1000條數(shù)據(jù)后進(jìn)行一次寫操作,這樣既減少了10的訪問,也提高了寫入效率。關(guān)鍵配置如下(以transferHottrTab_Job為例):
數(shù)據(jù)遷移中讀取的數(shù)據(jù)量較大,為了高時(shí)效的完成讀取作業(yè),讀取數(shù)據(jù)的任務(wù)進(jìn)行分區(qū),每個(gè)分區(qū)交給不同的線程處理。該模式的優(yōu)點(diǎn)在于分區(qū)中每一個(gè)元素的處理都能像一個(gè)普通Spring Batch任務(wù)的單步一樣運(yùn)行。具體關(guān)系圖如3-1,將需要讀取的目標(biāo)數(shù)據(jù)分為了3個(gè)分區(qū),每一個(gè)分區(qū)都有一個(gè)執(zhí)行上下文Execution Context,StepExecutionSplitter根據(jù)不同的上下文生成作業(yè)步執(zhí)行器,然后交給PartitionHandler來(lái)處理。應(yīng)為Spring Batch默認(rèn)實(shí)現(xiàn)了StepExecutionSplitter以及PartitionHandler。開發(fā)過程中原則上只需要實(shí)現(xiàn)自己分區(qū)邏輯partitioner即可。
小時(shí)表和分鐘表都含有對(duì)數(shù)據(jù)觀測(cè)時(shí)間的字段,因此對(duì)該字段進(jìn)行分區(qū),可以實(shí)現(xiàn)分區(qū)策略的共享。具體配置如下:
class=”com.xxzx.partition.DBpartition”>
作業(yè)中用于對(duì)數(shù)據(jù)庫(kù)進(jìn)行分區(qū)的DBpartition了實(shí)現(xiàn)了Spring Btach的Partitioner接口,定義具體的分區(qū)策略,將數(shù)據(jù)查詢的時(shí)間進(jìn)行切片,然后寫入Step的執(zhí)行上下文,關(guān)鍵代碼如下:
while(start<=max){
ExecutionContext context=new ExecutionContext();
if(end>=max){
end=max;
}
context.putInt(_STARTTIME,start);
context.putInt(_ENDTIME,end);
start+=targetSize;
end+=targetSize;
resultMap.put(“partition”+(number++),context);
通過把每次任務(wù)中需要查詢的時(shí)間段根據(jù)targetSize的值進(jìn)行切片,意味著數(shù)據(jù)片段分配到不同的作業(yè)步中。并將_ENDTIME和_STARTYIME寫入Step的執(zhí)行上下文(ExecutionContext)。然后在讀取數(shù)據(jù)的階段通過讀取Step執(zhí)行上下文獲取每個(gè)片段的統(tǒng)計(jì)時(shí)段。
3.2定時(shí)調(diào)度
由于Spring Batch本身并不是一個(gè)定時(shí)的調(diào)度框架。本文采用Spring本身提供的一個(gè)輕量級(jí)的調(diào)度框架SpringScheduler來(lái)實(shí)現(xiàn)定時(shí)調(diào)度任務(wù)。關(guān)鍵配置如下:
其中采用cron表達(dá)式實(shí)現(xiàn)每5分鐘調(diào)度一次作業(yè),并且在schedulerLauncher中完成對(duì)啟動(dòng)具體作業(yè)的配置。這樣便將Spring Scheduler和Spring Batch結(jié)合起來(lái)完成數(shù)據(jù)遷移任務(wù)。
四、結(jié)論
本文基于Spring Batch框架采用數(shù)據(jù)分區(qū)技術(shù)、多線程并行處理的方法開發(fā)了一個(gè)數(shù)據(jù)庫(kù)遷移系統(tǒng)完成批量數(shù)據(jù)的遷移工作,并結(jié)合Spring Scheduler實(shí)現(xiàn)了批處理任務(wù)的定時(shí)調(diào)度。在實(shí)際工作中優(yōu)化了本省自動(dòng)站數(shù)據(jù)處理系統(tǒng)中帶寬占用率高、系統(tǒng)資源浪費(fèi)的現(xiàn)狀。實(shí)際工作中對(duì)本省自動(dòng)站數(shù)量?jī)梢刈詣?dòng)站進(jìn)行了測(cè)試,完成3260條數(shù)據(jù)的遷移的時(shí)間不超過30秒。完全滿足實(shí)際業(yè)務(wù)中的需求。