數(shù)據(jù)工程中的任務(wù)調(diào)度實(shí)踐

數(shù)據(jù)工程領(lǐng)域當(dāng)前遇到的挑戰(zhàn)

現(xiàn)代系統(tǒng)正變得越來越復(fù)雜,從單線程到多線程华坦,從單體到微服務(wù)撮躁,從單節(jié)點(diǎn)到分布式,從本地到云端... … 復(fù)雜度使得程序產(chǎn)生預(yù)期的結(jié)果需要越來越多的必要條件捺氢,而每種條件都有其自身的成功概率藻丢,即使每種條件的成功概率都很高,根據(jù)墨菲定律摄乒,或早或晚一定會(huì)遇到不可預(yù)知的結(jié)果悠反。

在數(shù)據(jù)工程領(lǐng)域,這個(gè)問題尤其突出馍佑,目前大數(shù)據(jù)領(lǐng)域幾乎都是分布式運(yùn)行的任務(wù)斋否、高可用的消息隊(duì)列、多備份的存儲(chǔ)拭荤、主從節(jié)點(diǎn)等等茵臭。在這樣的情況下,如何構(gòu)建穩(wěn)定舅世、健壯的任務(wù)或服務(wù)成為了一個(gè)挑戰(zhàn)旦委。而數(shù)據(jù)工程實(shí)踐中每日調(diào)度的任務(wù)成為了與各個(gè)復(fù)雜數(shù)據(jù)組件交互的最主要形式奇徒,所以本文我們將以數(shù)據(jù)工程的任務(wù)調(diào)度為例,利用混沌工程幫助我們找出系統(tǒng)薄弱點(diǎn)或脆弱性缨硝,引出我們沉淀的基于日志驅(qū)動(dòng)的任務(wù)調(diào)度實(shí)踐摩钙。

什么是混沌工程?

混沌工程是在系統(tǒng)上進(jìn)行實(shí)驗(yàn)的學(xué)科, 目的是建立對(duì)系統(tǒng)抵御生產(chǎn)環(huán)境中失控條件的能力以及信心查辩。(摘自:混沌工程原則)
混沌工程通過以下四個(gè)步驟來找出系統(tǒng)中隱藏的“混沌”:

  1. 用系統(tǒng)在正常行為下的一些可測(cè)量的輸出來定義“穩(wěn)定狀態(tài)”腺律。
  2. 假設(shè)這個(gè)系統(tǒng)在控制組和實(shí)驗(yàn)組都會(huì)繼續(xù)保持穩(wěn)定狀態(tài)。
  3. 在實(shí)驗(yàn)組中引入反映真實(shí)世界事件的變量宜肉,如服務(wù)器崩潰匀钧、硬盤故障、網(wǎng)絡(luò)連接斷開等谬返。
  4. 通過控制組和實(shí)驗(yàn)組之間的狀態(tài)差異來反駁穩(wěn)定狀態(tài)的假說之斯。
    混沌工程實(shí)驗(yàn)是通過向現(xiàn)有系統(tǒng)注入故障,從而發(fā)現(xiàn)系統(tǒng)的薄弱點(diǎn)遣铝,從而可以有針對(duì)性地提高整個(gè)系統(tǒng)的健壯性佑刷。

環(huán)境都是高可用的,應(yīng)該很健壯啊

有些人可能會(huì)有疑問酿炸,“我們環(huán)境都是高可用的瘫絮,應(yīng)該很健壯啊”。這個(gè)問題還是要分開來看填硕,健壯的系統(tǒng)能夠忠實(shí)執(zhí)行程序邏輯并得到最終結(jié)果麦萤。但是如果程序邏輯就是有問題的呢?
或者扁眯,即使程序邏輯沒有問題壮莹,由于程序本身的脆弱性,在系統(tǒng)從錯(cuò)誤中恢復(fù)時(shí)可能沒有處理一些必要的邏輯姻檀,導(dǎo)致最終結(jié)果出現(xiàn)問題命满。因此,系統(tǒng)級(jí)別的高可用性或健壯性與程序級(jí)別的健壯性是兩回事绣版,必須分開看待胶台。二者缺一不可。
在工程實(shí)踐中杂抽,我們往往會(huì)過于關(guān)注基礎(chǔ)設(shè)置是否具備高可用性诈唬,而忽略了程序邏輯的健壯性和錯(cuò)誤恢復(fù)處理。

