大數據平台作業調度系統詳解-理論篇


大數據平台作業調度系統詳解-理論篇

 

  第一篇,先來討論一下大數據開發平台的核心組件之一:作業調度系統。

  作業調度系統是一個相對復雜的系統,涉及的內容繁雜,針對的場景多種多樣,實現的方案千差萬別,是一個需要理論和實踐並重的系統。

本文重點談理論,會先從大的場景划分的角度對市面上的各種調度系統進行分類討論,然后再針對具體的作業調度系統,探討一下各自的架構流派和實現方案,並簡單分析一下各自的優缺點。希望能讓大家對作業調度系統要做什么,該怎么做,有一個大致的了解

1、那些調度系統們

調度系統,更確切地說:

  作業調度系統(Job Scheduler)

  工作流調度系統(workflow Scheduler)

除了Crontab,Quartz這類偏單機的定時調度程序/庫。開源的分布式作業調度系統也有很多,比較知名的比如:oozie,azkaban,chronos,zeus等等,此外,還有包括阿里的TBSchedule,SchedulerX,騰訊的Lhotse,當當的elastic-job,唯品會的Saturn等等

可以說,幾乎每家稍微有點規模的數據平台團隊,都會有自己的調度系統實現方案,要不然自研,要不然在開源的基礎上進行一些封裝和改造(比如很多公司采取了封裝oozie的方式)。

  1.1、作業調度系統和資源調度系統(或者集群調度系統)的區別

  后者的典型代表比如:Yarn/Mesos/Omega/Borg,還有阿里的伏羲,騰訊的蓋婭(Gaia),百度的Normandy等等。

資源調度系統,它的工作重點是底層物理資源的分配管理,目標是最大化的利用集群機器的CPU/磁盤/網絡等硬件資源,所調配和處理的往往是與業務邏輯沒有直接關聯的通用的程序進程這樣的對象。

  作業調度系統,關注的首要重點是在正確的時間點啟動正確的作業,確保作業按照正確的依賴關系及時准確的執行。資源的利用率通常不是第一關注要點,業務流程的正確性才是最重要的。

  作業調度系統有時也會考慮負載均衡問題,但保證負載均衡更多的是為了系統自身的健壯性,而資源的合理利用,作為一個可以優化的點,往往依托底層的資源調度系統來實現。

  那么,為什么市面上會存在這么多的作業調度系統項目,作業調度系統為什么沒有像Hdfs/Hive/HBase之類的組件,形成一個相對標准化的解決方案呢?歸根到底,還是由作業調度系統的業務復雜性決定的。

  一個成熟易用,便於管理和維護的作業調度系統,需要和大量的周邊組件對接,不僅包括各種存儲計算框架,還可要處理或使用到包括:血緣管理,權限控制負載流控,監控報警,質量分析等各種服務或事務。

  市面上的各種開源的作業調度系統,要不然就是在某些環節/功能上是缺失的,使用和運維的代價很高,需要大量二次開發;要不然就是只針對特定的業務場景,形態簡單,缺乏靈活性;又或者在一些功能環節上是封閉自成體系的,很難和外部系統進行對接。

  那么,理想中,完備的作業調度系統,到底都要處理哪些事務呢?要做好這些事務都有哪些困難要克服,有哪些方案可以選擇,市面上的開源調度系統項目又是如何應對這些問題的,容我和大家一起來探討一下。

 

2、兩大類作業調度系統

首先,讓我來對作業調度系統進行一下大的分類。市面上的作業調度系統,根據實際的功能定位,主要分為兩大類方向:

  (1)、定時分片類作業調度系統

  (2)、DAG工作流類作業調度系統

這兩類系統的架構和功能實現通常存在很大的差異。所以下文先做一下兩者的簡單的比較。

 

2.1、定時分片類作業調度系

  定時分片類系統的方向,重點定位於任務的分片執行場景,這類系統的代表包括:TBSchedule,SchedulerX,Elastic-job, Saturn。我司自研的Vacuum也是這樣的系統。

  這種功能定位的作業調度系統,其最早的需要來源和出發點往往是做一個分布式的Crontab/Quartz。

  一開始各個業務方八仙過海,自己玩自己的單機定時任務,然后,隨着業務的增長,各種定時任務越來越多,分散管理的代價越來越高。再加上有些業務隨着數據量的增長,為了提高運行效率,也需要以分布式的方式在多台機器上並發執行。這時候,分布式分片調度系統也就孕育而生了。

  這類系統的實際應用場景,往往和日常維護工作或需要定時執行的業務邏輯有一定關聯。比如需要定時批量清理一批機器的磁盤空間,需要定時生成一批商品清單,需要定時批量對一批數據建索引,需要定時對一批用戶發送推送通知等等。

 

