目录

​1.安装Airflow​

​1.1安装简介​

​ 1.2安装须知​

​1.3安装准备​

​1.4 安装Python3.x​

​1.4.1安装Anaconda【方式1】​

​1.4.2安装指定版本Python【方式2】​

​1.4.3安装pip【python3可跳过】​

​1.5 安装airflow​

​1.5.1安装环境准备​

​1.5.2激活python虚拟环境​

​1.5.3开始安装​

​1.5.4生产环境安装运行模式​

​ 2.Airflow使用说明​

​2.1Airflow基本概念​

​2.2编写DAG文件流程​

​2.3编写DAG文件​

​2.4检查DAG定义文件正确性​

​2.5WebUI首页功能说明​

​2.5.1WebUI触发Dag任务​

​2.5.2首页DAGs表字段和图标说明​

​2.6查看DAG和Task执行情况​

​2.7Tree View操作Task任务​

​2.8Operator Example​

​2.8.1BashOperator​

​2.8.2SqoopOperator​

​2.8.3Spark​

​2.9自定义Operator 开发​

​2.10参考资料​



1.安装Airflow

1.1安装简介

Airflow是基于python开发的,推荐使用以下安装方式:

  1. Airflow支持python2、python3安装运行。
  2. 使用virtualenv虚拟环境安装airflow,避免多个python版本之间引起的不兼任问题。
  3. Python环境可以用Anaconda(优点:包含绝大部分常用Python依赖库,服务器不能联网安装的情况比较合适。缺点:安装包较大。)或者安装指定版本Python,两种方式根据情况选择安装方式。

 1.2安装须知

开始安装airflow之前需要知道和准备的

  1. Airflow在pip上已经更名为apache-airflow,下载最新版请使用后者pip install apache-airflow。
  2. Airflow 1.8版本依赖的是MySQL 5.6以上(5.6.24以上高版本可用),5.7以下报1071, u'Specified key was too long; max key length is 767 bytes,如果你使用MySQL作为你的airflow backend请升级你的MySQL到最新版。
  3. MySQL5.6 升级到5.7在使用airflow 时会报1146, u"Table 'performance_schema.session_variables' doesn't exist",执行mysql_upgrade -u root -p --force解决。
  4. Airflow的mysql driver使用的是mysqlclient mysql://root:@127.0.0.1/sqlalchemy_lab?charset=utf8,如果使用其他 driver将报syntax error。

1.3安装准备

Linux系统中建立airflow用户,以下安装基于此用户进行安装操作

useradd airflow

passwd airflow

su airflow

1.4 安装Python3.x

1.4.1安装Anaconda【方式1】

  • 下载 

 ​​Anaconda | Individual Edition​

  • 安装

下载后执行sh文件进行安装,按提示操作完成安装。

1.4.2安装指定版本Python【方式2】


1.4.2.1下载

cd /usr/local/src

wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz

tar zxf Python-3.6.5.tgz

cd Python-3.6.5

1.4.2.2编译安装

必须增加安装参数--with-ssl,否则后面pip安装提示找不到SSL

./configure --with-ssl

make && make install

python -v

1.4.2.3设置系统默认python3版本

Linux默认的python是2.X版本,改成系统默认使用python3.6,非必要,如需python3执行时指定python3命令的执行路径即可

mv /usr/bin/python /usr/bin/python2.back

ln -s /usr/local/bin/python3 /usr/bin/python

python -v

1.4.2.4修复yum报错问题

因为yum使用的是python2,替换python3之后可能导致无法正常工作,因此修改yum配置文件(vim /usr/bin/yum),  把文件头部的#!/usr/bin/python改成#!/usr/bin/python2.7保存退出即可

如果出现以下错误:

File "/usr/libexec/urlgrabber-ext-down", line 28

except OSError, e:

^

SyntaxError: invalid syntax

解决办法是修改

vim /usr/libexec/urlgrabber-ext-down

将/usr/bin/python改为/usr/bin/python2.7




1.4.3安装pip【python3可跳过】

ps:python3已默认安装pip,Anaconda自带pip,注意不是pip3。

1.4.3.1更换pip镜像

Anaconda更换源,加快下载速度

 

 ​

或安装时指定临时镜像

/usr/local/bin/pip install sqlmap -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

1.4.3.2安装pip

cd /usr/local/src

wget https://files.pythonhosted.org/packages/45/ae/8a0ad77defb7cc903f09e551d88b443304a9bd6e6f124e75c0fbbf6de8f7/pip-18.1.tar.gz

tar zxf pip-18.1.tar.gz

cd pip-18.1

#使用python3安装,上面已将python默认版本设置为python3,没有设置可以执行时指定python3命令路径执行如:

/usr/local/bin/python3

python setup.py install

1.5 安装airflow

1.5.1安装环境准备

  • yum安装依赖包

yum安装依赖库,使用Anaconda也需要安装,否则后面安装和init airflow db会不成功。

yum install xz gcc zlib zlib-devel openssl-devel sqlite-devel python-devel mysql-devel

yum install bzip2-devel ncurses-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel

  • 修改AIRFLOW_HOME 环境变量
mkdir -p /opt/airflow/{dags,logs,plugins}

echo "export AIRFLOW_HOME=/opt/airflow" >> /etc/profile

source /etc/profile

cd /opt/airflow

  • Python虚拟环境

推荐使用virtualenv安装airflow(【可选】避免python多版本引起冲突问题,推荐使用此方式安装)。

1Anaconda【方式1】

使用Anaconda创建虚拟环境,可以随意指定python版本,不需要本机安装指定的python版本,会自动下载安装到Anaconda。

  • 创建虚拟环境

conda create --name airflow python=3.6

  • 激活环境

conda activate airflow

  • 退出当前环境

conda deactivate

  • 删除虚拟环境【重装时执行】

conda remove --name airflow --all

2安装指定版本Python【方式2】

该方式使用哪个python版本执行命令,venv中对应的python版本就是该版本。

cd /opt/airflow

  • 建立airflow的venv

python -m venv airflow-venv

  • 激活ariflow的venv

source airflow-venv/bin/activate



1.5.2激活python虚拟环境

后续所有安装和使用都需要进入上面python建立的虚拟环境中进行操作,根据上面的安装方式选择对应的激活方式进入python虚拟环境。

  • Anaconda方式

#激活airflow环境

conda activate airflow

  • 安装指定版本python方式

#激活ariflow的venv

source airflow-venv/bin/activate

1.5.3开始安装

  • 设置环境变量

设置如下环境变量(不设置后续会字符问题错误),此环境变量仅需要设置成临时变量即可并不需要配置成永久变量。

export SLUGIFY_USES_TEXT_UNIDECODE=yes

  • pip安装airflow

pip下载速度慢可以更换pip国内源,更换方法见前面python安装步骤。

  • 升级pip

pip install --upgrade pip

  • 升级setuptools

pip install --upgrade setuptools pip

  • 默认安装最新版

pip install apache-airflow

  • 安装指定版本

pip install apache-airflow==1.10.1

  • 安装其他依赖

#数据库URL连接密码加密方式,避免明文

pip install apache-airflow[crypto]

#Async worker classes for gunicorn

pip install apache-airflow[async]

  • 初始化数据库

 初始化sqlite数据库,并在AIRFLOW_HOME目录下生成配置文件

airflow initdb

  • 启动airflow

 启动web服务和调度服务,web默认端口8080

airflow webserver -p 8080  | airflow webserver --debug

airflow scheduler

  • 重启airflow

 重启webserver和scheduler

su airflow
ps -ef|egrep 'scheduler|airflow-webserver'|grep -v grep|awk '{print $2}'|xargs kill -9
rm -rf /opt/airflow/airflow-webserver.pid
airflow webserver -p 8080 -D
airflow scheduler -D
tail -f /opt/airflow/logs/airflow-scheduler.err

重启worker

su airflow
ps -ef|egrep 'serve_logs|celeryd'|grep -v grep
rm -rf /home/airflow/airflow/airflow-worker.pid
airflow worker -D
tail -f /opt/airflow/logs/airflow-worker.err

至此,airflow已安装完成,此方式仅适合demo,不适合生产环境使用,详见下面安装章节。

 

1.5.4生产环境安装运行模式

airflow默认使用sqlite和SequentialExecutor无法并行化任务,生产环境推荐使用LocalExecutor或者CeleryExecutor(分布式方式),需要使用MySQL作为元数据库才可以启用LocalExecutor和CeleryExecutor。

1.5.4.1安装MySQL

  • MySQL5.7安装参考资料

修改配置文件

vi /etc/my.conf

[client]

default-character-set=utf8mb4

[mysql]

default-character-set=utf8mb4

[mysqld]

collation-server = utf8mb4_unicode_ci

init-connect='SET NAMES utf8mb4'

character-set-server = utf8mb4

  • MySQL5.6安装参考资料

​CentOS6.8手动安装MySQL5.6 - 猫头老鹰 - 博客园​

1.修改配置文件

mysql5.6使用上面5.7的编码会报错或需要修改其他配置文件,可以考虑使用utf8

[client]

default-character-set=utf8

[mysql]

default-character-set=utf8

[mysqld]

collation-server = utf8_unicode_ci

init-connect='SET NAMES utf8'

character-set-server = utf8

2.设置mysql必要参数

airflow 必须设置其参数

修改my.cnf,在[mysqld]下添加如下参数

explicit_defaults_for_timestamp=1

3.创建数据库

create database airflow default charset utf8 collate utf8_general_ci;



create user 'airflow'@'%' identified by 'airflow';

create user 'airflow'@'localhost' identified by 'airflow';



grant all on airflow.* to 'airflow'@'%';

flush privileges;

4.pip安装mysql依赖

pip install apache-airflow[mysql]

5.airflow运行模式

airflow生产环境建议两种运行方案LocalExecutor或者CeleryExecutor

  •  LocalExecutor (单机版调度)