僅僅是冪等就足夠了嗎默怨?

有些人認(rèn)為他們的程序是冪等的讯榕,因此即使出錯(cuò)了可以重跑,所以不需要考慮其他。這里先講一下冪等的定義:總能夠用同樣的參數(shù)重復(fù)執(zhí)行愚屁,并得到相同的結(jié)果济竹。

那我們可以按照混沌工程的四個(gè)步驟來模擬一個(gè)場(chǎng)景出來:

  1. 用系統(tǒng)在正常行為下的一些可測(cè)量的輸出來定義“穩(wěn)定狀態(tài)”,這里嘗試定義“穩(wěn)定狀態(tài)”為:

    • ETL計(jì)算結(jié)果穩(wěn)定且正確(冪等)
    • 資源隊(duì)列占用合理霎槐,提交的任務(wù)不需要等待太久就可以運(yùn)行
    • 過去的數(shù)據(jù)不會(huì)被重復(fù)計(jì)算
    • 同一時(shí)刻不發(fā)生重復(fù)計(jì)算
  2. 假設(shè)這個(gè)系統(tǒng)在控制組和實(shí)驗(yàn)組都會(huì)繼續(xù)保持穩(wěn)定狀態(tài)送浊。

  3. 在實(shí)驗(yàn)組中引入反映真實(shí)世界事件的變量:手動(dòng)調(diào)度任務(wù)時(shí)頁面卡住了,習(xí)慣性多點(diǎn)了幾次丘跌,刷新頁面后發(fā)現(xiàn)調(diào)度起來了十幾個(gè)任務(wù)袭景。

  4. 通過控制組和實(shí)驗(yàn)組之間的狀態(tài)差異來反駁穩(wěn)定狀態(tài)的假說:

    • 資源隊(duì)列被打滿,新調(diào)度的任務(wù)都得排隊(duì)(不符合穩(wěn)定狀態(tài)條件2)
    • 重跑并覆蓋過去已經(jīng)運(yùn)行過的數(shù)據(jù)(計(jì)算資源浪費(fèi)闭树,不符合穩(wěn)定狀態(tài)條件3)
    • 計(jì)算同一天的數(shù)據(jù)幾十次耸棒,而最終只留了最后那份(計(jì)算資源浪費(fèi),不符合穩(wěn)定狀態(tài)條件4)

通過上面的模擬實(shí)驗(yàn)我們可以知道报辱,雖然ETL是滿足冪等性(即穩(wěn)定狀態(tài)條件1)的与殃,但是由于沒有滿足其他幾個(gè)穩(wěn)定狀態(tài),所以我們可以說它仍然是存在脆弱性的碍现。

反脆弱的任務(wù)調(diào)度應(yīng)該是什么樣的幅疼?

對(duì)于一個(gè)每日運(yùn)行的任務(wù)來說,理想情況下它應(yīng)該每天都能成功完成昼接,但實(shí)際情況下很可能會(huì)遇到失敗的情況爽篷。不同的調(diào)度引擎往往對(duì)失敗的情況有不同的處理方式慢睡。例如逐工,有的調(diào)度引擎會(huì)忽略過去失敗的任務(wù)并繼續(xù)開啟下一個(gè)調(diào)度周期。比如跳過了2022年2月2日的任務(wù)一睁,繼續(xù)運(yùn)行2022年2月3日的任務(wù)钻弄。但當(dāng)發(fā)現(xiàn)任務(wù)出現(xiàn)問題后,就需要手動(dòng)補(bǔ)數(shù)據(jù)并重新運(yùn)行2022年2月2日的任務(wù)者吁,以便將數(shù)據(jù)完整地補(bǔ)齊。如果在這期間有報(bào)表使用了2022年2月2日的數(shù)據(jù)饲帅,那么這些報(bào)表的數(shù)據(jù)肯定是不準(zhǔn)確的复凳。

然而,完全依賴任務(wù)調(diào)度工具有一些缺點(diǎn)灶泵。首先育八,它完全依賴于調(diào)度工具的任務(wù)歷史記錄。如果沒有配置失敗通知機(jī)制赦邻,那么需要一個(gè)個(gè)去查看哪個(gè)任務(wù)掛掉了髓棋。其次,如果允許失敗任務(wù)之后的任務(wù)繼續(xù)運(yùn)行,可能會(huì)導(dǎo)致對(duì)順序有要求的場(chǎng)景出現(xiàn)問題按声。比如膳犹,假設(shè)2月3日的數(shù)據(jù)在MySQL中進(jìn)行了upsert操作,而2月2日的數(shù)據(jù)在重新運(yùn)行失敗任務(wù)后又執(zhí)行了一次签则,那么就會(huì)導(dǎo)致用舊的數(shù)據(jù)覆蓋新的數(shù)據(jù)的問題等等须床。