這類系統的核心目標基本上就是兩點:

  • 對作業分片邏輯的支持:將一個大的任務拆成多個小任務分配到不同的服務器上執行, 難點在於要做到不漏,不重,保證負載平衡,節點崩潰時自動進行任務遷移等

  • 高可用的精確定時觸發要求:因為往往涉及到實際業務流程的及時性和准確性,所以通常需要保證任務觸發的強實時和可靠性

 

所以,負載均衡,彈性擴容,狀態同步和失效轉移通常是這類調度系統在架構設計時重點考慮的特性

從接入方案和流程上來說,因為要支持分片邏輯,要支持失效轉移等,這類調度系統,對所調度的任務通常都是有侵入性要求的。

常見的做法是用戶作業需要依賴相關分片調度系統的客戶端庫函數,拓展一個作業調度類做為作業觸發的入口點。一般還需要接收和處理分片信息用於對數據進行正確的分片處理。此外通常還需要實現一些接口用於滿足服務端的管理需求,比如注冊節點,注冊作業,啟動任務,停止任務,匯報狀態等等。有些系統還要求作業執行節點常駐Daemon進程,用於協調本地作業的管理和通訊。

從觸發實現邏輯的角度來說,為了在海量任務的情況下,保證嚴格精確定時觸發,這類調度系統有一大半,其定時觸發邏輯,實際上是由執行節點自身在本地觸發的,也就是說要求作業或守護進程處於運行狀態,向服務端注冊作業,服務端分配分片信息和定時邏輯給到客戶端,但定時的觸發,是由客戶端庫函數封裝的如Quartz等定時邏輯來實際執行觸發的。

這樣做的首要目的當然是為了保證觸發的精度和效率,降低服務端負載,此外如果服務端短時間內掛掉,只要作業配置保持不變,作業還是能夠在客戶端正常觸發的。

也有些系統,比如SchedulerX,是采用服務端觸發邏輯的。這對服務端的要求就高了很多,因為這時候,服務端不光要協調分片邏輯,還要維護觸發隊列。所以服務端觸發的系統,首先需要保證服務端的高可用,其次還要保障性能,因此,通常都是采用集群方案

2.2、DAG工作流類調度系統

  這一類系統的方向,重點定位於任務的調度依賴關系的正確處理,分片執行的邏輯通常不是系統關注的核心,或者不是系統核心流程的關鍵組成部分,如果某些任務真的關注分片邏輯,往往交給后端集群(比如MR任務自帶分片能力)或者具體類型的任務執行后端去實現。

  這類系統的代表,包括:oozie,azkaban,chronos,zeus,Lhotse,還有各種大大小小的公有雲服務提供的那些可視化工作流定義系統。我司自研的Jarvis調度系統也屬於這類系統。

  DAG工作流類調度系統所服務的往往是作業繁多,作業之間的流程依賴比較復雜的場景,比如大數據開發平台的離線數倉報表處理業務,從數據采集,清洗,到各個層級的報表的匯總運算,到最后數據導出到外部業務系統,一個完整的業務流程,可能涉及到成百上千個相互交叉依賴關聯的作業。

所以DAG工作流類調度系統關注的重點,通常會包括:

足夠豐富和靈活的依賴觸發機制:比如時間觸發任務,依賴觸發任務,混合觸發任務

  • 而依賴觸發自身,可能還要考慮,多親依賴,長短周期依賴(比如小時任務依賴天任務,或者反過來),依賴范圍判定(比如所依賴任務最后一次成功就可以觸發下游,還是過去一個星期的所有任務都成功才可以觸發下游),自身歷史任務依賴,串並行觸發機制等等

 

作業的計划,變更和執行流水的管理和同步

  • 這一條,定時分片類調度系統固然也要考慮,但通常都相對簡單。

  • 而在DAG工作流類調度系統中,因為任務觸發機制的靈活性和作業依賴關系的復雜性,這個需求就尤為重要,需要提供的功能更加復雜,具體的問題解決起來也困難很多。

 

