用Crontab打造简易工作流引擎
1. 引言
众所周知,Oozie(1, 2)是基于时间条件与数据生成来做工作流调度的,但是Oozie的数据触发条件只支持HDFS路径,故而面临着这样的问题:
- 无法判断Hive partition是否已存在;
- 无法判断Elasticsearch index是否已写入完成;
- ...
因此,灵活可扩展的工作流引擎才是正确姿势!下面,我将介绍如何用Crontab来打造一个类似于Oozie的简易工作流引擎;对标Oozie,其应满足功能:
- 时间条件与数据生成触发任务,如Oozie coordinator的
datasets与input-events; - 支持触发条件的轮询;
- 支持任务并行执行,如Oozie workflow的
fork与join; - 捕获错误及运行状态日志。
2. 实现
触发条件
判断Hive partition是否已存在,思路比较简单——show partitions <tb_name>后能否grep到该partition:
# check wheter $1's partition ($2) exists
hive_partition_exists() {
table_name=$1
partition=$2
hive -e "show partitions ${table_name}" | grep ${partition}
[ $? == 0 ]
}
获取Hive 表的最后一个partition,grep命令配合正则表达式中的Lookahead匹配:
# get latest hive partition
latest_hive_partition() {
table_name=$1
partition_name=$2
hive -e "show partitions ${table_name}" | tail -1 | grep -Po "(?<=${partition_name}=).*"
}
在检查ES index是否写入完成时,可用思路——定时flush index,然后判断当前时刻的doc数较上一时刻是否发生变化;若变化,则说明正在写入。Shell脚本处理json太蛋疼了,故不给出代码啦。
条件轮询
所谓“条件轮询”,是指如果数据未生成,则会一直轮询该条件是否满足。我们采用while循环中sleep的方式来实现条件轮询:
hive_partition_exists etl.ad_tb1 ${log_partition}
ad1_exists=$?
hive_partition_exists etl.ad_tb2 ${log_partition}
ad2_exists=$?
while (( ${ad1_exists} != 0 || ${ad2_exists} != 0))
do
echo "`date -d "now"`: log partitions ${log_partition} not exist, and waiting" >> ${log_path}
sleep 1m
hive_partition_exists etl.ad_tb1 ${log_partition}
ad1_exists=$?
hive_partition_exists etl.ad_tb2 ${log_partition}
ad2_exists=$?
done
实例
接下来,以Hive写Elasticsearch的为例,说明如何用crontab做定时Hive任务。hiveql脚本如下:
add jar /path/to/jars/elasticsearch-hadoop-2.3.1.jar;
set mapred.job.name=ad_tag-${LOG_PARTITION}~~${TAG_PARTITION};
set hive.map.aggr = false;
insert overwrite table ad_tag
select media, a.dvc as dvc, case when c1_arr is null then array('empty') else c1_arr end as c1_arr, '${LOG_PARTITION}' as week_time
from (
select dvc, app_name as media
from ad_log
where is_exposure = '1' and day_time between date_sub('${LOG_PARTITION}', 6) and '${LOG_PARTITION}'
group by dvc, app_name
) a
left outer join (
select dvc, collect_set(c1) as c1_arr
from tag
lateral view inline(tag) in_tb
where day_time = '${TAG_PARTITION}'
group by dvc
) b
on a.dvc = b.dvc;
为了实现任务的并行执行,我用到Linux命令中的&:
log_partition=`date -d "5 day ago" "+%Y-%m-%d"`
tag_partition=$(latest_hive_partition tag.dmp_tag day_time)
log_path="${log_partition}.log"
echo "`date -d "now"`: log partitions ${log_partition} exist" >> ${log_path}
echo "`date -d "now"`: latest tag partition ${tag_partition}" >> ${log_path}
hive -f ad_tag1.hql --hivevar LOG_PARTITION=${log_partition} --hivevar TAG_PARTITION=${tag_partition} & hive -f ad_tag2.hql --hivevar LOG_PARTITION=${log_partition} --hivevar TAG_PARTITION=${tag_partition}
exit 1
PS: 当手动执行脚本是OK的,但是crontab去执行时却出错,最可能的原因是crontab未能正确加载用户的环境变量;故可以在运行脚本中加入:
source /etc/profile
source /path/to/.bashrc
但是,用crontab做工作流调度,会存在如下问题:
- 无法很好地管理任务之间的依赖关系;
- 无法更好地监控任务的运行状况;
- 因Shell脚本的编程处理能力的限制,无法更自由地做扩展。
用Crontab打造简易工作流引擎的更多相关文章
- 我的微型工作流引擎-功能解析及API设计
一.前言 上一篇我给大家介绍了我的工作流的模型和基本的设计,这篇我想详细说明下我这款工作流的功能及使用示例.这款工作流主要是面向开发者设计的,为了先让大家有个全局的认识,局部功能的设计实现就不细说了, ...
- Winform开发框架之简易工作流设计
一讲到工作流,很多人第一反应就是这个东西很深奥,有时候又觉得离我们较为遥远,确实完善的工作流设计很多方面,而正是由于需要兼顾很多方面,一般通用的工作流都难做到尽善尽美.微软也提供了几个版本的WF框架支 ...
- 《程序猿闭门造车》之NBPM工作流引擎 - 项目整体架构
前言: 又是一年一度的圣诞节,可这关我什么事呢 :( ,好不容易周末了,还是说说NBPM吧,前不久我发布了一篇关于工作流的文章:<程序猿闭门造车>之NBPM工作流引擎 - 开篇,很多爱好工 ...
- Winform开发框架之简易工作流设计(转自 伍华聪博客)
Winform开发框架之简易工作流设计 一讲到工作流,很多人第一反应就是这个东西很深奥,有时候又觉得离我们较为遥远,确实完善的工作流设计很多方面,而正是由于需要兼顾很多方面,一般通用的工作流都难做到尽 ...
- 工作流引擎Activiti与SpringBoot2整合--开源软件诞生17
开源ERP技术整合系列--第17篇 用日志记录"开源软件"的诞生 [点亮星标]----祈盼着一个鼓励 博主开源地址: 码云:https://gitee.com/redragon/r ...
- 工作流引擎Oozie(一):workflow
1. Oozie简介 Yahoo开发工作流引擎Oozie(驭象者),用于管理Hadoop任务(支持MapReduce.Spark.Pig.Hive),把这些任务以DAG(有向无环图)方式串接起来.Oo ...
- 【2016-11-7】【坚持学习】【Day22】【工作流引擎设计--执行用户】
最近在做一个工作流引擎,架构师已经设计好了,但是我发现他设计 每一步的用户集合的设计,有一定的不足,或者是不方便,不同的组织架构影响着他的用户数据源配置方式. 于是我想花点时间去看看人家优秀是工作流引 ...
- .net之工作流工程展示及代码分享(二)工作流引擎
在介绍完表单类的时候,接下来介绍工作流引擎,主要由四个类组成,分别是流程.流程步骤.流程实例.流程步骤实例类. 流程类: [Serializable] public class Flow { [Xml ...
- F2工作流引擎之-纯JS Web在线可拖拽的流程设计器(八)
Web纯JS流程设计器无需编程,完全是通过鼠标拖.拉.拽的方式来完成,支持串行.并行.分支.异或分支.M取N路分支.会签.聚合.多重聚合.退回.传阅.转交,都可以非常方便快捷地实现,管理员 ...
随机推荐
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- iOS开发之App间账号共享与SDK封装
上篇博客<iOS逆向工程之KeyChain与Snoop-it>中已经提到了,App间的数据共享可以使用KeyChian来实现.本篇博客就实战一下呢.开门见山,本篇博客会封装一个登录用的SD ...
- 小兔JS教程(四)-- 彻底攻略JS数组
在开始本章之前,先给出上一节的答案,参考答案地址: http://www.xiaotublog.com/demo.html?path=homework/03/index2 1.JS数组的三大特性 在J ...
- PHP设计模式(二)工厂方法模式(Factory Method For PHP)
简单工厂简述: 简单工厂模式实现了生产产品类的代码跟客户端代码分离,在工厂类中你可以添加需要生成长跑的逻辑代码(new 产品类),但是问题来了,优秀的代码是符合"开闭原则"如果你要 ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- CentOS 7 修改主机名
今天在阿里云上买了一个centos7的服务器,连接上以后,发现一个很长很长的主机名,看着让人很是不爽,就想着怎样将其改成一个有个性的名字. 这里我想说的是,在centos7 版本的linux系统上和c ...
- APP并非一个人在战斗,还有API—Xamarin.Android回忆录
前言 一般来说,一个客户端APP并非独立存在的,很多时候需要与服务器交互.大体可分为两方面的数据,常规字符串数据和文件数据,因为这两种数据很可能传输方式不一样,比如字符串之类的数据,使用HTTP协议, ...
- Ubuntu14.04配置Mono+Jexus
总所周知,ASP.NET是微软公司的一项技术,是一个网站服务端开发的一种技术,它可以在通过HTTP请求文档时再在Web服务器上动态创建它们,就是所谓动态网站开发,它依赖运行于 IIS 之中的程序 .但 ...
- 腾讯云上免费部署HTTPS
接上篇<腾讯云下安装 nodejs + 实现 Nginx 反向代理>,想从头一步到位的同学建议从上篇文章开始阅读.本文将继续介绍如何通过 Nginx 免费部署HTTPS. 留意下,这里的“ ...
- 剁手党也有春天 -- 淘宝 UWP ”比较“功能诞生记
前言 网购已经不再是现在的时髦,而变成了我们每天的日常生活.上网已经和买买买紧密地联系在了一起,成为了我们的人生信条.而逛街一词,越来越多地变成了一种情怀.有时候我们去逛街,要么是为了打发时间,要么是 ...