修改${AIRFLOW_HOME}/airflow.cfg配置文件

executor = LocalExecutor

#修改为mysql地址

sql_alchemy_conn = mysql://user:password@192.168.1.200:3306/airflow

  • CeleryExecutor (分布式调度)

消息队列可以使用redis、rabbitmq

1.安装依赖包

pip install apache-airflow[celery]

pip install apache-airflow[redis]

pip install redis

2.修改配置文件

修改${AIRFLOW_HOME}/airflow.cfg配置文件

executor = CeleryExecutor

#修改为mysql地址

sql_alchemy_conn = mysql://user:password@192.168.1.200:3306/airflow

broker_url=redis://192.168.115.101:6379/0

result_backend = db+mysql://user:password@192.168.1.200:3306/airflow

3.初始化数据库

初始化mysql数据库,并在AIRFLOW_HOME目录下生成配置文件

4.启动airflow

启动web服务和调度服务,web默认端口8080

airflow webserver -p 8080  | airflow webserver --debug

airflow scheduler

CeleryExecutor方式需要在worker节点启动worker, LocalExecutor不用执行

airflow worker

1.5.4.2Web登陆认证

Airflow Web UI默认没有登陆认证,需要安装相关登陆认证模块。

  • 安装web登陆认证包
pip install apache-airflow[password]

  • 修改配置文件

修改${AIRFLOW_HOME}/airflow.cfg配置文件,注意是修改还是新增配置项,搜索到后替换成下面值【注意配置项所属scheme,不同scheme配置项名称会有相同】

Scheme重复会报错误:section 'webserver' already exists

[webserver]

#修改

authenticate = True

#新增

auth_backend = airflow.contrib.auth.backends.password_auth

  • 添加Web登陆账号

#启动1个python命令窗口执行下面命令,将用户名和密码替换为自己设置账号

import airflow

from airflow import models, settings

from airflow.contrib.auth.backends.password_auth import PasswordUser

user = PasswordUser(models.User())

user.username = 'new_user_name'

user.email = 'new_user_email@example.com'

user.password = 'set_the_password'

session = settings.Session()

session.add(user)

session.commit()

session.close()

exit()

重启airflow服务

  • airflow进程管理

使用airflow自带的命令启动和停止不方便管理,因此安装进程管理工具方便启动和停止airflow,进程管理工具可以在进程意外被杀掉或退出,会自动重新启动进程,进程主要有两种。

1.supervisord【方式1】

安装

yum install git

conda activate airflow

默认的supervisord不支持python3 因此使用git获取安装

pip install git+https://github.com/Supervisor/supervisor

生成supervisord配置文件

echo_supervisord_conf > $AIRFLOW_HOME/supervisord.conf

修改配置文件

cd $AIRFLOW_HOME

mkdir -p relative/directory && cd relative/directory

vim airflow.ini

[program:airflow_webserver]

#程序启动命令

command=airflow webserver -p 8080

#用哪个用户启动进程 默认是root

user=airflow

#在supervisord启动的时候也自动启动

autostart=false

#程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启

autorestart=true

#默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程

stopasgroup=true

#默认为false,向进程组发送kill信号,包括子进程

killasgroup=true

stderr_logfile=/opt/airflow/logs/airflow-webserver.err.log

stdout_logfile=/opt/airflow/logs/airflow-webserver.out.log



[program:airflow_scheduler]

command=airflow scheduler

user=airflow

autostart=false

stopasgroup=true

killasgroup=true

stderr_logfile=/opt/airflow/logs/airflow-scheduler.err.log

stdout_logfile=/opt/airflow/logs/airflow-scheduler.out.log



[program:airflow_worker]

command=airflow worker

user=airflow

autostart=false

stopasgroup=true

killasgroup=true

stderr_logfile=/opt/airflow/logs/airflow-worker.err.log

stdout_logfile=/opt/airflow/logs/airflow-worker.out.log

启动supervisord

supervisord -c $AIRFLOW_HOME/supervisord.conf

停止supervisord

supervisorctl shutdown

启用Web界面管理进程

vim $AIRFLOW_HOME/supervisord.conf

默认禁用web管理进程,修改为下图:

访问web界面

http://localhost:9001

管理airflow服务

启动airflow服务

supervisorctl start airflow_scheduler

supervisorctl start airflow_worker

supervisorctl start airflow_webserver

停止airflow服务

supervisorctl stop airflow_webserver

supervisorctl stop airflow_worker

supervisorctl stop airflow_scheduler

重启airflow服务

supervisorctl restart airflow_webserver

停止所有服务

supervisorctl stop all

supervisord参考资料

supervisord管理airflow进程资料

https://www.jianshu.com/p/5c17846835e7

supervisord资料

 

2.systemd【方式2】

该方式依赖Linux系统systemd的命令,需要centos7及以上系统支持。

https://www.jianshu.com/p/0562a2d8f429

https://www.jianshu.com/p/99ebc934de5b

修改airflow时区