任務的優先級管理,業務隔離,權限管理等

  • 在定時分片類調度系統中,通常情況下,具體執行端的業務的隔離很多情況下是天然的,注冊了特定業務的節點才會去執行特定的任務。然后,加上業務鏈路一般都比較短,以及強實時性要求,所以對優先級的管理通常要求也不高,基本靠資源隔離來實現資源的可用,不太存在競爭資源的問題,權限管理也同理。

  • 而在DAG工作流類調度系統中,往往一大批作業共享資源執行,所以優先級,負載隔離,和權限管控的問題也就突顯出來

     

各種特殊流程的處理,比如暫停任務,重刷歷史數據,人工標注失敗/成功,臨時任務和周期任務的協同等等

  • 這類需求,本質上也是因為業務流程的復雜性帶來的,比如業務邏輯變更啦,腳本寫錯啦,上游數據有問題啦,下游系統掛掉啦等等,而業務之間的網狀關聯性,導致處理問題時需要考慮的因素很多,也就要求處理的手段要足夠靈活強大

 

完備的監控報警通知機制

    • 最簡單的比如,任務失敗報警,超時報警,再進一步,流量負載監控,業務進度監控和預測,如果做的再完善一點,還可以包括業務健康度監控分析,性能優化建議和問題診斷專家系統等

 

 

小結

  需要注意的是,這兩類系統的定位目標,並不是絕對沖突矛盾的。

  只不過,要同時圓滿的支持這兩大類需求,從實現的角度來說是很困難的,因為側重點的不同,在架構上多少會對某些方面做些取舍,當前的系統都沒有能夠做到完美的兩者兼顧。但這不代表他們就一定是不可調和的,好比離線批處理計算框架和流式實時計算框架,長期以來各行其路,但是,隨着理論,實踐的進步,也開始有依托一種框架統一處理兩類計算業務的可能性出現。

 

3、DAG工作流調度系統的兩種心法流派

  DAG工作流調度系統有很多開源實現,各大公司也往往有自己的系統實現。這些系統,從開發語言,支持的任務類型,調度方式,監控報警,到業務接入的方式,周邊管理工具的完備性等角度來說,都是千差萬別的。這些差別在很大程度上都是產品形態招式上的差異,但是有一條,不止招式那么簡單,我認為是心法流派的差異,它在很大程度上影響了一個系統的核心框架設計思想。

這個差異就是:具體任務的執行,是依托於一個靜態的執行列表還是動態的執行列表,此話怎講?別急,待我詳細解釋一下。

 

兩個概念 : 作業計划(Job Plan)和任務實例(Task Instance)

要談執行列表的心法流派問題,首先,得明確作業計划和任務實例兩個概念

通常情況下,既然你把一個作業丟到調度系統上去監管執行,那除了個別一次性作業,多數情況下這些作業都是要周期性重復執行的,只是有些純粹由時間驅動,有些還有前置任務依賴關系要處理。

那么什么時候執行這個作業,是每個月月底執行一次,還是每天凌晨2點執行一次,又或者還是早上9點到晚上6點之間,每個小時執行一次?任務觸發的條件,是前置任務全部成功,還是任一前置任務成功,又或者要求自身的上一次執行結果也要成功? 回答這些問題的,就是所謂的作業計划(Plan)

而具體落到某年某月某天,一個作業什么時候真正執行一次?這一次具體的執行,就是所謂的任務執行實例(Instance)

 

靜態執行列表 v.s. 動態執行列表

回頭繼續討論,所謂的靜態執行列表流派,是說一個作業的具體執行實例,是跟據作業計划提前計算並生成執行列表的,然后調度系統按照這個提前生成的執行列表去執行任務。 更進一步,有些系統實際上壓根就沒有區分作業計划和任務執行列表,兩者是和二為一的,人工定義一個確定了依賴和先后關系任務列表,定期執行這整個列表。

對於實際有作業計划和執行列表之分的系統,常見的做法是在頭一天晚上接近凌晨的時候,分析所有作業的時間要求和作業間的依賴關系,然后生成下一天所有需要執行的作業的實例列表,將具體每個任務實例的執行時間點和相互依賴關系固化下來。調度系統執行任務時,遍歷檢查這個列表,觸發滿足條件的任務的執行。

