[Oozie] Continuous Delivery with Oozie

在大數據的平台上開發大數據應用的時候,如果想要自動化執行不同的 Spark 腳本的話,很常會使用 Apache Oozie 這個軟體,如果想要配合一些 Continuous Delivery 的工具如 Jenkins 和 TeamCity 來使用的時候,需要透過 Oozie 的 WebAPI 來使用,有兩種主要的使用方法,一種是利用 Shell Script 下達 Curl 的指令快速溝通,另一種方式則是利用 Oozie 專案開發的 OozieClient 配合 groovy 或是 Java 的指令運行。

如何使用 Curl 與 WebAPI 溝通,官方網站有詳細的講解使用的方法,本篇簡單列出幾個比較常用的範例介紹並留存紀錄。

1. 查詢特定的 JobInfo:

官網中有提到如何使用 filter 來查詢想要知道的 JobId 如下的使用方法:

GET /oozie/v1/jobs?filter=user%3Dbansalm&offset=1&len=50&timezone=GMT

備註:但是筆者在嘗試使用的時候,只能夠針對 workflows 查找,並且一直出現類似以下的回傳訊息 {offset:1,len:50,total:0,workflows:[]},由於筆者想要針對coordinator 查找,所以最後找到以以下的方法,本方法並沒有在官網中詳盡說明!

curl -iku $user:$passwd -X GET "$url/oozie/v1/jobs?jobtype=coordinator&filter=User%3D$user;Status%3DRUNNING;Name%3D$COORDNAME"

在執行 1. 的 curl 指令的時候,可能會得到類似以下的 json 檔案:

{
  offset: 1,
  len: 50,
  total: 1002,
**jobs: [
    {
**    jobType: "workflow"
      id: "0-200905191240-oozie-W",
      appName: "indexer-workflow",
      appPath: "hdfs://user/tucu/indexer-wf",
      user: "bansalm",
      group: "other",
      status: "RUNNING",
      createdTime: "Thu, 01 Jan 2009 00:00:00 GMT",
      startTime: "Fri, 02 Jan 2009 00:00:00 GMT",
      endTime: null,
      info: "run=0",
    },
    {
**    jobType: "coordinator"
      id: "0-200905191240-oozie-C",
      appName: "logprocessor-coord",
      appPath: "hdfs://user/bansalm/myapp/logprocessor-coord.xml",
      user: "bansalm",
      group: "other",
      status: "RUNNING",
      createdTime: "Thu, 01 Jan 2009 00:00:00 GMT",
      startTime: "Fri, 02 Jan 2009 00:00:00 GMT",
      endTime: "Fri, 31 Dec 2009 00:00:00 GMT",
      info: "nextAction=5",
    },
    {
**    jobType: "bindle"
      id: "0-200905191240-oozie-B",
      appName: "logprocessor-bundle",
      appPath: "hdfs://user/bansalm/myapp/logprocessor-bundle.xml",
      user: "bansalm",
      group: "other",
      status: "RUNNING",
      createdTime: "Thu, 01 Jan 2009 00:00:00 GMT",
      startTime: "Fri, 02 Jan 2009 00:00:00 GMT",
      endTime: "Fri, 31 Dec 2009 00:00:00 GMT",
    },
    ...
  ]
}
2. 關閉一個特定的 JobId:

在已知自己想要關閉的 workflow, coordinator 或是 bundle Id 之後就可以利用以下的指令將它停止!

curl -iku $user:$passwd -X PUT "$url/oozie/v1/job/$jobId?action=kill"
3. 啟動一個特定的 Job

首先你要利用 Xml 來描述你要啟動工作的特徵,$knoxConf 是你的檔案來源,他可以是 workflow, coordinator, bundle 的任一個!

curl -iku $user:$passwd -X POST -H "Content-Type: application/xml" -T $knoxConf $url/oozie/v1/jobs?action=start
以下提供 coordinator 的 $knoxConf 的範例:
<configuration>
    <property>
        <name>oozie.coord.application.path</name>
        <value>hdfs://.../coordinator.xml</value>
    </property>
    <property>
        <name>frequency</name>
        <value>* * * * *</value>
    </property>
    <property>
        <name>appRoot</name>
        <value>/.../workflow.xml</value>
    </property>
</configuration>

在使用 Oozie WebAPI 之後,通常會得到一個 Json 的 Response,以下提供一個原始碼他使用 Shell Script 去取得 Json 內特定的 Key:Value 對!連結

#!/bin/bash
function jsonval {
    temp=`echo $json | sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w $prop`
}

json=`curl -s -X GET /oozie/v1/jobs?filter=user%3Dbansalm&offset=1&len=50&timezone=GMT`
prop='想要取得值的 key'
picurl=`jsonval`
使用 OozieClient

如同前面提到的,如果想要更好地整合開發程式,另外也可以利用 OozieClient。

參考資料:Book: The Workflow Scheduler for Hadoop