標籤:
一,介紹
Oozie是一個基於Hadoop的工作流程調度器,它可以通過Oozie Client 以編程的形式提交不同類型的作業,如MapReduce作業和Spark作業給底層的計算平台(如 Cloudera Hadoop)執行。
Quartz是一個開源的調度軟體,它為任務的調度執行提供了各種觸發器以及監聽器
下面使用Quartz + Oozie 將一個MapReduce程式提交給Cloudera Hadoop執行
二,調度思路
①為什麼要用Quartz呢?主要是藉助Quartz強大的觸發器功能。它可以允許滿足不同的調度需求,如每周執行作業一次、重複執行作業多少次。這裡有一個重要的問題:假設我有一個作業需要重複執行,當第一次把該作業提交到CDH上執行後,以後需要執行該作業時不再是又一次把該作業上傳到CDH上然後執行,而是把提交過的作業記錄下來,下次需要運行時,直接讓CDH再運行該作業。
②使用Quartz還有一個好處就是:在作業提交的時候可以做一些控制。比如,某種類型的作業提交的頻率很高,或者已耗用時間較短(根據它上次執行完的情況來判斷),那麼下次運行它時,讓它具有更高的優先順序。
③使用Oozie的目的很明確,就是讓它把作業發送給底層的計算平台,如CDH去執行作業。
三,Eclipse開發環境搭建
主要是需要Quartz和Oozie的依賴包。具體如下:
四,實現思路
a) 調度系統目前只考慮調度兩種類型的作業:Mapreduce作業和Spark作業。先把這二種作業通過Quartz傳遞給Oozie,然後再讓Oozie把作業提交給CDH計算平台去執行。
b) Quartz提供了一個公用的Job介面。裡面只有一個execute()方法,該方法負責完成Quartz所調度的作業的具體功能:把作業傳遞給Oozie
c) 定義一個抽象類別BaseJob,它裡面定義了二個方法。這二個方法主要是用來做一些準備工作,即使用Quartz把作業傳遞給Oozie時需要找到作業在HDFS上的儲存目錄,並將之複製執行目錄下。
d) 最後是兩個具體的實作類別,MRJob和SparkJob,它們分別代表Mapreduce作業和Spark作業。在實作類別裡面完成作業的配置,然後將作業提交到CDH計算平台上執行。
相關類圖如下:
五,具體程式碼分析
MRJob.java
實現了org.quartz.Job介面的execute(),該方法當觸發器被觸發時,會自動地被Quartz Schedule 調度執行。這樣,就可以根據需要定義觸發器,控製作業何時提交給Oozie。
1 @Override 2 public void execute(JobExecutionContext arg0) throws JobExecutionException { 3 try{ 4 String jobId = wc.run(conf); 5 System.out.println("Workflow job submitted");//submit job to oozie and get the jobId 6 7 //wait until the workflow job finishes 8 while(wc.getJobInfo(jobId).getStatus() == Status.RUNNING){ 9 System.out.println("Workflow job running...");10 try{11 Thread.sleep(10*1000);12 }catch(InterruptedException e){e.printStackTrace();}13 }14 System.out.println("Workflow job completed!");15 System.out.println(wc.getJobId(jobId));16 }catch(OozieClientException e){e.printStackTrace();}17 }
測試的main函數程式如下:可以看出對於用戶端而言,只需要按照編寫常規的Quartz作業方式,就可以調試MapReduce作業了。要想運行該程式,當然還得提前準備到作業的運行環境。具體參考
1 import static org.quartz.JobBuilder.newJob; 2 import static org.quartz.TriggerBuilder.newTrigger; 3 4 import java.util.Date; 5 6 import org.quartz.JobDetail; 7 import org.quartz.Scheduler; 8 import org.quartz.SchedulerFactory; 9 import org.quartz.SimpleTrigger;10 import org.quartz.impl.StdSchedulerFactory;11 import org.slf4j.Logger;12 import org.slf4j.LoggerFactory;13 14 import com.quartz.job.MRJob;15 16 17 public class QuartzOozieJobTest {18 public static void main(String[] args) throws Exception{19 QuartzOozieJobTest test = new QuartzOozieJobTest();20 test.run();21 }22 23 public void run() throws Exception{24 Logger log = LoggerFactory.getLogger(QuartzOozieJobTest.class);25 26 log.info("------- Initializing ----------------------");27 28 SchedulerFactory sf = new StdSchedulerFactory();29 Scheduler sched = sf.getScheduler();30 31 long startTime = System.currentTimeMillis() + 20000L;32 Date startTriggerTime = new Date(startTime);33 34 JobDetail jobDetail = newJob(MRJob.class).withIdentity("job", "group1").build();35 SimpleTrigger trigger = (SimpleTrigger) newTrigger().withIdentity("trigger", "group1").startAt(startTriggerTime).build();36 37 Date ft = sched.scheduleJob(jobDetail, trigger);38 39 log.info(jobDetail.getKey() + " will submit at " + ft + " only once.");40 41 sched.start();42 // sched.shutdown(true);43 }44 }
整個項目的原始碼下載
一個簡單的使用Quartz和Oozie調度作業給大資料計算平台執行