oozie,azkaban和大多數公有雲上的workflow服務,和我司的第一代Jarvis調度系統,基本上都是屬於這個流派。其中oozie,azkaban基本采用的是作業計划和執行列表一體的方案,我司的Jarvis一代采用的是兩者分離,由作業計划定期生成執行列表的方案。

然后,所謂的動態執行列表流派,是說某個作業的具體執行實例,並沒有提前固化計算出來,而是在它的上游任務(純時間周期任務的話就是上個周期的任務)執行完畢時,根據當時時刻點最新的作業計划和依賴關系動態計算出來的。

zeus,chronos和我司的第二代Jarvis調度系統,基本上是屬於這個流派的。

這兩個流派沒有絕對的優劣之分,各有優缺點,各有自己擅長處理的場景和不擅長處理的場景,所以有時候系統的具體實現也不完是絕對互斥的,在某些功能方面也是有變化取舍的。

那么,為什么會有兩種流派?提前生成執行列表還是需要的時候再生成,又有什么關系嗎?兩種流派各自的主要問題和難點是什么?

罪惡之源

之所以會有兩種流派,問題的源頭在於,作業計划和執行實例列表,這兩者服務的對象不同。

從周期性作業管理的角度來說,你面向的對象當然應該是作業計划,當你想改變一個周期性作業的執行策略時,你修改的是作業的執行計划本身。而做為調度系統,在具體任務的執行過程中,它面向的對象則是任務的一次執行實例,而非計划本身。

所以當計划產生變更時,就涉及到作業計划和執行列表之間的同步問題。

對於靜態執行列表流派來說,處理確定的任務執行列表是它的長項,因為執行列表一旦生成,那你就可以對它進行任意的修改,可以進行各種Hack,不再需要考慮原有的作業計划依賴關系等等。比如你今天想臨時跳過一部分任務的執行,直接把它們從實例列表中刪除,並從下游任務的依賴列表中移除依賴關系就好。

而對於動態執行列表流派來說,這種臨時的Hack動作就會比較難處理,因為計划和實例是根據規則強關聯的。要影相今天的任務實例,可能就要修改作業的計划,而修改了計划,后續比如明天的任務實例也可能會受到影響。

但是,對於執行實例或者具體實例的依賴關系難以提前確定和生成的場景,比如不等周期的依賴(比如月底的月任務依賴於每天的日任務)或者任意成功條件即可觸發,觸發實例個數不確定的情況,就幾乎無法提前生成靜態的執行列表克。

再比如在一些短周期任務計划變更,或者任務依賴關系調整,任務列表已經有部分任務執行完畢的情況下,靜態執行列表方案能否快速,正確的更新執行列表, 都會遇到很大的挑戰。

再比如,一天的所有任務中,有些任務的修改是臨時的,有些任務的修改是長期的,這種情況下,靜態執行列表的方案因該如何應對呢? 對於計划和執行列表一體的系統,幾乎是沒法做的,只能再復制生成一份臨時執行列表,卻別對待。而對於從計划列表定時生成執行列表的系統,則勢必需要部分修改已實例化的任務執行列表,部分修改未實例化的作業計划,在這種模式下,如何保證兩邊的修改不沖突,如果沖突,以誰為主,甚至能否發現沖突,往往都是很困難的。

 

小結

所以,簡單總結來說,靜態執行列表方案,擅長處理時間范圍確定的(最好是當前周期的),已知的,一次性的任務變更,前提是你對如何Hack執行列表有清楚的認識。動態執行列表方案擅長處理尚未發生的,長期的計划變更,對於不等周期和短周期任務的變更時效性也會好很多,臨時的一次性變更則需要通過其它方式來輔助完成。

當然,這兩種流派針對自己不擅長的場景,多少也能找到各種的補救手段來應對,並非完全一籌莫展,只是補救手段的復雜程度和代價大小的問題。

這兩種流派,我們都實踐過,總體看來,靜態執行列表方案,系統架構相對簡單,系統運行邏輯相對直白,容易分析問題,但是能處理的場景也比較有限。動態執行列表方案,能覆蓋的場景范圍更廣,計划變更響應更及時,但是系統架構實現相對復雜,運行邏輯也更加復雜,牽扯的因素較多,有時候不容易一眼理順邏輯。