Airflow默认时区是UTC,为了方便使用修改为本地时区。

修改文件

1、修改scheduler时间

vim ${AIRFLOW_HOME}/airflow.cfg

default_timezone = Asia/Shanghai

2、进入${PYTHON_HOME}/lib/python3.6/site-packages

3、修改airflow/utils/timezone.py

3.1 在 utc = pendulum.timezone('UTC') 这行(第27行)代码下添加

from airflow import configuration as conf



try:

tz = conf.get("core", "default_timezone")

if tz == "system":

utc = pendulum.local_timezone()

else:

utc = pendulum.timezone(tz)

except Exception:

pass

3.2 修改utcnow()函数 (在第69行)

原代码 d = dt.datetime.utcnow()

修改为 d = dt.datetime.now()

4、修改airflow/utils/sqlalchemy.py

在utc = pendulum.timezone('UTC') 这行(第37行)代码下添加

from airflow import configuration as conf



try:

tz = conf.get("core", "default_timezone")

if tz == "system":

utc = pendulum.local_timezone()

else:

utc = pendulum.timezone(tz)

except Exception:

pass

5、修改airflow/www/templates/admin/master.html(第31行),webserver界面右上角当前时间

把代码 var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000);

改为 var UTCseconds = x.getTime();

把代码 "timeFormat":"H:i:s %UTC%",

改为  "timeFormat":"H:i:s",

修改时区参考资料

 

安装参考资料

  • 单机安装

 

  • 分布式安装

 


 2.Airflow使用说明

Airflow是一个可编程,调度和监控的工作流平台,基于有向无环图(DAG),airflow可以定义一组有依赖的任务,按照依赖依次执行。airflow提供了丰富的命令行工具用于系统管控,而其web管理界面同样也可以方便的管控调度任务,并且对任务运行状态进行实时监控,方便了系统的运维和管理。

2.1Airflow基本概念

Airflow运维部署功能调研_spark

 如上图所示,一个工作流可以用一个 DAG 来表示,在 DAG 中将完整得记录整个工作流中每个作业之间的依赖关系、条件分支等内容,并可以记录运行状态。通过 DAG,我们可以精准的得到各个作业之间的依赖关系。

Airflow中常见的名词概念:

  • DAG

DAG 意为有向无循环图,在 Airflow 中则定义了整个完整的作业。同一个 DAG 中的所有 Task 拥有相同的调度时间。

  • Task

Task 为 DAG 中具体的作业任务,它必须存在于某一个 DAG 之中。Task 在 DAG 中配置依赖关系,跨 DAG 的依赖是可行的,但是并不推荐。跨 DAG 依赖会导致 DAG 图的直观性降低,并给依赖管理带来麻烦。

  • DAG Run

当一个 DAG 满足它的调度时间,或者被外部触发时,就会产生一个 DAG Run。可以理解为由 DAG 实例化的实例。

  • Task Instance

当一个 Task 被调度启动时,就会产生一个 Task Instance。可以理解为由 Task 实例化的实例。

2.2编写DAG文件流程

1、${AIRFLOW_HOME}/dags目录支持子目录和软连接,不同的dag可以根据业务分类使用不同目录存储方便查看管理。

2、编写DAG文件流程:

a.创建定义DAG的python文件。

b. DAG文件中编写定义Task任务和任务之间的依赖关系。

c. python xxx.py(DAG定义文件)测试是否有python语法错误。

d. WebUI界面触发Dag任务运行实列。

e. 查看Dag和tasks的执行情况。

2.3编写DAG文件

vim hello_airflow.py


from datetime import timedelta

import airflow

from airflow import DAG

from airflow.operators.bash_operator import BashOperator

default_args = {

    'owner': 'airflow',

    'depends_on_past': False,

    'start_date': airflow.utils.dates.days_ago(2),

    'email': ['airflow@example.com'],

    'email_on_failure': False,

    'email_on_retry': False,

    'retries': 1,

    'retry_delay': timedelta(minutes=5)

}

dag = DAG(

    'hello_airflow',

    default_args=default_args,

    description='My first DAG',

    schedule_interval=timedelta(days=1),

)

t1 = BashOperator(

    task_id='print_date',

    bash_command='date',

    dag=dag,

)

t2 = BashOperator(

    task_id='sleep',

    depends_on_past=False,

    bash_command='sleep 5',

    dag=dag,

)

templated_command = """

{% for i in range(5) %}

    echo "{{ ds }}"

    echo "{{ macros.ds_add(ds, 7)}}"

    echo "{{ params.my_param }}"

{% endfor %}

"""

t3 = BashOperator(

    task_id='templated',

    depends_on_past=False,

    bash_command=templated_command,

    params={'my_param': 'Parameter I passed in'},

    dag=dag,

)

t1 >> [t2, t3]


参考官网demo例子,其中有每部分代码详细说明.

​https://airflow.apache.org/tutorial.html#example-pipeline-definition​

DAG定义参数说明

