目录
1.1安装简介
Airflow是基于python开发的,推荐使用以下安装方式:
- Airflow支持python2、python3安装运行。
- 使用virtualenv虚拟环境安装airflow,避免多个python版本之间引起的不兼任问题。
- Python环境可以用Anaconda(优点:包含绝大部分常用Python依赖库,服务器不能联网安装的情况比较合适。缺点:安装包较大。)或者安装指定版本Python,两种方式根据情况选择安装方式。
1.2安装须知
开始安装airflow之前需要知道和准备的
- Airflow在pip上已经更名为apache-airflow,下载最新版请使用后者pip install apache-airflow。
- 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到最新版。
- MySQL5.6 升级到5.7在使用airflow 时会报1146, u"Table 'performance_schema.session_variables' doesn't exist",执行mysql_upgrade -u root -p --force解决。
- 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基本概念
如上图所示,一个工作流可以用一个 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文件。
- 左侧 On/Off 按钮控制 DAG 的运行状态,Off 为暂停状态,On 为运行状态。注意:所有 DAG 脚本初次部署完成时均为 Off 状态。
- 若 DAG 名称处于不可点击状态,可能为 DAG 被删除或未载入。若 DAG 未载入,可点击右侧刷新按钮进行刷新。注意:由于可以部署若干 WebServer,所以单次刷新可能无法刷新所有 WebServer 缓存,可以尝试多次刷新。
- Recent Tasks 会显示最近一次 DAG Run(可以理解为 DAG 的执行记录)中 Task Instances(可以理解为作业的执行记录)的运行状态,如果 DAG Run 的状态为 running,此时显示最近完成的一次以及正在运行的 DAG Run 中所有 Task Instances 的状态。
- Last Run 显示最近一次的 execution date。注意:execution date 并不是真实执行时间,具体细节在下文 DAG 配置中详述。将鼠标移至 execution date 右侧 info 标记上,会显示 start date,start date 为真实运行时间。start date 一般为 execution date 所对应的下次执行时间。
- 点击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执行情况
点击DAG名称,进入查看该DAG信息页面,如下:
- 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任务
点击小方框,弹出以下操作界面:
- 在作业名字的右边有一个漏斗符号,点击后整个 DAG 的界面将只显示该作业及该作业的依赖作业。当该作业所处的 DAG 较大时,此功能有较大的帮助。
- Task Instance Details 显示该 Task Instance 的详情,可以从中得知该 Task Instance 的当前状态,以及处于当前状态的原因。例如,若该 Task Instance 为 no status 状态,迟迟不进入 queued 及 running 状态,此时就可通过 Task Instance Details 中的 Dependency 及 Reason 得知原因。
- Rendered 显示该 Task Instance 被渲染后的命令。
- Run 指令可以直接执行当前作业,需要分布式部署支持。
- 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个配置文件。
- 使用BashOperator调用shell脚本中写好的spark提交任务,即使用spark-sql、spark-submit。
- 使用airflow自带的Operator相关操作,其仅仅是包装了参数最后拼接成提交命令的字符串,原理跟第一种方式一致。
- 使用SSHOperator:使用此运算符在远程服务器上运行bash命令(使用SSH协议通过paramiko库)spark-submit。这种方法的好处是您不需要复制hdfs-site.xml或维护任何文件。
- 与Livy一起使用SimpleHTTPOperator:Livy是一个开源的REST接口,可以从任何地方与Apache Spark进行交互。您只需要进行REST调用。
- 设置Spark任务提交方式
使用airflow自带的Operator需要先进行以下配置:
点击进入编辑
host中可以填写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参考资料
airflow在国内资料较少,到国外一些网站寻找一些解决办法
https://stackoverflow.com
Airflow ETL设计参考文章,推荐阅读
https://gtoonstra.github.io/etl-with-airflow
https://github.com/hgrif/airflow-tutorial