天天看點

利用DataWorks指派節點補強參數功能

一、前言

DataWorks提供了系統參數供周期排程的任務使用,一般最常用到的系統參數是這兩個:

${bdp.system.bizdate}

${bdp.system.cyctime}

,分别代表任務運作時的昨天和目前時間。

系統參數 簡寫模式 格式 示例
${bdp.system.bizdate} ${bizdate} yyyymmdd 20190802
${bdp.system.cyctime} ${cyctime} yyyymmddhh24miss 20190802110653
使用簡寫模式時,參數配置裡需要寫上例如bizdate=$bizdate的配置内容,如果寫上了完整的系統參數則無需配置

這種系統參數的好處是直接調用,在任務執行時直接會被替換為對用的内容。

當然DataWorks也提供了自定義參數,可以友善地生成定制化的時間格式。

對應的也有兩類:

  • 大括号{ }:對應業務時間,例如{yyyymmdd}将基于bdp.system.bizdate取值。
  • 中括号[ ]:對應運作時間,例如[yyyymmddhh]将基于bdp.system.cyctime取值。

自定義參數可以通過在括号内+/-N來擷取後N天,前N天的時間,基于時間格式的不同也可以達到後N月,前N月,後N年,前N年等等諸如此類的操作,這裡不展開。

除此之外還有一些不太常用的系統參數:

參數 說明
$jobid 任務所屬的工作流ID
$nodeid 節點id
$taskid 任務ID(節點執行個體ID)
$bizmonth 業務月份(格式為yyyymm),其實就是運作時間的上一月
$gmtdate 目前日期(格式為yyyymmdd),此參數預設為當天日期,補資料時傳入的是業務日期+1,相當于$cyctime的日期版

二、那麼問題來了

上面對DataWorks的參數做了簡單介紹,那麼如果我們想獲得更加定制化的參數怎麼辦。比如在一個資料同步任務裡需要Unix時間戳。這種場景并不是我空想出來的,在有些業務資料庫中并沒有存儲datetime類型的時間字段,這種時候想增量同步資料到ODPS不管是系統參數還是自定義參數都無法實作。

解決方案

2.1 加字段

有一種簡單粗暴的辦法就是讓開發在業務資料庫表中加上datetime字段,這樣就能利用上DataWorks提供的系統參數或者自定義參數來解決。

2.2 腳本處理

不将任務配置在DataWorks上,而是通過MaxCompute Studio或者ODPSCMD工具與MaxCompute互動,在腳本裡将解析Unix時間戳取出資料後再上傳。

2.3 指派節點

終于來到本文重點,上述兩種辦法的确能解決問題,但會額外增加多餘的開銷。加字段增加了開發成本,而且對業務沒有幫助,開發不見得樂意幫你做。通過腳本處理會導緻任務節點的依賴關系不好關聯,在DataWorks管轄範圍之外又多了一批腳本需要管理,互相之間的依賴幾乎無解。

所幸DataWorks提供了指派節點功能,如何建立指派節點不再贅述,在資料開發裡很容易找到。直接實戰上代碼:

通過SHELL指派

yesterday_d=`date -d "-1 day" "+%Y-%m-%d 00:00:00"` #取昨天時間
timeStamp_yd=`date -d "$yesterday_d" +%s`   #取昨天的10時間戳
today_d=`date "+%Y-%m-%d 00:00:00"`
timeStamp_td=`date -d "$today_d" +%s`
echo $timeStamp_yd"000",$timeStamp_td"000"     #改成13位時間戳
           

通過SQL指派

SELECT  UNIX_TIMESTAMP(TO_DATE('${bdp.system.bizdate}','yyyymmdd'))*1000
,UNIX_TIMESTAMP(DATEADD(TO_DATE('${bdp.system.bizdate}','yyyymmdd'),1,'dd' ))*1000;
           

可以看到指派節點是取到了代碼中的最後一條echo、select、print裡的結果。不過下遊節點在調用時會有些不一樣。

  • SHELL指派傳給下遊節點的是一個一維數組,需要這樣調用:

    ${input[0]}

    ${input[1]}

    ;
  • SQL指派傳給下遊節點的參數是一個二維數組,需要這樣調用:

    ${input[0][0]}

    ${input[0][1]}

    ;
  • Python指派傳給下遊節點的同SHELL,也是一維數組,調用方式相同。

既然是數組,顯然并不是一定要調用到元素那一層,直接

${input}

也是支援的,兩個參數會用逗号隔開組成一個完整字元串被調用。

三、後話

這是僅作抛磚引玉,用時間戳的例子來展示如何使用指派節點在為任務傳參。顯然你可以利用SHELL、ODPS SQL、Python創造出你想要的任意參數,然後通過做好上下遊任務依賴,配置上下文參數傳遞的方式傳給下遊節點。如何傳遞這裡就不再示範了,可自行查閱官方文檔。

繼續閱讀