在前几篇博客我已将绘制WorkFlow的工作事件都已经设计好了。这里总结一下如何将这些事件一起组成一个WorkFlow工作流,并且会讲一些绘制工作流的注意事项。
首先要注意我们添加的任何一个中间的事件这里有两种情况,分别是 DOCUMENTS 与 ACTIONS :
DOCUMENTS :
ACTIONS :
也很好理解,DOCUMENTS中添加的事件都是之前我们在Oozie中已经编辑好的那些文件,而ACTIONS添加的则需要我们在这里自己写清指令。
1、开始绘制任务要求的WorkFlow
介绍一下这个WorkFlow的具体工作内容,要解决每小时从MySQL产生的数据增量更新到Hive中,并且更新数据后在hive中将几个表进行数据的汇总与整理,筛除掉各自表中不需要的数据。最后将这个汇总好的表 'trace' 导出到MySQL中,实现按照小时实时更新。
A.通过ACTIONS中的sqoop添加import表事件:
sqoop导入指令:
sqoop import --connect "jdbc:mysql://192.168.102.18:3306/school?useUnicode=true&characterEncoding=utf-8" --username root --password P@ssw0rd4321 --driver com.mysql.jdbc.Driver --query 'select * from snap_match where alarmTime>date_sub(date_format(now(), "%Y-%m-%d %H"), interval 1 hour) and alarmTime<date_format(now(), "%Y-%m-%d %H") and $CONDITIONS' --target-dir /user/activemq_topic/snap_match/$date_today/$hour --fields-terminated-by '\t' --lines-terminated-by '\n' --null-string '\\N' --null-non-string '\\N' --m 1;
这个直接按住拖动到特定的矩形框就可以了。并且并行执行3个sqoop导入事件。为什么这里不能使用DOCUMENTS中是sqoop事件我在这篇博客中介绍过: 使用hue中的sqoop导入数据被killed
B.在各自的sqoop导入事件后配置DOCUMENTS的Hive加载事件:
hive的load指令:
load data inpath "/user/activemq_topic/snap_match/${date_today}/${hour}" overwrite into table activemq_topic.snap_match_copy partition (datet='${date_today}',hours='${hour}')
之前就写在文件中:
C.数据导入并加载后再进行数据的汇总与导出
其中hive的汇总数据如下:
insert overwrite table activemq_topic.trace_copy partition(datet='${date_today}',hours='${hour}')
SELECT h.credentialsNum num,h.humanName xm,type,indexCode,alarmTime,SUBSTR(s.alarmTime,0,10) as date,SUBSTR(s.alarmTime,11,3) as timeHour,s.bkgpicurl as detail,'抓拍机' as fromType
FROM activemq_topic.snap_match_copy s LEFT JOIN activemq_topic.humans h ON s.humanId = h.humanId
WHERE `datet`='${date_today}' AND `hours`='${hour}'
union all
SELECT XXX ....................
union all
SELECT XXX ....................
union all
SELECT XXX ....................;
sqoop导出指令:
sqoop export --connect "jdbc:mysql://192.168.102.18:3306/school?useUnicode=true&characterEncoding=utf-8" --username root --password P@ssw0rd4321 --table trace --fields-terminated-by '\001' --input-null-string '\\N' --input-null-non-string '\\N' --export-dir /user/hive/warehouse/activemq_topic.db/trace_copy/datet=${date_today}/hours=${hour};
这样就绘制好我所需的WorkFlow。
2、配置schedule定期执行WorkFlow
A.首先创建一个schedule
B.选择我们要定期执行的WorkFlow
这里我之前绘制的是Trace_As_Hour_Workflow这个工作流。
C.选择执行的时间,记得调整时区
注意:这里一定记得要调整时区,好像默认的是洛杉矶的当地时间。如果不修改到Shanghai则会发现调用的时间总是会推迟几小时。
D.设定传入的参数
这个参数会自动从配置的Workflow中获取,之前绘制的时候各个事件添加的参数这里给他赋值即可。
我这里只需要传入一个当前日期的 date_today,格式 'yyyy-MM-dd' 与上一小时数的 hour,格式 'HH'。
date_today参数:(当天日期)
${coord:formatTime(coord:nominalTime(), 'yyyy-MM-dd')}
hour参数:(上一小时数)
${coord:formatTime(coord:dateOffset(coord:nominalTime(), -1, 'HOUR'), 'HH')}
拓展:这个参数怎么来的可以参考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的频率所得到的日期时间。 |
${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指定 |
3、执行测试
我们将schedule启动后过段时间可以在这里看到运行的情况,都是成功的:
MySQL数据库中的trace的表也会按照小时增量更新: