咨询Oozie是否支持跨Action传递变量
嘿,作为Oozie新手碰到这个需求太正常了,放心,Oozie完全支持在不同Action之间传递变量,刚好适配你每周运行、跨Action复用计算值的场景!下面给你讲两种最常用的实现方式:
1. 利用Action的输出属性(Output Properties)
这是动态传递计算值的首选方案,核心思路是:第一个Action把计算结果写入HDFS上的一个文本文件(格式为key=value),然后在Workflow配置中声明这个Action的输出属性,后续Action就可以通过EL表达式直接引用。
举个具体的例子,假设你用Shell Action做计算:
<action name="calculate-weekly-values"> <shell xmlns="uri:oozie:shell-action:0.1"> <job-tracker>${jobTracker}</job-tracker> <name-node>${nameNode}</name-node> <!-- 你的计算脚本,比如计算本周数据总量 --> <exec>compute_weekly_stats.sh</exec> <!-- 让脚本把结果写入HDFS的output.txt文件 --> <argument>/user/oozie/workflows/weekly-job/output.txt</argument> <!-- 声明输出属性:从output.txt中读取`weekly_total`这个key对应的值,绑定到变量`weekly_total` --> <output to="weekly_total">/user/oozie/workflows/weekly-job/output.txt</output> </shell> <ok to="process-with-value"/> <error to="job-fail"/> </action>
你的Shell脚本compute_weekly_stats.sh最后要输出符合格式的内容到指定文件,比如:
# 假设计算得到本周总量是12500 echo "weekly_total=12500" > $1
然后在后续的Action(比如Hive Action)里,就可以直接用${weekly_total}引用这个值:
<action name="process-with-value"> <hive xmlns="uri:oozie:hive-action:0.2"> <job-tracker>${jobTracker}</job-tracker> <name-node>${nameNode}</name-node> <script>process_weekly_data.hql</script> <!-- 把变量传递给Hive脚本 --> <param>WEEKLY_TOTAL=${weekly_total}</param> </hive> <ok to="end"/> <error to="job-fail"/> </action>
注意事项:
- 输出文件必须放在Oozie能访问的HDFS路径下,权限要设置正确(比如Oozie用户有读写权限)
- 输出文件每行只能是一个
key=value对,多个值可以写多行 - 变量名要避免和Oozie内置变量冲突
2. 全局Job Properties(适合静态/全局变量)
如果是一些不需要动态计算的全局变量(比如每周运行的固定参数),可以直接在job.properties文件中定义,或者在Workflow的<global>标签里声明,整个Workflow的所有Action都能直接引用:
比如在job.properties里:
jobTracker=your-job-tracker-url nameNode=hdfs://your-nn-url weekly_report_date=2024-05-20
然后在Action里直接用${weekly_report_date}即可。但如果是第一个Action动态计算的值,还是推荐用第一种方案。
适配你每周运行的场景
因为你的任务是每周调度,大概率会用到Oozie Coordinator。如果是在Coordinator中需要引用Workflow里的变量,还可以用Coordinator的EL表达式:
<action name="trigger-weekly-workflow"> <workflow> <app-path>/user/oozie/workflows/weekly-job</app-path> <configuration> <!-- 传递Coordinator参数到Workflow --> <property> <name>schedule_date</name> <value>${coord:formatTime(coord:nominalTime(), 'yyyy-MM-dd')}</value> </property> </configuration> </workflow> </action>
Workflow内部依然可以用前面的方式传递动态计算的变量,完全兼容。
内容的提问来源于stack exchange,提问作者Leo Prince

