背景
之前項目中的sqoop等離線數據遷移job都是利用shell腳本通過crontab進行定時執行,這樣實現的話比較簡單,但是隨着多個job復雜度的提升,無論是協調工作還是任務監控都變得麻煩,我們選擇使用oozie來對工作流進行調度監控。在此介紹一下oozie~
官網介紹
首先看官網首頁介紹:http://oozie.apache.org
(1)Oozie是一個管理 Apache Hadoop 作業的工作流調度系統。
(2)Oozie的 workflow jobs 是由 actions 組成的 有向無環圖(DAG)。
(3)Oozie的 coordinator jobs 是由時間 (頻率)和數據可用性觸發的重復的 workflow jobs 。
(4)Oozie與Hadoop生態圈的其他部分集成在一起,支持多種類型的Hadoop作業(如Java map-reduce、流式map-reduce、Pig、Hive、Sqoop和Distcp)以及特定於系統的工作(如Java程序和shell腳本)。
(5)Oozie是一個可伸縮、可靠和可擴展的系統。
oozie web控制台界面如下:
注:如果界面報錯 Oozie web console is disabled,請看https://blog.csdn.net/Abysscarry/article/details/80503594
對比選型
在沒有工作流調度系統之前,公司里面的任務都是通過 crontab 來定義的,時間長了后會發現很多問題:
1.大量的crontab任務需要管理 2.任務沒有按時執行,各種原因失敗,需要重試 3.多服務器環境下,crontab分散在很多集群上,光是查看log就很花時間
於是,出現了一些管理crontab任務的調度系統,如 CronHub、CronWeb 等。
而在大數據領域,現在市面上常用的工作流調度工具有Oozie, Azkaban,Cascading,Hamake等,
我們往往把 Oozie和Azkaban來做對比:
兩者在功能方面大致相同,只是Oozie底層在提交Hadoop Spark作業是通過org.apache.hadoop的封裝好的接口進行提交,而Azkaban可以直接操作shell語句。在安全性上可能Oozie會比較好。
工作流定義: Oozie是通過xml定義的而Azkaban為properties來定義。
部署過程: Oozie的部署相對困難些,同時它是從Yarn上拉任務日志。
任務檢測: Azkaban中如果有任務出現失敗,只要進程有效執行,那么任務就算執行成功,這是BUG,但是Oozie能有效的檢測任務的成功與失敗。
操作工作流: Azkaban使用Web操作。Oozie支持Web,RestApi,Java API操作。
權限控制: Oozie基本無權限控制,Azkaban有較完善的權限控制,供用戶對工作流讀寫執行操作。
運行環境: Oozie的action主要運行在hadoop中而Azkaban的actions運行在Azkaban的服務器中。
記錄workflow的狀態: Azkaban將正在執行的workflow狀態保存在內存中,Oozie將其保存在Mysql中。
出現失敗的情況: Azkaban會丟失所有的工作流,但是Oozie可以在繼續失敗的工作流運行
由於我在安裝公司CDH集群時已經安裝好oozie了,且有對應的可視化操作工具hue,所以我們直接選擇oozie進行工作流調度啦!
原理詳解
主要概念:
我們在官網介紹中就注意到了,Oozie主要有三個主要概念,分別是 workflow,coordinator,bundle。
其中:
Workflow:工作流,由我們需要處理的每個工作組成,進行需求的流式處理。
Coordinator:協調器,可以理解為工作流的協調器,可以將多個工作流協調成一個工作流來進行處理。
Bundle:捆,束。將一堆的coordinator進行匯總處理。
簡單來說:workflow是對要進行的順序化工作的抽象,coordinator是對要進行的順序化的workflow的抽象,bundle是對一堆coordiantor的抽象。層級關系層層包裹。
Oozie本質是通過 launcher job 運行某個具體的Action。launcher job是一個 map-only 的MR作業,而且並不知道它將在集群的哪台機器上執行這個MR作業。oozie有很多的坑,也是因為這個 launcher job 解析job時觸發的異常情況!
組件架構圖:
ps:這個圖是google上好不容易找到的,國內基本沒有或者不清晰…
相信稍微了解下oozie的具體用法后再看這個圖,就一目了然了!
Job組成:
一個oozie 的 job 一般由以下文件組成:
job.properties :記錄了job的屬性
workflow.xml :使用hPDL 定義任務的流程和分支
lib目錄:用來執行具體的任務
其中:
Job.properties:
KEY | 含義 |
---|---|
nameNode | HDFS地址 |
jobTracker | jobTracker(ResourceManager)地址 |
queueName | Oozie隊列(默認填寫default) |
examplesRoot | 全局目錄(默認填寫examples) |
oozie.usr.system.libpath | 是否加載用戶lib目錄(true/false) |
oozie.libpath | 用戶lib庫所在的位置 |
oozie.wf.application.path | Oozie流程所在hdfs地址(workflow.xml所在的地址) |
user.name | 當前用戶 |
oozie.coord.application.path | Coordinator.xml地址(沒有可以不寫) |
oozie.bundle.application.path | Bundle.xml地址(沒有可以不寫) |
注:
1、這個文件如果是在本地通過命令行進行任務提交的話,這個文件在本地就可以了,當然也可以放在hdfs上,與workflow.xml和lib處於同一層級。
2、nameNode,jobTracker和 workflow.xml在hdfs中的位置必須設置。
e.g:Shell節點的job.properties文件示例如下:
nameNode=hdfs://cm1:8020
jobTracker=cm1:8032
queueName=default
examplesRoot=examples
oozie.wf.application.path=${nameNode}/user/workflow/oozie/shell
workflow.xml:
這個文件是定義任務的整體流程的文件,官網wordcount例子如下:
<workflow-app name='wordcount-wf' xmlns="uri:oozie:workflow:0.1"> <start to='wordcount'/> <action name='wordcount'> <map-reduce> <job-tracker>${jobTracker}</job-tracker> <name-node>${nameNode}</name-node> <configuration> <property> <name>mapred.mapper.class</name> <value>org.myorg.WordCount.Map</value> </property> <property> <name>mapred.reducer.class</name> <value>org.myorg.WordCount.Reduce</value> </property> <property> <name>mapred.input.dir</name> <value>${inputDir}</value> </property> <property> <name>mapred.output.dir</name> <value>${outputDir}</value> </property> </configuration> </map-reduce> <ok to='end'/> <error to='end'/> </action> <kill name='kill'> <message>Something went wrong: ${wf:errorCode('wordcount')}</message> </kill/> <end name='end'/> </workflow-app>
可以看到:
**[控制流節點]:主要包括start、end、fork、join等,其中fork、join成對出現,在fork展開。分支,最后在join結點匯聚
** start
** kill
** end
**[動作節點]:包括Hadoop任務、SSH、HTTP、EMAIL、OOZIE子任務
** ok --> end
** error --> end
** 定義具體需要執行的job任務
** MapReduce、shell、hive
文件需要被放在HDFS上才能被oozie調度,如果在啟動需要調動MR任務,jar包同樣需要在hdfs上
Lib目錄:
在workflow工作流定義的同級目錄下,需要有一個lib目錄,在lib目錄中存在java節點MapReduce使用的jar包。
需要注意的是,oozie並不是使用指定jar包的名稱來啟動任務的,而是通過制定主類來啟動任務的。在lib包中絕對不能存在某個jar包的不同版本,不能夠出現多個相同主類。
Workflow 介紹:
workflow 是一組 actions 集合(例如Hadoop map/reduce作業,pig作業),它被安排在一個控制依賴項DAG(Direct Acyclic Graph)中。“控制依賴”從一個action到另一個action意味着第二個action不能運行,直到第一個action完成。
Oozie Workflow 定義是用 hPDL 編寫的(類似於JBOSS JBPM jPDL的XML過程定義語言)。
Oozie Workflow actions 在遠程系統(如Hadoop、Pig)中啟動工作。在action完成時,遠程系統 回調 Oozie通知action完成,此時Oozie將繼續在workflow 中進行下一步操作。
Oozie Workflow 包含控制流節點(control flow nodes)和動作節點(action nodes).
控制流節點定義workflow的開始和結束(start、end 和 fail 節點),並提供一種機制來控制workflow執行路徑(decision、fork和join節點)。
action 節點是workflow觸發計算/處理任務執行的機制。Oozie為不同類型的操作提供了支持:Hadoop map-reduce、Hadoop文件系統、Pig、SSH、HTTP、電子郵件和Oozie子工作流。Oozie可以擴展來支持其他類型的操作。
Oozie Workflow 可以被參數化(在工作流定義中使用諸如$inputDir之類的變量)。在提交workflow作業值時,必須提供參數。如果適當地參數化(即使用不同的輸出目錄),幾個相同的workflow作業可以並發。
Coordinator介紹:
用戶通常在grid上運行map-reduce、hadoop流、hdfs或pig作業。這些作業中的多個可以組合起來形成一個workflow 作業。Hadoop workflow 系統定義了一個workflow 系統來運行這樣的工作。
通常,workflow 作業是基於常規的時間間隔(time intervals)和數據可用性(data availability)運行的。在某些情況下,它們可以由外部事件觸發。
表示觸發workflow 作業的條件可以被建模為必須滿足的謂詞(predicate )。workflow 作業是在謂詞滿足之后開始的。謂詞可以引用數據、時間和/或外部事件。在將來,可以擴展模型來支持額外的事件類型。
還需要連接定期運行的workflow 作業,但在不同的時間間隔內。多個后續運行的workflow 的輸出成為下一個workflow 的輸入。例如,每15分鍾運行一次的workflow 的4次運行的輸出,就變成了每隔60分鍾運行一次的workflow 的輸入。將這些workflow 鏈接在一起會導致它被稱為數據應用程序管道。
Oozie Coordinator 系統允許用戶定義和執行周期性和相互依賴的workflow 作業(數據應用程序管道)。
真實世界的數據應用管道必須考慮到二次處理、后期處理、捕獲、部分處理、監測、通知和SLAS。
Bundle介紹:
Bundle 是一個更高級的oozie抽象,它將批處理一組Coordinator應用程序。
用戶將能夠在bundle級別啟動/停止/暫停/恢復/重新運行,從而獲得更好、更容易的操作控制。
更具體地說,oozie Bundle系統允許用戶定義和執行一堆通常稱為數據管道的Coordinator應用程序。在Bundle中,Coordinator應用程序之間沒有顯式的依賴關系。然而,用戶可以使用Coordinator應用程序的數據依賴來創建隱式數據應用程序管道。