所以,如果是在業務場景比較簡單,任務依賴容易理清的場景下,靜態執行列表方案的系統維護代價會比較小,反之,則應該考慮構建動態執行列表方案的系統。

最后,這兩種方案也並非完全互斥,我司的jarvis二代調度系統,就在一些局部功能中使用了靜態執行列表的思想,來輔助處理一些動態執行列表方案比較難應對的問題。比如,用戶需要知道今天有哪些任務將要執行,什么時候執行,這就會需要一個實例化的執行列表,總不能跟用戶說我們的任務是動態實例化的,所以還沒有執行的任務無法展示吧 :)

 

4、工作流調度系統功能特性和需求分析

  談完心法再來談談招式,不論流派如何,最后落實到系統實現,從系統的角度,需要考慮具備哪些特性,可以提高穩定性,降低管理維護成本,從用戶的角度,關心的則是能夠提供哪些功能,可以提高工作效率,降低開發使用成本。

工作流的定義方式

既然是工作流調度系統,用戶首先要面對的問題,當然是如何定義和管理工作流。

靜態顯式定義和管理工作流

  多數靜態執行列表流派的系統,比如oozie,azkaban以及各種公有雲的workflow服務,都會包含創建工作流Flow這樣一個過程,用戶需要定義一個具體的作業流程里面都包含哪些作業,他們的先后依賴關系如何。所不同的是,用戶通過什么手段來定義和描述這個工作流:

  比如oozie要求用戶提供XML文件(也可以通過API提交),按照規定的格式描述各個工作流的拓撲邏輯和Job的依賴關系,各種任務類型的細節配置等等。

  Azkaban要求用戶定義.job文件來描述作業的依賴關系,然后為每個沒有依賴關系的作業及其下游作業創建一個工作流,如果要嵌套子工作流,則需要顯式的申明和創建。然后將所有的.job文件和作業執行需要的依賴打包成zip包通過服務器上傳,最終在服務器上創建出工作流並展示給用戶。

  oozie和Azkaban采取的這兩種方式,從系統設計的角度來說,對外部系統的關聯和依賴比較小,是一個相對獨立封閉的環境,演進起來比較自由。但這兩個系統最大的問題是,周邊的運維使用工具太過缺乏,易用性很差。作為工具使用可以,但是做為平台服務,缺失了太多內容,工作流的定義和維護成本太高。所以有很多公司是在oozie和Azkaban的基礎上對工作流的提交管理進行了二次開發封裝,來降低使用難度。

  而各種公有雲的workflow服務,則多半是通過圖形化拖拽作業節點的方式,來讓用戶顯式的定義工作流,本質上和oozie的方式沒有太大區別,只是通過可視化的操作來屏蔽配置的語法細節,降低工作流定義的難度。

 

動態隱式定義和管理工作流

  Chronos,Zeus和我司的兩代Jarvis調度系統,走的則是另一條路。系統中並沒有讓用戶顯式的定義一個工作流。實際上,這些系統的管理維度是作業,用戶定義的是作業之間的依賴關系,哪些作業構成一個工作流,系統實際上並不關心,用戶也不需要申明,系統只負責按規則將所有滿足條件的任務調度起來,將一批任務圈定成一個Flow這種行為,對系統來說並非必需。你甚至可以理解為整個系統里的所有作業就是一個多進多出並發執行的大Flow。

 

對比

  你要問那比如權限隔離,調度配置這些,沒有了Flow的概念怎么處理? 事實上,這些概念和一組任務的執行鏈路這個概念壓根就沒有必然的關系。Flow關注的是的依賴關系,其它上面提到的那些概念關注的是資源的管控,這兩者涉及的對象可以重疊,但是並非一定要重疊,有些時候也不適合重疊。

那兩種處理方式各有什么優缺點呢?

顯式定義工作流Flow這種方式,優點是用戶明確的知道哪些任務是一組的,適合處理工作流內作業規模較小,工作流之間的作業沒有交叉依賴,不會頻繁變更的場景,用戶的掌控感可能較強,但是反之,作業規模大,關聯復雜,變更頻繁的場景實際上是不太適合的,另外對依賴和觸發邏輯的支持,局限性也較大(下一節詳解)

