python etl排程 ETL DAG排程策略

2021-10-18 13:01:10 字數 1142 閱讀 9224

1.目前etl的fetch task策略是基於任務子孫任務數和任務優先順序獲得task list

2.然後遍歷task list 檢視任務是否具備執行條件

集群資源校驗(yarn/hdfs)

資料是否準備好(僅mysql task具備),解決主從延遲問題

任務開始時間

任務的父任務是否都執行成功

3.每10s fetch一次task,遍歷一次基於<2>的邏輯

我們把任務的父任務執行狀態判斷放到最後是想降低資料庫查詢成本(如果沒放到最後,可以在exec_log表中維護乙個依賴是否校驗的狀態去動態變更來減少資料庫輪訓查詢成本)

我們如何避免,如 a->b->c 依賴關係,a還沒完成又去校驗b,b又沒通過,又去校驗c這種情況呢(如果此樹較大,我們又是基於子孫任務數排序的話,會出現這種無謂遍歷資料庫的情況)。如果我們沒有維護全域性樹及樹中各任務的狀態的話(成本較高,要時刻保證記憶體中的樹與mysql表的任務狀態同步)。

我們可以這麼做(較少資料庫的無謂遍歷),在任務初始化時把任務依賴的dag載入的map中,並只維護任務與其一級子任務的關係如(<1,[2,3,4]> 父任務id:1,子任務id:2,3,4),然後在任務a校驗沒通過時,把a的一級子任務加入到list(此處不能放入set中,以為不能使用去重的集合,乙個子任務可能會有多個父任務)中,依次遍歷按照如此邏輯,在這一輪遍歷結束後清空list。(或者維護全域性list,在此任務校驗通過後,從set清除此任務的一級子任務)---此種策略適用於只基於子孫任務數的排序方式,如果還有基於權重的排序並且權重只更新了子任務而沒有更新此子任務的上游所有父任務就會出現嚴重問題

索性不如在每次fetch時就拿出子與父的map關係及當時的任務狀態,作為任務提交時的判斷,這樣每fetch一次只與資料庫互動一次

有如下兩張表,直接用sql可解決之前說的問題,注:

denpend

exec_log

depend 表的父id join exec_log 表的task_id,那麼depend.child_id, depend.parent_id(=exec_log.task_id), exec_log.status(父任務的狀態)就出來了,group by depend.child_id ,sum(exec_log.status)=0 的depend.child_id可以跑,否則不可跑

此策略已上線,執行穩定!!!

程序排程及排程策略

程序排程負責動態的將cpu分配給各個程序。主要功能如下 1 記住程序狀態。2 決定哪個程序,什麼時候獲取cpu及其占用多長時間。3 把cpu分配給程序,即將選中程序的pcb中有關程序的相關資訊,如程式狀態暫存器 通用暫存器等內容送入cpu的相應的暫存器中,從而讓該程序占用cpu去執行。4 收回cpu...

排程 開放車間排程Open Shop

定義 有n個需要加工的工件和m種用來加工的機器,每個工件有m道工序,沒道工序的加工時間是已知的,但是不規定每個工件的加工順序,即工件的加工順序是任意的 一台機器在同乙個時刻只能加工乙個工件,乙個工件不能同時在兩台機器上加工 每個工件在同一時刻也只能在某一台機器上加工 最終需要求得一組機器與工件的排列...

程序排程與作業排程

作業排程按一定的演算法從磁碟上的 輸入井 中選擇資源能得到滿足的作業裝入記憶體,使作業有機會去占用處理器執行。但是,乙個作業能否占用處理器,什麼時間能夠占用處理器,必須由程序排程來決定。所以,作業排程選中了乙個作業且把它裝入記憶體時,就應為該作業建立乙個程序,若有多個作業被裝入記憶體,則記憶體中同時...