雖然一些調(diào)度框架在適當(dāng)?shù)呐渲脮r(shí)可以解決上述問題,但無法保證所有調(diào)度框架都能解決這些問題渐裂,或者你的項(xiàng)目對(duì)調(diào)度框架沒有自由選擇的余地豺旬。因此,在實(shí)踐中柒凉,我們需要在ETL任務(wù)和實(shí)際調(diào)度框架(如Airflow等)中引入“日志驅(qū)動(dòng)”的這一層抽象隔離族阅,以便為任務(wù)運(yùn)行添加一層統(tǒng)一的邏輯處理。這樣做可以使得ETL任務(wù)在不同的調(diào)度框架下表現(xiàn)一致膝捞,更加符合大家的預(yù)期坦刀,也不局限于某一個(gè)特定的調(diào)度框架。這樣我們就得以擺脫特定框架的局限绑警,而不是讓每個(gè)人都要熟悉常見求泰、不常見的調(diào)度框架。

數(shù)據(jù)工程的任務(wù)調(diào)度實(shí)踐

前述問題的一個(gè)難點(diǎn)在于在處理重復(fù)提交的任務(wù)時(shí)如何隔離不同調(diào)度系統(tǒng)的具體實(shí)現(xiàn)计盒。

我認(rèn)為數(shù)據(jù)工程的任務(wù)調(diào)度應(yīng)該以“日志驅(qū)動(dòng)”作為解決方案渴频。而日志驅(qū)動(dòng)的重要部分“日志解耦”正是處理這個(gè)問題的利器:我們需要判斷是不是有任務(wù)已經(jīng)提交過了,對(duì)不對(duì)北启?同時(shí)要考慮到隔離不同調(diào)度系統(tǒng)卜朗,所以方案自然是需要一個(gè)單獨(dú)的地方保存這些調(diào)度日志,以便在調(diào)度任務(wù)時(shí)檢查是否需要調(diào)度(是否有相同任務(wù)在運(yùn)行或者這個(gè)任務(wù)是否已經(jīng)運(yùn)行過等)咕村,從而解耦不同具體組件的日志场钉。

注意這里的“日志”并不是任務(wù)運(yùn)行的日志,而是調(diào)度任務(wù)的日志懈涛,記錄的是那個(gè)任務(wù)在哪個(gè)時(shí)間調(diào)度逛万,狀態(tài)是什么等等。
應(yīng)用“日志驅(qū)動(dòng)”所帶來的的好處批钠,遠(yuǎn)不止于此宇植,因?yàn)榱舸媪巳蝿?wù)調(diào)度日志的記錄,在這個(gè)基礎(chǔ)上很多事情變得可能埋心。其實(shí)“日志驅(qū)動(dòng)”和“斷點(diǎn)續(xù)傳”這個(gè)概念很像指郁,只不過沒有應(yīng)用在下載文件上,而是應(yīng)用到了任務(wù)調(diào)度拷呆。日志驅(qū)動(dòng)有幾個(gè)核心要點(diǎn):

  • 自行記錄任務(wù)運(yùn)行歷史闲坎,而不依賴與調(diào)度框架的功能疫粥。這樣就做到了與不同調(diào)度框架解綁;
  • 調(diào)度是有序的腰懂,上個(gè)周期任務(wù)失敗了梗逮,不會(huì)跳過它運(yùn)行下個(gè)周期的任務(wù),每次調(diào)度還是會(huì)先執(zhí)行之前失敗的任務(wù)悯恍,直到它成功库糠;