而不顯式定義工作流的方式,用戶無需理會和手工定義和處理工作流這個概念,使用靈活,作業之間依賴變更,業務調整等行為,都會自動反映到整體的任務執行流程中,對於用戶而言,管理的壓力較小,作業流程變更操作簡單。相對不足的地方是作業的分組這個概念沒有Flow來承接,資源的管理需要通過其它方式來實現。

作業運行周期的管理

顯式靜態定義工作流的系統,對作業運行周期的管理,通常都是以整個工作流為單位來定義和管理的。當調度時間到達時,啟動整個工作流,工作流內部的作業按照依賴關系依次執行。所以如果一個工作流內部存在需要按不同周期進行調度的作業,就會很難處理,需要想各種補救手段去間接規避,比如拆分工作流,創建子工作流,或者復制多份作業等。

非顯式動態定義工作流的系統,對作業運行周期的管理,通常是以單個作業為單位的(因為壓根就沒有固定的Flow這個單位可以管理 ),所以用戶只需要按需定義自己作業的運行周期就好了。相對的,對調度系統開發者來說,實現的難度會比較大,因為正確的自動判定依賴觸發關系的邏輯會比較復雜。

作業依賴關系的管理

  在開始討論依賴管理之前,我們先來看看通常用做判斷一個作業的具體任務實例是否可以開始運行的條件都有哪些?

  首先當然是時間依賴,大量的定時觸發任務,依托時間來判斷是否滿足運行條件。其次是任務依賴,需要根據前置任務的執行情況,來決定當前任務是否滿足運行條件。

  通常情況下,這兩種依賴條件構成了大多數調度系統啟動任務運行的核心判定依據。但是有時候還有第三種依賴條件,就是數據依賴,通過判斷任務運行所依托的數據是否存在來決定是否啟動任務。

  理論上,如果所有生成數據的任務的運行狀態和結果都能被調度系統所控制或者感知,那么數據依賴這種依賴關系就是一個偽命題,既非必要,往往也不是最佳解決方案。

  為什么這么說?因為數據依賴意味着對調度系統而言,業務邏輯不再是透明的,一方面,你需要知道獲取數據信息的途徑,另一方面,如何判定一個任務依賴的數據是否完備了,本身也不是一件容易的事,容錯性往往也不好。

  比如你通過文件是否存在來判斷,那么文件里的內容是錯的呢?或者生成文件的任務跑了一半失敗了,文件內容不完整呢?即使你能保證文件的正確性和原子性,那么如果上游任務重跑刷新了數據呢?你如何判定這種情況?

  總體來說,個人認為,一個調度系統,如果對數據依賴這種依賴關系依托得越多,那么相對來說整個系統就越不成熟和完備,需要人工干涉的可能性越高。當然,事事無絕對,也有一些使用數據依賴才是最合理有效的解決方案的場景。而且,退一步說,調度系統再完善,也是一個有邊界的系統,總難免一些依賴要通過外部數據的判定來實現。

回頭繼續討論作業依賴關系的管理

  對於采用人工顯式定義工作流的系統而言,作業依賴的管理,在很大程度上,其實是通過對工作流的拓撲邏輯的管理來實現的,用戶改變工作流的拓撲邏輯的過程,實際上也就改變了作業間的依賴關系。 而作業的任務依賴關系,其邊界,基本上就是在當前的工作流范圍之類。

