Oozie工作流中两个Hive2 Action如何共享同一启动时间戳
嘿,我来帮你搞定这个Oozie工作流传递统一启动时间戳的问题!咱们先理清楚你遇到的坑,再给你靠谱的解决方案:
核心问题分析
你现在的几个问题本质上都是时间戳初始化时机不对:
- 全局
<configuration>里写${timestamp()},Oozie会把它当成需要手动输入的外部参数,所以Hue会弹窗要你填; - 用
wf:conf('execution_start')拿不到值,是因为这个参数根本没被正确初始化(Oozie一直在等你输入,自然是NULL); - 每个Action单独用
${timestamp()},那肯定会不一样啊——两个Action执行有时间差,计算出来的时间戳当然会有区别。
正确解决方案:让时间戳只在启动时计算一次
要让两个Hive2 Action用同一个启动时间戳,关键是让这个值在工作流刚启动时就计算好,然后全局共享给所有后续步骤。这里有两种靠谱的实现方式:
方式1:在<start>节点初始化全局参数
直接在工作流的启动节点里把时间戳算好,这样整个工作流生命周期里这个值都不会变:
<?xml version="1.0" encoding="UTF-8"?> <workflow-app xmlns="uri:oozie:workflow:0.5" name="workflow.xml"> <global> <job-tracker>host1:1234</job-tracker> <name-node>hdfs://myhost:4312</name-node> </global> <!-- 在这里初始化时间戳,工作流启动时仅计算一次 --> <start to="script1"> <param>execution_start=${timestamp()}</param> </start> <action name="script1"> <hive2 xmlns="uri:oozie:hive2-action:0.2"> <jdbc-url>jdbc:hive2://myhost:10/default</jdbc-url> <script>script1.hql</script> <param>execution_start=${execution_start}</param> </hive2> <ok to="script2" /> <error to="fail" /> </action> <action name="script2"> <hive2 xmlns="uri:oozie:hive2-action:0.2"> <jdbc-url>jdbc:hive2://myhost:10/default</jdbc-url> <script>script2.hql</script> <param>execution_start=${execution_start}</param> </hive2> <ok to="end" /> <error to="fail" /> </action> <kill name="fail"> <message>Sub workflow failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message> </kill> <end name="end" /> </workflow-app>
方式2:用全局<parameters>标签定义初始化
另一种方式是在工作流根节点下加<parameters>,直接把时间戳参数的默认值设为${timestamp()},Oozie启动时会自动计算这个值,不用你手动输入:
<?xml version="1.0" encoding="UTF-8"?> <workflow-app xmlns="uri:oozie:workflow:0.5" name="workflow.xml"> <!-- 全局参数定义,启动时自动计算时间戳 --> <parameters> <parameter>execution_start=${timestamp()}</parameter> </parameters> <global> <job-tracker>host1:1234</job-tracker> <name-node>hdfs://myhost:4312</name-node> </global> <start to="script1" /> <action name="script1"> <hive2 xmlns="uri:oozie:hive2-action:0.2"> <jdbc-url>jdbc:hive2://myhost:10/default</jdbc-url> <script>script1.hql</script> <param>execution_start=${execution_start}</param> </hive2> <ok to="script2" /> <error to="fail" /> </action> <action name="script2"> <hive2 xmlns="uri:oozie:hive2-action:0.2"> <jdbc-url>jdbc:hive2://myhost:10/default</jdbc-url> <script>script2.hql</script> <param>execution_start=${execution_start}</param> </hive2> <ok to="end" /> <error to="fail" /> </action> <kill name="fail"> <message>Sub workflow failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message> </kill> <end name="end" /> </workflow-app>
验证一下
修改完工作流后,你可以在Hive脚本里直接用${execution_start}引用这个时间戳,比如:
-- script1.hql 示例 INSERT INTO table1 SELECT *, '${execution_start}' as workflow_start_time FROM source_table;
执行完后去查两个脚本插入的数据,workflow_start_time的值肯定是完全一样的,都是工作流启动那一刻的时间戳。
内容的提问来源于stack exchange,提问作者nessa.gp
相关产品推荐
相关产品推荐