整个 DAG 的配置就是一份完整的 Python 代码,在代码中实例化 DAG,实例化适合的 Operator,并通过 set_downstream 等方法配置上下游依赖关系。下面我们简单看一下在 DAG 配置中的几个重要概念。

  • DAG

要配置一个 DAG 自然需要一个 DAG 实例。在同一个 DAG 下的所有作业,都需要将它的 dag 属性设置为这个 DAG 实例。在实例化 DAG 时,通过传参数可以给这个 DAG 实例做一些必要的配置。

  • dag_id给 DAG 取一个名字,方便日后维护。
  • default_args默认参数,当属于这个 DAG 实例的作业没有配置相应参数时,将使用 DAG 实例的 default_args 中的相应参数。
  • schedule_interval配置 DAG 的执行周期,语法和 crontab 的一致。
  • 作业 (Task)

Airflow 提供了很多 Operator,我们也可以自行编写新的 Operator。在本例中使用了 2 种 Operator,DummyOperator 什么都不会做, BashOperator 则会执行 bash_command 参数所指定的 bash 指令,并且使用 jinja2 模版引擎,对该指令进行渲染,因而在本例的 bash_command 中,可以看到一些需要渲染的变量。当 Operator 被实例化后,我们称之为相应 DAG 的一个作业(Task)。在实例化 Operator 时,同样可以通过穿参数进行必要的配置,值得注意的是,如果在 DAG 中有设置 default_args 而在 Operator 中没有覆盖相应配置,则会使用 default_args 中的配置。

  • dag传递一个 DAG 实例,以使当前作业属于相应 DAG。
  • task_id给作业去一个名字,方便日后维护。
  • owner作业的拥有者,方便作业维护。另外有些 Operator 会根据该参数实现相应的权限控制。
  • start_date作业的开始时间,即作业将在这个时间点以后开始调度。
  • 依赖

配置以来的方法有两种,除了可以使用作业实例的 set_upstream 和 set_downstream 方法外,还可以使用类似

task1 << task2 << task3

task3 >> task4

这样更直观的语法来设置。

这里我们要特别注意一个关于调度执行时间的问题。在谈这个问题前,我们先确定几个名词:

  • start date: 在配置中,它是作业开始调度时间。而在谈论执行状况时,它是调度开始时间。
  • schedule interval: 调度执行周期。
  • execution date: 执行时间,在 Airflow 中称之为执行时间,但其实它并不是真实的执行时间。

那么现在,让我们看一下当一个新配置的 DAG 生效后第一次调度会在什么时候。很多人会很自然的认为,第一次的调度时间当然是在作业中配置的 start date,但其实并不是。第一次调度时间是在作业中配置的 start date 的第二个满足 schedule interval 的时间点,并且记录的 execution date 为作业中配置的 start date 的第一个满足 schedule interval 的时间点。听起来很绕,让我们来举个例子。

假设我们配置了一个作业的 start date 为 2017年10月1日,配置的 schedule interval 为 **00 12 * * *** 那么第一次执行的时间将是 2017年10月2日 12点 而此时记录的 execution date 为 2017年10月1日 12点。因此 execution date 并不是如其字面说的表示执行时间,真正的执行时间是 execution date 所显示的时间的下一个满足 schedule interval 的时间点。

另外,当作业已经执行过之后,start date 的配置将不会再生效,这个作业的调度开始时间将直接按照上次调度所对应的 execution date 来计算。

这个例子只是简要的介绍了一下 DAG 的配置,也只介绍了非常少量的配置参数。Airflow 为 DAG 和作业提供了大量的可配置参数,详情可以参考 ​​Airflow 官方文档​​。

2.4检查DAG定义文件正确性

执行python hello_airflow.py测试是否有python语法错误,有错误需要纠正错误。

2.5WebUI首页功能说明

2.5.1WebUI触发Dag任务

在浏览器中访问​​http://xxx:8080​​,并登陆airflow,首页会看到刚才定义的DAG文件。

  1. 左侧 On/Off 按钮控制 DAG 的运行状态,Off 为暂停状态,On 为运行状态。注意:所有 DAG 脚本初次部署完成时均为 Off 状态。
  2. 若 DAG 名称处于不可点击状态,可能为 DAG 被删除或未载入。若 DAG 未载入,可点击右侧刷新按钮进行刷新。注意:由于可以部署若干 WebServer,所以单次刷新可能无法刷新所有 WebServer 缓存,可以尝试多次刷新。
  3. Recent Tasks 会显示最近一次 DAG Run(可以理解为 DAG 的执行记录)中 Task Instances(可以理解为作业的执行记录)的运行状态,如果 DAG Run 的状态为 running,此时显示最近完成的一次以及正在运行的 DAG Run 中所有 Task Instances 的状态。
  4. Last Run 显示最近一次的 execution date。注意:execution date 并不是真实执行时间,具体细节在下文 DAG 配置中详述。将鼠标移至 execution date 右侧 info 标记上,会显示 start date,start date 为真实运行时间。start date 一般为 execution date 所对应的下次执行时间。
  5. 点击Links列的第1个图标 (Tigger Dag),触发DAG任务实列。