對於非顯式定義工作流的系統而言,用戶直接管理作業的依賴,所以這類系統一般都會提供給用戶配置上游任務和觸發條件的接口/界面。用戶通過改變作業之間的依賴關系,間接的影響相關聯作業的運行流程拓撲邏輯

  所以,你要問,這兩種定義和管理作業依賴的方式,看起來只是角度不同而已,換湯不換葯,采用那種,只是流程的需要,實際效果沒有什么區別吧?實際上,並不完全如此,比如,從用戶的角度來說:

  前面一種管理方式,需要用戶對工作流內部的作業比較了解,對當前的工作流拓撲邏輯也足夠清晰,才能較好的保證將新的作業安排放置到正確的位置上去。但只要滿足依賴,作業節點的安排位置也可以比較自由。

  舉個簡單的例子,比如BC兩個作業分別依賴作業A,其它沒有相互依賴關系。那么,我可以把BC作業並行的放在A作業后面,也可以為了控制資源使用,讓BC作業串聯的放置在A后面(相當於人工將作業C改為依賴作業B)。

  而后面一種管理方式,用戶只需要關心當前任務的前置任務有哪些就可以了,因此對用戶的要求降低了不少。不過這樣一來拓撲邏輯圖是唯一且自動生成的(上例ABC作業,就只能是BC作業並行放在A作業后面),缺點是你無法自由調整工作流程,但實際上你多半也沒有調整的必要。如果是為了控制作業優先級,大可通過其它方式實現

  后者還有一個很大的優勢,就是如果你的任務的依賴關系可以自動分析出來的話(比如hive任務,可以通過解析腳本,自動判斷上下游數據表,然后再通過數據表關聯自動找到上下游任務),那么多數情況下,用戶甚至都可以不用配置作業依賴關系,直接添加具體作業就完事了,工作流的拓撲關系全部交給系統自動分析,添加和調整。比如,我司的Jarvis調度系統,結合Hive元數據血緣分析工具,就基本上達到了這樣的效果 ;)

  最后,用戶顯式定義工作流這種模式,對跨工作流的任務依賴也很難處理,原本在一個工作流內部可以通過任務依賴來實現的控制,在跨工作流以后,通常就只能通過數據依賴的手段來輔助實現了,但如前所述,這么做的話,一來用戶可能需要定制數據依賴檢測邏輯,二來在遇到數據重跑之類的場景,任務的正確執行就需要進一步的人工干預處理了。

 

作業異常管理和系統監控

常在河邊走,哪有不濕鞋,運行作業多了,總會出問題。所以對用戶來說,作業異常流程管理能力的好壞,也是工作流調度系統是否好用的一個重要考慮因素。

比如,如果一個中間任務的腳本邏輯有錯,需要重跑自身及后續下游任務,該如何處理?用戶通過什么樣的方式完成這件工作?需要手工重新創建一個新的工作流?還是可以通過勾選作業,自動尋找下游任務的方式實現?

比如一個任務運行失敗,但是結果數據通過其它手段進行了修復,那么如何跳過該任務繼續運行后續任務?

再比如,任務失敗是否能夠自動重試?重試有什么前提條件,需要做什么預處理,任務失敗應該報警,向誰報警?以什么方式報警?什么情況下停止報警?任務運行得慢要不要報警? 怎么知道比以前慢?多慢該報警?不同的任務能否區別對待?等等

所有這些方面都決定了用戶的實際體驗和系統的好用/易用程度,同時,對系統的整體流程框架設計也可能會帶來一些影響。

開源的工作流調度系統在這些方面做得通常都相對簡單,這也是很多公司二次開發改造的重點方向。

 

資源和權限控制

有人的地方就有江湖。任務多了,勢必就需要進行資源和權限管控。

最直接的問題就是,如果有很多任務都滿足運行條件,資源有限的情況下,先跑哪個?任務優先級如何定義和管理?

再退一步,你怎么知道哪些資源到了瓶頸?如果調度系統管理執行的任務類型很多,任務也可以在不同的機器或集群上運行,你如何判定哪些任務需要多少資源?哪些機器或集群資源不足?能否按照不同的條件區別管理,分類控制並發度或優先級?

最后,誰能編輯,運行,管理一個任務?用戶角色怎么定義?和周邊系統,比如Hadoop/Hive系統的權限管理體系如何對接配合?

這些方面的內容,多數的開源的工作流調度系統也做得並不完善,或者說很難做到通用,因為很多功能需要和周邊系統深度配合才可能完成。

 

系統運維能力

系統的運維能力:包括是否有系統自身狀態指標的監控,是否有業務操作日志,執行流水等便於分析排查問題,系統維護,升級,上下線,能否快速完成,系統是否具備灰度更新能力等等。

 

5、總結

  工作流調度系統做為大數據開發平台的核心組件,牽扯的周邊系統眾多,自身的業務邏輯也很復雜,根據目標定位的不同,場景復雜度和側重點的不同,市面上存在眾多的開源方案。

  但也正因為它的重要性和業務環境的高度復雜性,多數有開發能力的公司,還是會二次開發或者自研一套甚至多套系統來支撐自身的業務需求。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM