Airflow入门和运行常用命令

96
什锦甜
1.1 2018.03.31 10:36* 字数 1703

什么是Airflow?

Airflow 是一个使用 python 语言编写的 data pipeline 调度和监控工作流的平台。Airflow 被 Airbnb 内部用来创建、监控和调整数据管道。任何工作流都可以在这个使用 Python 来编写的平台上运行。Airflow是通过DAG(Directed acyclic graph)来管理任务流程的任务调度工具,她不需要知道业务数据的具体内容,设置任务的依赖关系实现任务调度。

这个平台拥有和 Hive、Presto、MySQL、HDFS、Postgres 和 S3 交互的能力,并且提供了钩子(hook)使得系统拥有很好地扩展性。除了一个命令行界面,该工具还提供了一个基于 Web 的用户界面让您可以可视化管道的依赖关系、监控进度、触发任务等。

Airflow 的架构

在一个可扩展的生产环境中,Airflow 含有以下组件:

  • 一个元数据库(MySQL 或 Postgres)
  • 一组 Airflow 工作节点
  • 一个调节器(Redis 或 RabbitMQ)
  • 一个 Airflow Web 服务器


    Airflow Scheduler

功能简介

Function

任务依赖

通常,在一个运维系统,数据分析系统,或测试系统等大型系统中,我们会有各种各样的依赖需求。比如:

  • 时间依赖:任务需要等待某一个时间点触发。
  • 外部系统依赖:任务依赖 Mysql 中的数据,HDFS 中的数据等等,这些不同的外部系统需要调用接口去访问。
  • 机器依赖:任务的执行只能在特定的某一台机器的环境中,可能这台机器内存比较大,也可能只有那台机器上有特殊的库文件。
  • 任务间依赖:任务 A 需要在任务 B 完成后启动,两个任务互相间会产生影响。
  • 资源依赖:任务消耗资源非常多,使用同一个资源的任务需要被限制,比如跑个数据转换任务要10个 G,机器一共就30个 G,最多只能跑两个,我希望类似的任务排个队。
  • 权限依赖:某种任务只能由某个权限的用户启动。
    也许大家会觉得这些是在任务程序中的逻辑需要处理的部分,但是我认为,这些逻辑可以抽象为任务控制逻辑的部分,和实际任务执行逻辑解耦合。

Airflow的处理依赖的方式

Airflow 和crontab不同。crontab 可以很好地处理定时执行任务的需求,它是一种依赖管理系统,而且只管理时间上的依赖。Airflow 的核心概念,是 DAG (有向无环图),DAG 由一个或多个 TASK 组成,而这个 DAG 正是解决了上文所说的任务间依赖。Task A 执行完成后才能执行 Task B,多个Task之间的依赖关系可以很好的用DAG表示完善。

Airflow 完整的支持 crontab 表达式,也支持直接使用 python 的 datatime 表述时间,还可以用 datatime 的 delta 表述时间差。这样可以解决任务的时间依赖问题。

Airflow 在 CeleryExecuter 下可以使用不同的用户启动 Worke r,不同的 Worker 监听不同的 Queue ,这样可以解决用户权限依赖问题。Worker 也可以启动在多个不同的机器上,解决机器依赖的问题。

Airflow 可以为任意一个 Task 指定一个抽象的 Pool,每个 Pool 可以指定一个 Slot 数。每当一个 Task 启动时,就占用一个 Slot ,当 Slot 数占满时,其余的任务就处于等待状态。这样就解决了资源依赖问题。

Airflow 中有 Hook 机制(其实我觉得不应该叫 Hook ),作用时建立一个与外部数据系统之间的连接,比如 Mysql,HDFS,本地文件系统(文件系统也被认为是外部系统)等,通过拓展 Hook 能够接入任意的外部系统的接口进行连接,这样就解决的外部系统依赖问题。

Airflow的命令

  • airflow webserver -p 8080 打开webserver
  • airflow scheduler 调度器,必须启动,不然dag没法run起来(使用CeleryExecutor、LocalExecutor时)
  • airflow run dagid [time] run task instance
  • airflow backfill [dagid] -s[startTime] -e [endTime] run a backfill over 2 days
run的demo
# run your first task instance
airflow run example_bash_operator runme_0 2018-01-11

# run a backfill over 2 days
airflow backfill example_bash_operator -s 2018-01-10 -e 2018-01-11

基于CeleryExecutor方式的系统架构

基于CeleryExecutor方式的系统架构
使用celery方式的系统架构图(官方推荐使用这种方式,同时支持mesos方式部署)。turing为外部系统,GDags服务帮助拼接成dag,可以忽略。
1.master节点webui管理dags、日志等信息。scheduler负责调度,只支持单节点,多节点启动scheduler可能会挂掉
2.worker负责执行具体dag中的task。这样不同的task可以在不同的环境中执行。

celery executor

基于LocalExecutor方式的系统架构图

另一种启动方式的思考,一个dag分配到1台机器上执行。如果task不复杂同时task环境相同,可以采用这种方式,方便扩容、管理,同时没有master单点问题。


local executor

从安装airflow到成功运行,踩了很多坑,凭借着回忆简单记录一下。

运行常用命令

  • Initialize the db 第一次安装完初始化airflow
    airflow initdb
  • 开启webserver,登陆网页http://localhost:8080可以看到dag运行状况
    airflow webserver --port 8080
  • test the 单个DAG
$ python airflow_dag.py #先编译python
编译成功之后test:
#格式:airflow test dag_id task_id execution_time
$ airflow test airflow_tutorial print_world 2017-07-01
  • 测试成功之后运行
#开启调度任务器
$ airflow scheduler 
# 开始运行任务
$ airflow trigger {$dag}.py
这一步也可以在web界面点trigger按钮

一点总结

我用airflow执行的任务是从一个数据库中同步数据到另一个数据库。本来想用airflow里的hook连数据库,进行同步,但是程序死卡在running死活不运行。这样研究了好久也没研究出来原因。网上关于airflow的文档都停留在介绍和入门,很少有实际运行的例子。
后来才发现,其实没必要非去使用airflow连数据库的方法。airflow相当于一个工具,一个嵌入在python文件中的工具。所以在写airflow时,其他部分功能定义正常写,连数据库啊,分割字符串啊,这些都按照python里的方法来写就可以了,最后再用airflow定义task前后依赖关系。
搞清楚这点,就会发现其实airflow非常好用。

Airflow