用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路分支.会签.聚合.多重聚合.退回.传阅.转交,都可以非常方便快捷地实现,管理员 ...
随机推荐
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
- 学习ASP.NET Core, 怎能不了解请求处理管道[3]: 自定义一个服务器感受一下管道是如何监听、接收和响应请求的
我们在<服务器在管道中的"龙头"地位>中对ASP.NET Core默认提供的具有跨平台能力的KestrelServer进行了介绍,为了让读者朋友们对管道中的服务器具有更 ...
- Android使用静默安装时碰见的问题
升级时碰见的异常 private void installPackage(String appName,final File apk) { if (!apk.exists()) { setHasNew ...
- 报错:You need to use a Theme.AppCompat theme (or descendant) with this activity.
学习 Activity 生命周期时希望通过 Dialog 主题测试 onPause() 和 onStop() 的区别,点击按钮跳转 Activity 时报错: E/AndroidRuntime: FA ...
- Linux设备管理(三)_总线设备的挂接
扒完了字符设备,我们来看看平台总线设备,平台总线是Linux中的一种虚拟总线,我们知道,总线+设备+驱动是Linux驱动模型的三大组件,设计这样的模型就是将驱动代码和设备信息相分离,对于稍微复杂一点的 ...
- 找到第k个最小元----快速选择
此算法借用快速排序算法. 这个快速选择算法主要利用递归调用,数组存储方式.包含3个文件,头文件QuickSelect.h,库函数QuickSelect.c,测试文件TestQuickSelect. 其 ...
- java中判断字符串是否为只包含数字
1.用Java自带的函数 public static boolean isNumeric(String str){ for(int i=str.length();--i>=0;){ if (!C ...
- bzoj1531: [POI2005]Bank notes
Description Byteotian Bit Bank (BBB) 拥有一套先进的货币系统,这个系统一共有n种面值的硬币,面值分别为b1, b2,..., bn. 但是每种硬币有数量限制,现在我 ...
- Web应用多账号系统设计及微信扫码登录实现
Web应用多账号系统设计及微信扫码登录实现 1 前言概述 公司对功能测试,性能测试,安全测试等等都做了比较好的自动化后,急需要一个MIS系统来统一管理这些结果及报表. 此MIS系统特点如下: 仅内 ...
- ASP.NET MVC 视图(四)
ASP.NET MVC 视图(四) 前言 上篇对于利用IoC框架对视图的实现进行依赖注入,最后还简单的介绍一下自定义的视图辅助器是怎么定义和使用的,对于Razor语法的细节和辅助器的使用下篇会说讲到, ...