2.5.2首页DAGs表字段和图标说明

  • DAG
    dag_id
  • Schedule
    调度时间
  • Owner
    dag拥有者
  • Recent Tasks
    这里包含9个圆圈,每个圆圈代表task的执行状态和次数
    圈1 success:现实成功的task数,基本上就是该tag包含多少个task,这里基本上就显示几。
    圈2 running:正在运行的task数
    圈3 failed:失败的task数
    圈4 unstream_failed:
    圈5 skipped:跳过的task数
    圈6 up_for_retry:执行失败的task,重新执行的task数
    圈7 queued:队列,等待执行的task数
    圈8 :
    圈9 scheduled:刚开始调度dag时,这一次执行总共调度了dag下面多少个task数,并且随着task的执行成功,数值逐渐减少。
  • Last Run
    dag最后执行的时间点
  • DAG Runs
    这里显示dag的执行信息,包括3个圆圈,每个圆圈代表dag的执行状态和次数
    圈1 success:总共执行成功的dag数,执行次数
    圈2 runing:正在执行dag数
    圈3 faild:执行失败的dag数
  • Links


link



说明



Trigger Dag



人为执行触发



Tree View



当dag执行的时候,可以点入,查看每个task的执行状态(基于树状视图),状态:success,running,failed,skipped,retry,queued,no status



Graph View



同上,基于图视图(有向无环图),查看每个task的执行状态,状态:success,running,failed,skipped,retry,queued,no status



Tasks Duration



每个task的执行时间统计,可以选择最近多少次执行(number of runs)



Task Tries



每个task的重试次数



Gantt View



基于甘特图的视图,每个task的执行状态


  • Code View
    查看任务执行代码
  • Logs
    查看执行日志,比如失败原因
  • Refresh
    刷新dag任务
    -Delete Dag
    删除该dag任务

当某dag执行失败,可以通过3个View视图去查看是哪个task执行失败。

2.6查看DAG和Task执行情况

Airflow运维部署功能调研_bash_02

点击DAG名称,进入查看该DAG信息页面,如下:

Airflow运维部署功能调研_开发语言_03

  • Graph View

查看DAG中Task之间的依赖关系

  • Tree View

查看每个Task的执行情况,点击小方框可以进行相应的操作。

  • Task Duration
  • Task Tries
  • Landing Times
  • Gant

查看分析每个Task任务执行的时长,帮助快速找出瓶颈以及大部分时间花在特定DAG运行中的位置,以便进行调优。

  • Details

查看DAG的基本定义信息。

  • Code

查看DAG定义文件

  • Refresh

刷新加载DAG文件

  • Delete

从airflow中删除DAG定义。

2.7Tree View操作Task任务

Airflow运维部署功能调研_python_04

 点击小方框,弹出以下操作界面:

Airflow运维部署功能调研_bash_05

  1. 在作业名字的右边有一个漏斗符号,点击后整个 DAG 的界面将只显示该作业及该作业的依赖作业。当该作业所处的 DAG 较大时,此功能有较大的帮助。
  2. Task Instance Details 显示该 Task Instance 的详情,可以从中得知该 Task Instance 的当前状态,以及处于当前状态的原因。例如,若该 Task Instance 为 no status 状态,迟迟不进入 queued 及 running 状态,此时就可通过 Task Instance Details 中的 Dependency 及 Reason 得知原因。
  3. Rendered 显示该 Task Instance 被渲染后的命令。
  4. Run 指令可以直接执行当前作业,需要分布式部署支持。
  5. clear 指令为清除当前Task Instance状态,清除任意一个 Task Instance 都会使当前 DAG Run 的状态变更为 running。注意:如果被清除的 Task Instance 的状态为 running,则会尝试 kill 该 Task Instance 所执行指令,并进入 shutdown 状态,并在 kill 完成后将此次执行标记为 failed(如果 retry 次数没有用完,将标记为 up_for_retry)。Clear 有额外的5个选项,均为多选,这些选项从左到右依次为:
  • Past: 同时清除所有过去的 DAG Run 中此 Task Instance 所对应的 Task Instance。
  • Future: 同时清除所有未来的 DAG Run 中此 Task Instance 所对应的 Task Instance。注意:仅清除已生成的 DAG Run 中的 Task Instance。
  • Upstream: 同时清除该 DAG Run 中所有此 Task Instance 上游的 Task Instance。
  • Downstream: 同时清除该 DAG Run 中所有此 Task Instance 下游的 Task Instance。
  • Recursive: 当此 Task Instance 为 sub DAG 时,循环清除所有该 sub DAG 中的 Task Instance。注意:若当此 Task Instance 不是 sub DAG 则忽略此选项。

     6.Mark Success 指令为讲当前 Task Instance 状态标记为 success。注意:如果该 Task Instance 的状态为 running,则会尝试 kill 该 Task Instance 所执行指令,并进入 shutdown 状态,并在 kill 完成后将此次执行标记为 failed(如果 retry 次数没有用完,将标记为 up_for_retry)。

