任務和調度:理解批量處理的關鍵設計

ss5723 8年前發布 | 34K 次閱讀 設計 分布式/云計算/大數據

一、背景

1.1.什么是批量處理

1.2.批量處理擁有廣泛的使用場景

1.3.批量處理需要良好的架構設計

二、批量處理中的關鍵設計

2.1從SpringBatch看批量任務設計模式

2.2任務調度設計

三、總結

一、背景

 

1.1.什么是批量處理

維基百科給批量處理的定義是指在沒有人工干預的情況下,由一個計算機程序基于一份批量的輸入執行一系列的任務的一種處理模式。這句話可能有點拗口,簡單來說,批量處理是一種處理模式,這種模式在進行數據處理時,輸入數據一般包含多條,處理過程中一般沒有人工交互。而另一種主流的處理模式,聯機處理與批量處理的最主要區別就是,聯機處理中一般一條輸入數據就產生一次處理過程,然后直接將結果反饋給調用方。批量處理曾經在早期的計算機處理模式中占據統治地位。

1.2.批量處理擁有廣泛的使用場景

我們先來看下批量處理的特點:

  • 批量處理單次執行就可以處理大量數據,而聯機處理中單次執行一般只能處理少量數據。

  • 批量處理每次需要處理大量的數據,執行時間將較長,而聯機系統需要實時、快速響應調用方的請求。

  • 批量處理不需要維持與調用方的連接,執行結果一般通過報告等形式通知調用方,資源利用率比較高。

  • 批量處理可以選擇將處理時間放在計算資源不那么緊張的時間段,更好的利用系統資源。

從批量處理的特點我們可以看到,在實時性、交互性要求不高,同時待處理的數據量比較大的場景下,就可以考慮使用批量處理的模式。而實際各種業務系統中通常都會存在大量適合使用或者正在使用批量處理的場景,常見的如銀行的對賬、網銀的批量待發工資、日志系統中批量備份日志等。我們大家可能都會有從支付寶里提現至銀行卡的經歷,通常提現并不是實時的,支付寶會給你一個deadline,這中間支付寶與銀行之間數據對賬就是采用批量處理完成的。

 

1.3.批量處理需要良好的架構設計

在最簡單的批量處理場景下,我們可以通過編寫腳本,在類Unix系統中通過cron程序定時啟動執行。但是這種模式僅僅適合單機處理的情況,沒有分布式處理的能力,同時也沒有辦法進行統一的監控管理。在實際使用時,可能同時存在數量巨大的批量任務,如何管理與調度這些任務將是個巨大的挑戰。設計良好的批量處理框架可以簡化批量任務開發過程,減少配置時間,提高整體穩定性。筆者曾經參與過某銀行BPM系統批量處理框架的設計,一開始設計比較簡單,在各個服務器部署批量腳本,基于cron執行,通過數據庫進行結果統計,在項目上線初始階段,由于批量任務比較少,所做的工作也比較簡單,該設計能夠基本滿足需求,但是隨著項目上線后,批量任務越來越多,場景越來越復雜(比如需要支持數據庫服務器HA切換時批量任務不重復執行),原有設計已經越來越力不從心,最后只有推倒重新設計,費時又費力,由此可見一個好的批量處理框架設計是多么的重要。本文將通過分析批量處理中的兩個關鍵環節, 結合一些開源的批量處理框架,來聊一聊如何更好地進行批量處理型架構的設計。

 

二、批量處理中的關鍵設計

批量處理中兩個關鍵環節是 批量任務設計 任務調度設計

批量任務設計 :統一規定了作業的定義、編排、執行等過程,良好的作業模型可以隱藏了內部復雜性,簡化具體作業開發難度,更好的支持調度過程。

任務調度設計 :通俗的說調度就是控制作業在什么時候由那些資源(節點、線程等)去執行,同時還包含作業執行失敗后的處理等內容。

2.1從SpringBatch看批量任務設計模式

2.1.1傳統批量作業結構

我們首先來看一下過去幾十年間已經被廣泛使用的批量作業結構:

圖1 批量作業結構

這個架構圖非常簡單,傳遞了批量作業中最重要的幾個領域概念:

  • JobLauncher :該領域對象是Job的啟動器,其作用就是啟動Job。

  • Job :定義,配置批處理任務的領域對象,該對象的作用,是做Step的容器,配置該批處理任務需要的Step,以及他們之間的邏輯關系。

  • Step :定義批處理任務中一個對立的邏輯任務處理單元。基本上的業務邏輯處理代碼都是封裝在Step中的,這種形式定義了一個Step的流程必須是“ItemReader- ItemProcessor(可選)-ItemWriter”。

  • JobRepository :該領域對象會為Job的運行數據提供一種持久化機制,為所有的Job提供CRUD的操作接口,并為所有的操作提供事務支持。

