灵活可扩展的工作流管理平台Airflow
1. 引言
Airflow是Airbnb开源的一个用Python写就的工作流管理平台(workflow management platform)。在前一篇文章中,介绍了如何用Crontab管理数据流,但是缺点也是显而易见。针对于Crontab的缺点,灵活可扩展的Airflow具有以下特点:
- 工作流依赖关系的可视化;
- 日志追踪;
- (Python脚本)易于扩展
对比Java系的Oozie,Airflow奉行“Configuration as code”哲学,对于描述工作流、判断触发条件等全部采用Python,使得你编写工作流就像在写脚本一样;能debug工作流(test backfill命令),更好地判别是否有错误;能更快捷地在线上做功能扩展。Airflow充分利用Python的灵巧轻便,相比之下Oozie则显得笨重厚拙太多(其实我没在黑Java~~)。《What makes Airflow great?》介绍了更多关于Airflow的优良特性;其他有关于安装、介绍的文档在这里、还有这里。
下表给出Airflow(基于1.7版本)与Oozie(基于4.0版本)对比情况:
功能 | Airflow | Oozie |
---|---|---|
工作流描述 | Python | xml |
数据触发 | Sensor | datasets, input-events |
工作流节点 | operator | action |
完整工作流 | DAG | workflow |
定期调度 | DAG schedule_interval | coordinator frequency |
任务依赖 | >> , << |
<ok to> |
内置函数、变量 | template macros | EL function, EL constants |
之前我曾提及Oozie没有能力表达复杂的DAG,是因为Oozie只能指定下流依赖(downstream)而不能指定上流依赖(upstream)。与之相比,Airflow就能表示复杂的DAG。Airflow没有像Oozie一样区分workflow与coordinator,而是把触发条件、工作流节点都看作一个operator,operator组成一个DAG。
2. 实战
Airflow常见命令如下:
- initdb,初始化元数据DB,元数据包括了DAG本身的信息、运行信息等;
- resetdb,清空元数据DB;
- list_dags,列出所有DAG;
- list_tasks,列出某DAG的所有task;
- test,测试某task的运行状况;
- backfill,测试某DAG在设定的日期区间的运行状况;
- webserver,开启webserver服务;
- scheduler,用于监控与触发DAG。
下面将给出如何用Airflow完成data pipeline任务。
首先简要地介绍下背景:定时(每周)检查Hive表的partition的任务是否有生成,若有则触发Hive任务写Elasticsearch;然后等Hive任务完后,执行Python脚本查询Elasticsearch发送报表。但是,Airflow对Python3支持有问题(依赖包为Python2编写);因此不得不自己写HivePartitionSensor
:
# -*- coding: utf-8 -*-
# @Time : 2016/11/29
# @Author : rain
from airflow.operators import BaseSensorOperator
from airflow.utils.decorators import apply_defaults
from impala.dbapi import connect
import logging
class HivePartitionSensor(BaseSensorOperator):
"""
Waits for a partition to show up in Hive.
:param host, port: the host and port of hiveserver2
:param table: The name of the table to wait for, supports the dot notation (my_database.my_table)
:type table: string
:param partition: The partition clause to wait for. This is passed as
is to the metastore Thrift client,and apparently supports SQL like
notation as in ``ds='2016-12-01'``.
:type partition: string
"""
template_fields = ('table', 'partition',)
ui_color = '#2b2d42'
@apply_defaults
def __init__(
self,
conn_host, conn_port,
table, partition="ds='{{ ds }}'",
poke_interval=60 * 3,
*args, **kwargs):
super(HivePartitionSensor, self).__init__(
poke_interval=poke_interval, *args, **kwargs)
if not partition:
partition = "ds='{{ ds }}'"
self.table = table
self.partition = partition
self.conn_host = conn_host
self.conn_port = conn_port
self.conn = connect(host=self.conn_host, port=self.conn_port, auth_mechanism='PLAIN')
def poke(self, context):
logging.info(
'Poking for table {self.table}, '
'partition {self.partition}'.format(**locals()))
cursor = self.conn.cursor()
cursor.execute("show partitions {}".format(self.table))
partitions = cursor.fetchall()
partitions = [i[0] for i in partitions]
if self.partition in partitions:
return True
else:
return False
Python3连接Hive server2的采用的是impyla模块,HivePartitionSensor
用于判断Hive表的partition是否存在。写自定义的operator,有点像写Hive、Pig的UDF;写好的operator需要放在目录~/airflow/dags
,以便于DAG调用。那么,完整的工作流DAG如下:
# tag cover analysis, based on Airflow v1.7.1.3
from airflow.operators import BashOperator
from operatorUD.HivePartitionSensor import HivePartitionSensor
from airflow.models import DAG
from datetime import datetime, timedelta
from impala.dbapi import connect
conn = connect(host='192.168.72.18', port=10000, auth_mechanism='PLAIN')
def latest_hive_partition(table):
cursor = conn.cursor()
cursor.execute("show partitions {}".format(table))
partitions = cursor.fetchall()
partitions = [i[0] for i in partitions]
return partitions[-1].split("=")[1]
log_partition_value = """{{ macros.ds_add(ds, -2)}}"""
tag_partition_value = latest_hive_partition('tag.dmp')
args = {
'owner': 'jyzheng',
'depends_on_past': False,
'start_date': datetime.strptime('2016-12-06', '%Y-%m-%d')
}
# execute every Tuesday
dag = DAG(
dag_id='tag_cover', default_args=args,
schedule_interval='@weekly',
dagrun_timeout=timedelta(minutes=10))
ad_sensor = HivePartitionSensor(
task_id='ad_sensor',
conn_host='192.168.72.18',
conn_port=10000,
table='ad.ad_log',
partition="day_time={}".format(log_partition_value),
dag=dag
)
ad_hive_task = BashOperator(
task_id='ad_hive_task',
bash_command='hive -f /path/to/cron/cover/ad_tag.hql --hivevar LOG_PARTITION={} '
'--hivevar TAG_PARTITION={}'.format(log_partition_value, tag_partition_value),
dag=dag
)
ad2_hive_task = BashOperator(
task_id='ad2_hive_task',
bash_command='hive -f /path/to/cron/cover/ad2_tag.hql --hivevar LOG_PARTITION={} '
'--hivevar TAG_PARTITION={}'.format(log_partition_value, tag_partition_value),
dag=dag
)
report_task = BashOperator(
task_id='report_task',
bash_command='sleep 5m; python3 /path/to/cron/report/tag_cover.py {}'.format(log_partition_value),
dag=dag
)
ad_sensor >> ad_hive_task >> report_task
ad_sensor >> ad2_hive_task >> report_task
灵活可扩展的工作流管理平台Airflow的更多相关文章
- 工作流管理平台Airflow
Airflow 1. 引言 Airflow是Airbnb开源的一个用Python写就的工作流管理平台(workflow management platform).在前一篇文章中,介绍了如何用Cront ...
- 开源 C#工作流管理平台
{ font-family: 宋体; panose-1: 2 1 6 0 3 1 1 1 1 1 } @font-face { font-family: "Cambria Math" ...
- 【从零开始学BPM,Day1】工作流管理平台架构学习
[课程主题] 主题:5天,一起从零开始学习BPM [课程形式] 1.为期5天的短任务学习 2.每天观看一个视频,视频学习时间自由安排. [第一天课程] Step 1 软件下载:H3 BPM10.0全开 ...
- 一个实现浏览器网页与本地程序之间进行双向调用的轻量级、强兼容、可扩展的插件开发平台—PluginOK中间件
通过PluginOK中间件插件平台(原名本网通WebRunLocal)可实现在网页中的JavaScript脚本无障碍访问本地电脑的硬件.调用本地系统的API及相关组件,同时可彻底解决ActiveX组件 ...
- centos 7 OpenResty®(lua-nginx-module)搭建可扩展的Web平台
OpenResty®-英文官网地址:http://openresty.org/en/ OpenResty®-中文官网地址: http://openresty.org/cn/ OpenResty®> ...
- Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验
Net Core平台灵活简单的日志记录框架NLog初体验 前几天分享的"[Net Core集成Exceptionless分布式日志功能以及全局异常过滤][https://www.cnblog ...
- E8.Net 工作流二次开发架构平台
一. 产品简介 E8.Net工作流开发架构是基于微软.Net技术架构的工作流中间件产品,是国内商业流程管理(BPM)领域在.Net平台上的领先产品,是快速搭建流程管理解决方案的二次开 ...
- 面向服务体系架构(SOA)和数据仓库(DW)的思考基于 IBM 产品体系搭建基于 SOA 和 DW 的企业基础架构平台
面向服务体系架构(SOA)和数据仓库(DW)的思考 基于 IBM 产品体系搭建基于 SOA 和 DW 的企业基础架构平台 当前业界对面向服务体系架构(SOA)和数据仓库(Data Warehouse, ...
- AEAI Portal V3.5.2门户集成平台发版说明
AEAI Portal门户集成平台为数通畅联的核心产品,本着分享传递的理念,数通畅联将Portal_server.Portal_portlet两个项目开源,目的在于满足客户与伙伴的OEM需求,以及为广 ...
随机推荐
- C语言 · 阶乘计算 · 基础练习
问题描述 输入一个正整数n,输出n!的值. 其中n!=1*2*3*-*n. 算法描述 n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法.使用一个数组A来表示一个大整数a,A[0]表 ...
- 小白解决CENTOS7错误:Cannot find a valid baseurl for repo: base/7/x86_6
刚入手的MacBook想着学点东西,本汪还是决定玩玩CentOS服务器,安装好了VirtualBox + CentOS. 打开一看,懵逼了!命令行! 行吧,先装个图形界面: $sudo yum gro ...
- C#基础篇 - 理解委托和事件
1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具有相同签名方法的函数指针.简单理解,委托是一种可以把函数当做参数传递的类型.很多情况下,某 ...
- CentOS7 重置root密码
1- 在启动grub菜单,选择编辑选项启动 2 - 按键盘e键,来进入编辑界面 3 - 找到Linux 16的那一行,将ro改为rw init=/sysroot/bin/sh 4 - 现在按下 Con ...
- nodejs项目mysql使用sequelize支持存储emoji
nodejs项目mysql使用sequelize支持存储emoji 本篇主要记录nodejs项目阿里云mysql如何支持存储emoji表情. 因由 最近项目遇到用户在文本输入emoji进行存储的时候导 ...
- c#多线程
一.使用线程的理由 1.可以使用线程将代码同其他代码隔离,提高应用程序的可靠性. 2.可以使用线程来简化编码. 3.可以使用线程来实现并发执行. 二.基本知识 1.进程与线程:进程作为操作系统执行程序 ...
- AFNetworking 3.0 源码解读 总结(干货)(下)
承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...
- jQuery的属性
The Write Less , Do More ! jQuery的属性 1. attr(name|properties|key,value|fn) : 设置或返回被选元素的属性值 ①获取属性 < ...
- BPM端到端流程解决方案分享
一.需求分析 1.企业规模的不断发展.管理水平的不断提升,通常伴随着企业各业务板块管理分工更细.更专业,IT系统同样越来越多.越来越专 业化.不可避免的,部门墙和信息孤岛出现了,企业的流程被部门或者I ...
- 最新的 cocoaPods 安装方法
经过努力终于发现了最新的 解决cocoaPods安装的办法: taobao Gems 源已停止维护,现由 ruby-china 提供镜像服务 第一步:安装rvm, 不管需不需要升级ruby,rvm可以 ...