2.8Operator Example

2.8.1BashOperator

BashOperator有个坑,如果是执行sh脚本文件,后面需要加一个空格。

如:

bash_command='/sqoop/ods/shell/sys_province.sh '  .sh后面有个空格


from datetime import timedelta

import airflow

from airflow import DAG

from airflow.operators.bash_operator import BashOperator

default_args = {

    'owner': 'airflow',

    'depends_on_past': False,

    'start_date': airflow.utils.dates.days_ago(2),

    'email': ['airflow@example.com'],

    'email_on_failure': False,

    'email_on_retry': False,

    'retries': 1,

    'retry_delay': timedelta(minutes=5),

    # 'queue': 'bash_queue',

    # 'pool': 'backfill',

    # 'priority_weight': 10,

    # 'end_date': datetime(2016, 1, 1),

    # 'wait_for_downstream': False,

    # 'dag': dag,

    # 'adhoc':False,

    # 'sla': timedelta(hours=2),

    # 'execution_timeout': timedelta(seconds=300),

    # 'on_failure_callback': some_function,

    # 'on_success_callback': some_other_function,

    # 'on_retry_callback': another_function,

    # 'trigger_rule': u'all_success'

}

dag = DAG(

    'hello_airflow',

    default_args=default_args,

    description='My first DAG',

    schedule_interval=timedelta(days=1),

)

t1 = BashOperator(

    task_id='print_date',

    bash_command='date',

    dag=dag,

)

t2 = BashOperator(

    task_id='sleep',

    depends_on_past=False,

    bash_command='sleep 5',

    dag=dag,

)

templated_command = """

{% for i in range(5) %}

    echo "{{ ds }}"

    echo "{{ macros.ds_add(ds, 7)}}"

    echo "{{ params.my_param }}"

{% endfor %}

"""

t3 = BashOperator(

    task_id='templated',

    depends_on_past=False,

    bash_command=templated_command,

    params={'my_param': 'Parameter I passed in'},

    dag=dag,

)

t1 >> [t2, t3]


详细使用参考官网资料:

http://airflow.apache.org/code.html#airflow.operators.bash_operator.BashOperator

2.8.2SqoopOperator

SqoopOperator参数比较多,也可以直接使用BashOperator调用sh脚本中写的sqoop操作命令。


from datetime import datetime, timedelta

import airflow

from airflow import DAG

from airflow.models import Variable

from airflow.operators.bash_operator import BashOperator

from airflow.operators.dummy_operator import DummyOperator

dags_folder_path = Variable.get("dags_folder_path")

default_args = {

    'owner': 'airflow',

    'depends_on_past': False,

    'start_date': airflow.utils.dates.days_ago(2),

    'email': ['853539686@qq.com'],

    'email_on_failure': False,

    'email_on_retry': False,

    'retries': 1,

    'retry_delay': timedelta(minutes=5)

}

dag = DAG(

    dag_id='sqoop-ods-sys_province_city_area',

    description='抽取全国省份、城市、区域数据',

    default_args=default_args,

    schedule_interval='30 4 * * *',

    dagrun_timeout=timedelta(minutes=60)

)

#抽取省份数据

extract_sys_province = BashOperator(

    task_id='extract_sys_province',

    bash_command='%s/sqoop/ods/shell/sys_province.sh '%(dags_folder_path),

    dag=dag,

)

#抽取城市数据

extract_sys_city = BashOperator(

    task_id='extract_sys_city',

    bash_command='%s/sqoop/ods/shell/sys_city.sh '%(dags_folder_path),

    dag=dag,

)

#抽取区域数据

extract_sys_area = BashOperator(

    task_id='extract_sys_area',

    bash_command='%s/sqoop/ods/shell/sys_area.sh '%(dags_folder_path),

    dag=dag,

)

extract_sys_province >> extract_sys_city >> extract_sys_area


详细使用参考官网资料:

http://airflow.apache.org/code.html#airflow.contrib.operators.sqoop_operator.SqoopOperator

2.8.3Spark

提交Spark任务有以下几种方式,前面两种方式需要在airflow的调度机上安装spark、以及hadoop的4个配置文件。

  1. 使用BashOperator调用shell脚本中写好的spark提交任务,即使用spark-sql、spark-submit。
  2. 使用airflow自带的Operator相关操作,其仅仅是包装了参数最后拼接成提交命令的字符串,原理跟第一种方式一致。
  3. 使用SSHOperator:使用此运算符在远程服务器上运行bash命令(使用SSH协议通过paramiko库)spark-submit。这种方法的好处是您不需要复制hdfs-site.xml或维护任何文件。
  4. 与Livy一起使用SimpleHTTPOperator:Livy是一个开源的REST接口,可以从任何地方与Apache Spark进行交互。您只需要进行REST调用。
  • 设置Spark任务提交方式

使用airflow自带的Operator需要先进行以下配置:

Airflow运维部署功能调研_开发语言_06

点击进入编辑

Airflow运维部署功能调研_bash_07host中可以填写Master can be local, yarn, spark://HOST:PORT, mesos://HOST:PORT and k8s://https://<HOST>:<PORT>.

Either the "spark-submit" binary should be in the PATH or the spark-home is set in the extra on the connection.

  • SparkSQLOperator


from datetime import timedelta

import airflow

from airflow import DAG

from airflow.operators.bash_operator import BashOperator

from airflow.contrib.operators.spark_sql_operator import SparkSqlOperator

default_args = {

    'owner': 'airflow',

    'depends_on_past': False,

    'start_date': airflow.utils.dates.days_ago(2),

    'email': ['airflow@example.com'],

    'email_on_failure': False,

    'email_on_retry': False,

    'retries': 1,

    'retry_delay': timedelta(minutes=5),

    # 'queue': 'bash_queue',

    # 'pool': 'backfill',

    # 'priority_weight': 10,

    # 'end_date': datetime(2016, 1, 1),

    # 'wait_for_downstream': False,

    # 'dag': dag,

    # 'adhoc':False,

    # 'sla': timedelta(hours=2),

    # 'execution_timeout': timedelta(seconds=300),

    # 'on_failure_callback': some_function,

    # 'on_success_callback': some_other_function,

    # 'on_retry_callback': another_function,

    # 'trigger_rule': u'all_success'

}

dag = DAG(

    'sparksql_test',

    default_args=default_args,

    description='sparksql test',

    schedule_interval=timedelta(days=1),

)

t1 = SparkSqlOperator(

    task_id='testsql1',

    name='testsql1',

    conn_id='spark_default',

    sql='select * from peanut.user_info limit 10;',

    master='yarn',

    executor_cores=2,

    num_executors=2,

    executor_memory='1G',

    verbose=True,

    dag=dag,

)

t2 = SparkSqlOperator(

    task_id='testsql2',

    name='testsql2',

    conn_id='spark_default',

    sql='select count(*) from peanut.user_info;',

    master='yarn',

    executor_cores=2,

    num_executors=2,

    executor_memory='1G',

    verbose=True,

    dag=dag,

)

t1 >> t2


详细使用参考官网资料:

conn_id='spark_default' 是在设置Spark任务提交方式中设置的,修改为自己定义的。

http://airflow.apache.org/code.html#airflow.contrib.operators.spark_sql_operator.SparkSqlOperator

  • SparkSubmitOperator


from datetime import timedelta

import airflow

from airflow import DAG

from airflow.operators.bash_operator import BashOperator

from airflow.operators.dummy_operator import DummyOperator

from airflow.contrib.operators.spark_submit_operator import SparkSubmitOperator

default_args = {

    'owner': 'airflow',

    'depends_on_past': False,

    'start_date': airflow.utils.dates.days_ago(2),

    'email': ['airflow@example.com'],

    'email_on_failure': False,

    'email_on_retry': False,

    'retries': 1,

    'retry_delay': timedelta(minutes=5),

    # 'queue': 'bash_queue',

    # 'pool': 'backfill',

    # 'priority_weight': 10,

    # 'end_date': datetime(2016, 1, 1),

    # 'wait_for_downstream': False,

    # 'dag': dag,

    # 'adhoc':False,

    # 'sla': timedelta(hours=2),

    # 'execution_timeout': timedelta(seconds=300),

    # 'on_failure_callback': some_function,

    # 'on_success_callback': some_other_function,

    # 'on_retry_callback': another_function,

    # 'trigger_rule': u'all_success'

}

dag = DAG(

    'sparksubmit_test',

    default_args=default_args,

    description='sparksubmit test',

    schedule_interval=timedelta(days=1),

)

t1 = SparkSubmitOperator(

    task_id='tests_park_submit_job',

    conn_id='spark_default',

    name='airflow-spark-example',

    java_class='org.apache.spark.examples.SparkPi',

    application='/opt/cloudera/parcels/SPARK2/lib/spark2/examples/jars/spark-examples_2.11-2.2.0.cloudera2.jar',

    application_args=["1000"],

    executor_cores='2',

    executor_memory='2g',

    num_executors='3',

    driver_memory='2g',

    verbose=True,

    conf={'master':'yarn'},

    dag=dag

)

t2 = DummyOperator(

    task_id='DummyTask',

    dag=dag

)

t1 >> t2


详细使用参考官网资料:

conn_id='spark_default' 是在设置Spark任务提交方式中设置的,修改为自己定义的。

http://airflow.apache.org/code.html#airflow.contrib.operators.spark_submit_operator.SparkSubmitOperator

2.9自定义Operator 开发

https://www.jianshu.com/p/38d74a9f9d67

2.10参考资料

​Apache Airflow​

airflow在国内资料较少,到国外一些网站寻找一些解决办法

https://stackoverflow.com

Airflow ETL设计参考文章,推荐阅读

https://gtoonstra.github.io/etl-with-airflow

https://github.com/hgrif/airflow-tutorial