在這種設計模式下,任務的定義執行過程變得非常清晰,使用這只需要關注于每個Step中的具體業務實現即可,通過簡單的配置就能完成任務的設計。

2.1.2. SpringBatch中的任務設計模式:

傳統批量作業結構在好幾代平臺和編程語言中已經被證明為非常合理和有效。著名Java開源批處理框架SpringBatch就是實現了這種作業結構,不過除此之外,SpringBatch還加入了自身一些設計:

圖2 SpringBatch作業模型

上圖展現了SpringBatch中的幾個概念模型:

  • JobInstance :該領域概念和Job的關系與Java中實例和類的關系一樣,Job定義了一個工作流程, JobInstance就是該工作流程的一個具體實例。一個Job可以有多個JobInstance,多個JobInstance之間的區分就要靠另外一個領域概念JobParameters了。

  • JobParameters :是一組可以貫穿整個Job的運行時配置參數。不同的配置將產生不同的JobInstance,如果你是使用相同的JobParameters運行同一個Job,那么這次運行會重用上一次創建的JobInstance。

  • JobExecution :該領域概念表示JobInstance的一次運行,JobInstance運行時可能會成功或者失敗。每一次JobInstance的運行都會產生一個JobExecution。同一個JobInstance(JobParameters相同)可以多次運行,這樣該JobInstance將對應多個Jobexecution。JobExecution記錄了一個JobInstance在一次運行時的發生的所有事情,因此,一個JobExecution需要包含很多的屬性,并且需要持久化,這樣才能很好的支撐Restart等Spring Batch特性。

  • StepExecution : 類似于JobExecution,該領域對象表示Step的一次運行。Step是Job的一部分,因此一個StepExecution會關聯到一個Jobexecution。另外,該對象還會存儲很多與該次StepExecution運行相關的所有數據,因此該對象也有很多的屬性,并且需要持久化以支持一些Spring Batch的特性。

同時,為了提高作業運行時效率, SpringBatch中還同時提供了幾種并行處理方案:

  • 多線程處理 ,一個Step的處理過程可以配置一個包含多個線程資源的線程池處理。

  • 并行Step處理 ,根據任務的特點,可以將任務中的多個不同的Step進行分組,形成多個流,這多個流可以并行處理。

  • Step遠程分片處理 ,下圖為Step遠程分片模型:

圖3 遠程分片模型

   在遠程分片模型中,某一個Step中由Master節點去讀取數據,但是處理的過程,由Master分配給多個Slaves去處理,在這種模型中,Master節點的讀取能力不能成為整個Step的瓶頸。

  • Step分區處理 ,這種模式跟遠程分片處理過程很類似,不同是,分區處理中Master節點不負責讀取數據,而是由該Step中的各個分區獨立去讀取和處理,當然這種模式下如何將數據進行合適的分區很重要,并不是所有Step都適合這種模式去處理。

2.1.3 SpringBatch的不足

可以看到SpringBatch中提供了一套非常完善的批量任務設計模式,但是SpringBatch也有不足的地方:

  • SpringBatch本身不提供調度的能力,調度依賴于quartz,quartz雖然可以進行集群調度作業,一個節點掛了可以將任務漂移給其他節點執行從而避免單點故障,但是不支持分布式作業,一旦達到單機處理極限也會存在問題。

  • SpringBatch中雖然提供了一些并行處理方案,但是分片、多線程這些方案都非常依賴于任務配置,沒有提供一種自動化的機制去靈活地進行資源的調度。

2.2任務調度設計

2.2.1兩種調度模式

常見分布式調度系統在設計上主要有 中心化 和 去中心化 兩種模式:

2.2.1.1. 中心化的調度模式

下圖為中心化的調度模式結構圖:

圖4中心化的調度模型

如上圖所示,在中心化的調度模式下,一般都有一個Leader節點用來負責拉取任務的調度信息,然后向各個Follower節點分派任務,由Follower節點完成任務的執行。同時為了保證整個系統的高可用,Leader節點一般會采取主備模式,當一個Leader節點失效時,備用節點會接管Leader節點工作。

2.2.1.2. 去中心化的調度模式

下面再來看一下去中心化模式:

圖5去中心化的調度模型

在去中心化的調度模式下,沒有調度中心節點這個概念,所有節點都是工作節點,節點之間通過注冊中心進行分布式協調,但是在這種模式下,一般會有一個主節點用于處理一些集中式任務,如分片,清理運行時信息等,并無調度功能,定時調度都是由作業節點自己觸發執行。

