Q 未使用Oozie 系统参数之前弊端
补历史数据,只能通过脚本中循环遍历方式,成本高、耗时长、未使用并行或并行比较麻烦。
A 调研实践Hue Oozie 自带的系统常量。
实践:通过尝试使用不同参数寻找适合使用的参数及使用方法,如何计算出多种多样的参数结果。
过程:
创建hive脚本: test_coord_date
创建WorkFlow(工作流): test_coord_date_wk
创建Schedule(调度): test_coord_date_tm 选择工作流test_coord_date_wk
1 hive脚本中自定义变量(test_coord_date )
create table if not exists default.test_coord_date(
`to_date` string COMMENT '统计日期' ,--$ {coord:formatTime(coord:nominalTime(),'yyyy-MM-dd')} $之前实际使用无空格
`stat_date` string COMMENT ' 统计日期前一日,T1分区', --$ {coord:formatTime(coord:dateOffset(coord:nominalTime(), -1,'DAY'),'yyyy-MM-dd')}
`today` string COMMENT '永远是当前日期(系统当前日期)'--$ {coord:formatTime(coord:actualTime(),'yyyy-MM-dd')}
) COMMENT '系统常量使用'
PARTITIONED BY (`dt` string)
stored as parquet
tblproperties ("parquet.compression"="lzo");
insert overwrite table default.test_coord_date partition(dt='${dt}')
select '${to_date}' ,'${stat_date}','${today}'
2 WorkFlow-test_coord_date_wk传静态参数
需创建出需要传递的参数名称 dt、to_date、stat_date、today
3 Schedule-test_coord_date_tm 动态参数获取系统常量(可计算和定义格式)
为需要传递的参数填写对应的变量值:
${coord:formatTime(coord:dateOffset(coord:nominalTime(), -1,'DAY'),'yyyy-MM-dd')}
${coord:formatTime(coord:nominalTime(),'yyyy-MM-dd')}
${coord:formatTime(coord:dateOffset(coord:nominalTime(), -1,'DAY'),'yyyy-MM-dd')}
${coord:formatTime(coord:actualTime(),'yyyy-MM-dd')}
4 最终结果:
5 补历史可开启并行,设置并行数
6 Oozie 常用的系统常量
常量使用公式 | 含义说明 |
---|---|
${coord:minutes(int n)} | 返回日期时间:从一开始,周期执行n分钟 |
${coord:hours(int n)} | 返回日期时间:从一开始,周期执行n * 60分钟 |
${coord:days(int n)} | 返回日期时间:从一开始,周期执行n * 24 * 60分钟 |
${coord:months(int n)} | 返回日期时间:从一开始,周期执行n * M * 24 * 60分钟(M表示一个月的天数) |
${coord:endOfDays(int n)} | 返回日期时间:从当天的最晚时间(即下一天)开始,周期执行n * 24 * 60分钟 |
${coord:endOfMonths(1)} | 返回日期时间:从当月的最晚时间开始(即下个月初),周期执行n * 24 * 60分钟 |
${coord:current(int n)} | 返回日期时间:从一个Coordinator动作(Action)创建时开始计算,第n个dataset实例执行时间 |
${coord:dataIn(String name)} | 在输入事件(input-events)中,解析dataset实例包含的所有的URI |
${coord:dataOut(String name)} | 在输出事件(output-events)中,解析dataset实例包含的所有的URI |
${coord:offset(int n, String timeUnit)} | 表示时间偏移,如果一个Coordinator动作创建时间为T,n为正数表示向时刻T之后偏移,n为负数向向时刻T之前偏移,timeUnit表示时间单位(选项有MINUTE、HOUR、DAY、MONTH、YEAR) |
${coord:hoursInDay(int n)} | 指定的第n天的小时数,n>0表示向后数第n天的小时数,n=0表示当天小时数,n<0表示向前数第n天的小时数 |
${coord:daysInMonth(int n)} | 指定的第n个月的天数,n>0表示向后数第n个月的天数,n=0表示当月的天数,n<0表示向前数第n个月的天数 |
${coord:tzOffset()} | ataset对应的时区与Coordinator Job的时区所差的分钟数 |
${coord:latest(int n)} | 最近以来,当前可以用的第n个dataset实例 |
${coord:future(int n, int limit)} | 当前时间之后的dataset实例,n>=0,当n=0时表示立即可用的dataset实例,limit表示dataset实例的个数 |
${coord:nominalTime()} | nominal时间等于Coordinator Job启动时间,加上多个Coordinator Job的频率所得到的日期时间。例如:start=”2009-01-01T24:00Z”,end=”2009-12-31T24:00Z”,frequency=”{coord:days(1)},则nominal时间为:2009-01-02T00:00Z、2009-01-03T00:00Z、2009-01-04T00:00Z、…、2010-01-01T00:00Z |
${coord:actualTime()} | Coordinator动作的实际创建时间。例如:start=”2011-05-01T24:00Z”,end=”2011-12-31T24:00Z”,frequency=”${coord:days(1)}”,则实际时间为:2011-05-01,2011-05-02,2011-05-03,…,2011-12-31 |
${coord:user()} | 启动当前Coordinator Job的用户名称 |
${coord:dateOffset(String baseDate, int instance, String timeUnit)} | 计算新的日期时间的公式:newDate = baseDate + instance * timeUnit,如:baseDate=’2009-01-01T00:00Z’,instance=’2′,timeUnit=’MONTH’,则计算得到的新的日期时间为’2009-03-01T00:00Z’。 |
${coord:formatTime(String timeStamp, String format)} | 格式化时间字符串,format指定模式 |
成果:
通过调研和实践,熟悉整个系统常量使用方法和条件并掌握,然后应用到实际的开发中,补历史数据方便快捷,不易出错,灵活开启并行,设置并行数。