日志驅(qū)動(dòng)也帶來了幾點(diǎn)好處:

  • 可以解決重復(fù)調(diào)度的問題,當(dāng)任務(wù)運(yùn)行后發(fā)現(xiàn)有相同任務(wù)在運(yùn)行或者已經(jīng)運(yùn)行過了涮毫,當(dāng)前任務(wù)可以直接退出或者kill掉之前的任務(wù)
  • 補(bǔ)數(shù)據(jù)操作更加容易實(shí)現(xiàn)且靈活而不容易出錯(cuò)
  • 更加靈活的任務(wù)依賴配置(任務(wù)上下游不一定是同頻率或者必須在一個(gè)dag里面)
  • 更加靈活的調(diào)度起始設(shè)置瞬欧,例如對(duì)于kafka offset和自增主鍵的支持
  • 更加統(tǒng)一且容易的運(yùn)維操作(不同的項(xiàng)目、不同的調(diào)度引擎罢防,都可以基于日志驅(qū)動(dòng)(的表)來進(jìn)行運(yùn)維操作)
  • 可以記錄更加詳細(xì)的任務(wù)狀態(tài)艘虎,比如讀到多少條數(shù)據(jù),寫了多少條數(shù)據(jù)等等(特指結(jié)構(gòu)化記錄咒吐,而不是普通的執(zhí)行日志)野建,方便做統(tǒng)計(jì)查看
  • 可以自行選擇事務(wù)級(jí)別,或者說可以讓用戶選擇是否要“臟讀”數(shù)據(jù)
  • 還有一些其他好處恬叹,篇幅有限就不在此展開了


回到現(xiàn)實(shí)場(chǎng)景候生,任務(wù)失敗的情況大致可以分為兩種:

  • 重試就可以成功(網(wǎng)絡(luò)閃崩,排隊(duì)超時(shí)等)
  • 代碼绽昼、環(huán)境有問題需要人工介入的

對(duì)于重試就可以成功的情況唯鸭,往往在下一次調(diào)度就可以自動(dòng)補(bǔ)上之前失敗的任務(wù)的數(shù)據(jù);如果不想等到下一個(gè)周期硅确,可以人工馬上調(diào)度一次目溉。

對(duì)于無法重試成功的情況,往往每次調(diào)度都會(huì)掛掉菱农,但是只會(huì)嘗試最開始的那天的任務(wù)缭付,因?yàn)榍爸玫娜蝿?wù)沒有成功,只是在每天重試 2022-02-02 的任務(wù)循未; 無法重試成功的任務(wù)陷猫,仍然需要人工介入,修復(fù)(環(huán)境的妖、邏輯烙丛、上游數(shù)據(jù)等問題)之后,自動(dòng)(按順序)補(bǔ)上之前掛掉的任務(wù)的數(shù)據(jù)羔味;

總結(jié)

通過混沌工程的虛擬實(shí)驗(yàn)我們知道常規(guī)的任務(wù)調(diào)度并不足夠健壯,而日志驅(qū)動(dòng)的加入可以讓ETL任務(wù)更加穩(wěn)定钠右。同時(shí)日志驅(qū)動(dòng)也帶來了諸多好處赋元,不僅僅解決了混沌工程的穩(wěn)定性問題,也更加豐富了數(shù)據(jù)工程實(shí)踐。


文/Thoughtworks 張志豪
原文鏈接:數(shù)據(jù)工程中的任務(wù)調(diào)度實(shí)踐-Thoughtworks洞見

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末搁凸,一起剝皮案震驚了整個(gè)濱河市媚值,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌护糖,老刑警劉巖褥芒,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異嫡良,居然都是意外死亡锰扶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門寝受,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坷牛,“玉大人,你說我怎么就攤上這事很澄【┤颍” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵甩苛,是天一觀的道長(zhǎng)蹂楣。 經(jīng)常有香客問我,道長(zhǎng)讯蒲,這世上最難降的妖魔是什么痊土? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮爱葵,結(jié)果婚禮上施戴,老公的妹妹穿的比我還像新娘。我一直安慰自己萌丈,他們只是感情好赞哗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著辆雾,像睡著了一般肪笋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上度迂,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天藤乙,我揣著相機(jī)與錄音,去河邊找鬼惭墓。 笑死坛梁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腊凶。 我是一名探鬼主播划咐,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼拴念,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了褐缠?” 一聲冷哼從身側(cè)響起政鼠,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體砰琢,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年官帘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片登失。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遏佣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出揽浙,到底是詐尸還是另有隱情状婶,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布馅巷,位于F島的核電站膛虫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏钓猬。R本人自食惡果不足惜稍刀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望敞曹。 院中可真熱鬧账月,春花似錦、人聲如沸澳迫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽橄登。三九已至抓歼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拢锹,已是汗流浹背谣妻。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卒稳,地道東北人蹋半。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像充坑,于是被迫代替她去往敵國(guó)和親湃窍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子闻蛀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容