下面對比一下兩種調度模式各自的優缺點:

 

中心化

去中心化

實現難度

部署難度

觸發時間統一控制

可以

不可以

觸發延遲

異構語言支持

容易

困難

表1 中心化和去中心化調度比較

2.2.2.   TBSchedule 中的調度設計

TBSchedule是由Taobao開源的一款非常優秀的高性能分布式調度框架,TBSchedule的使用非常廣泛,目前被應用于淘寶、京東、國美、等很多互聯網企業的調度系統。TBSchedule有如下特點:

  • 支持集群、分布式

  • 靈活的任務分片

  • 動態的服務擴容和資源回收

  • 任務監控支持

TBSchedule支持Cluster,可以宿主在多臺服務器多個線程組并行進行任務調度,或者說可以將一個大的任務拆成多個小任務分配到不同的服務器。

TBSchedule的分布式機制是通過Sharding方式實現的,比如可以按所有數據的ID按10取模分片、按月份分片等等,根據不同的需求,不同的場景由客戶端配置分片規則。TBSchedule的宿主服務器可以進行動態擴容和資源回收,這個特點主要是因為它后端依賴的ZooKeeper,這里的ZooKeeper對于TBSchedule來說是一個NoSQL,用于存儲策略、任務、心跳信息數據,它的數據結構類似文件系統的目錄結構,它的節點有臨時節點、持久節點之分。調度引擎上線后,隨著業務量數據量的增多,當前Cluster可能不能滿足目前的處理需求,那么就需要增加服務器數量,一個新的服務器上線后會在ZooKeeper中創建一個代表當前服務器的一個唯一性路徑(臨時節點),并且新上線的服務器會和ZooKeeper保持長連接,當通信斷開后,節點會自動摘除。下圖為TBSchedule的基本結構圖,從圖上可以到,TBSchedule從整體上來說遵循的是去中心化的調度模式,每個節點都可以從ZooKeeper中拉取任務去執行。

圖6 TBSchedule結構圖

TBSchedule提供了兩個核心組件 ScheduleServer 、 TBScheduleManagerFactory。

ScheduleServer即任務處理器,的主要作用是任務和策略的管理、任務采集和執行,由一組工作線程組成,這組工作線程是基于隊列實現的,進行任務抓取和任務處理。每個任務處理器和ZooKeeper有一個心跳通信連接,用于檢測Server的狀態和進行任務動態分配。

調度服務器TBScheduleManagerFactory的主要工作ZooKeeper連接參數配置和ZooKeeper的初始化、調度管理。

TBSchedule中的用戶目標任務是通過實現任務接口實現的,任務接口中包含selectTasks和execute兩個方法,分別對應任務的采集和執行過程。

2.2.3.   TBSchedule 的不足

盡管TBSchedule已經很優秀,尤其是資源調度這塊,但是TBSchedule 也有不足的地方:

  • TBSchedule中對于批量任務開發的指導比較欠缺,這點SpringBatch中做的很好。

  • TBSchedule中任務執行是相互獨立的,而在在實際使用場景中很多任務執行必須依賴于另一個任務,甚至可能多個任務之間都有相互關系,形成任務流這種形式,任務流需要以可視化的方式進行編排和執行時的管理,TBSchedule沒有提供這種能力。

  • 目前TBSchedule中如果上線一個新服務器,需要通過手動的方式去啟動,沒有結合這幾年流行的容器技術,實現服務資源的動態伸縮。

四、總結

隨著計算機技術的發展,在C/S和B/S軟件體系結構中,聯機處理模式已經慢慢成為最主要的數據處理模式,盡管如此,批量處理作為一種古老的處理模式,任然以其高吞吐、高性能的特性占據著一席之地。

本文從批量處理的概念出發,結合開源批量框架SpringBatch和TBSchedule,簡要介紹了批處理型服務架構的設計。可以看到目前雖然有很多已經被廣泛使用的批量處理框架,但是還是存在著很多不完善的地方。

冰凍三尺非一日之寒,任何事物的發展和完善都不是一朝一夕的事,對于批量處理框架設計而言也是如此。 我們自己在設計時可以考慮站在巨人的肩膀上,借鑒成熟的框架設計,同時結合具體的業務場景,加入符合需求的功能特性,完善出功能強大、運行穩定和易于使用的批量處理框架。

 

來自:http://mp.weixin.qq.com/s?__biz=MzI5MDEzMzg5Nw==&mid=2660393382&idx=1&sn=05b3924639374a16b1cf2660658cfc1e&scene=2&srcid=0822QUrxOT8v2IpTJSqgYoFU&from=timeline&isappinstalled=0

 

 本文由用戶 ss5723 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!