(2022.11.12)
(airflow==2.4.2)
Airflow是Apache协议下用于开发、schedule、监控批(处理工作)模式的工作流(workflow)平台。工作流在Airflow中被表达为有向无环图(DAG, directed acyclic graph),其中包含若干任务(tasks),还包括依赖和数据流。
DAG表示出了任务间的依赖关系和执行顺序。任务描述了工作内容,可能 包括获取数据、执行分析、触发系统等。
其可扩展的python框架可连接任何技术。提供的web页面用于管理工作流。部署方式多样,可单机部署,也可分布部署。
Components
Airflow包括如下组件
- a scheduler:用于触发预定的workflow,提交任务以执行等
- an executor:用于执行任务。默认安装中,executor运行scheduler中的每个任务,而开发环境(production-suitable executors)多数executor将任务执行推送给workers执行
- a webserver:提供UI用于监视(inspect)、触发和对DAGs与任务的debug,Flask
- DAG文件夹:由scheduler、executor和workers读取
- metadata数据库:scheduler、executor和webserver存储数据用
多数executor通常会引入其他组件用于和workers通信,比如任务队列(task queue),但仍然可将executor和workers当做airflow中的同一个逻辑组件,管理(handle)任务执行。
Airflow本身对用户运行的内容不可知(agnostic),可运行用户设置的任何任务。
Scheduler
scheduler执行两个特定任务
- schedule和触发workflow
- 将scheduled workflows提交到executor
scheduler在触发task时,为了判断是否触发,会运行一个子线程(subprocess)用于监控DAG文件夹,也就是包括DAGs在内的Python脚本所在的文件夹,遍历DAGs文件夹并执行DAG。默认情况下,scheduler每分钟执行一次查询,可在config文件中修改。
scheduler使用executor运行待运行的task。
Executor
executor负责运行tasks。Airflow安装时每次只有一个executor。executor被定义为Airflowconfig文件(airflow.cfg
)的核心部分。
[core]
executor = KubernetesExecutor
executor分两种,local executor和remote executor。local包括DebugExecutor,LocalExecutor和SequentialExecutor。remote executor包括CeleryExecutor和KubernetesExecutor。local用于在本地执行任务,在scheduler线程内部。remote executor在远程执行任务,比如在Kubernets cluster的一个pod中,且常通过一系列workers/worker pool实现。
Metadata Database
元数据库用于保存executor、scheduler和web server的相关数据。默认使用SQLite,Airflow可使用任何SQLAlchemy支持的数据库。一般情况用于常选择PostgreSQL。
Queue
有的DAG中还会借用消息队列/任务队列。一旦识别出即将被激活的任务,scheduler将该任务推送金任务队列等待执行。
Airflow workers从队列中获取任务并执行。
另有web service用Flask实现
Workloads
DAG中标出了一系列任务,共三类常见任务
- Operators:预定义任务,可与DAG中的大多数任务绑定(string)
- Sensors:Operators的特殊子集,仅等待外部事件发生
- TaskFlow:用
@task
装饰,定制的Python函数,装饰成一个Task
尽管在Airflow内部,这些其实是BaseOperator
的子集(subclass),task和operator的概念也经常混用不做区分,但尽量把他们当做独立概念。Operators和Sensors堪比末班,当你在DAG文件中调用其中一个,都会创建一个task。
Operators最常用的是BashOperator
和PythonOperator
,分别执行bash命令的任务和Python任务。另DummyOperator
,该operator什么都不做,用于组织DAG中的任务,该任务被scheduler evaluated,但不被executor处理。
特点
所有Airflow的工作流都在Python中定义,工作流如同代码一样工作,这种设计的目的包括
- dynamic:airflow的pipeline被设置为python代码,允许动态pipeline生成
- extensible:架构包括operators用于连接各种技术。所有airflow的组件都可轻易扩展到适应环境
- flexible:workflow参数化(parameterization)利用了内建的Jinja模板引擎(workflow parameterization is built-in leveraging the Jinja templating engine)
优势:
- airflow有operator,可以连接扩展新技术。如果workflow有清晰的起止日期且有规律的间隔,则可以编码为Airflow的DAG(directed acyclic graph)。
- Airflow工作流需要开发者编码,用Python开发
- 保存为version control,因此可以roll back回到之前的版本
- workflow可多人同时协作完成
- 可测试
- 组件可扩展
- 丰富的schedule和执行语法使开发者能轻松定义复杂的pipeline,并定期执行。backfilling回填允许用户在修改逻辑之后,基于历史数据重新运行或运行pipeline。而能重新运行部分pipeline也可以提高效率。
- UI提供的内容包括pipeline的深度视图、单个任务、pipeline随着时间变化的总览。从UI上可以监控logs和管理任务,比如任务失败后的重新运行。
- 其开源特性使得你在组件上的提交和贡献可以被外部使用者继续开发、测试和使用。活跃的社区为开发者提供了沟通的平台。
缺点:
- batch workflow,由CLI和REST API触发,不适用event-based workflows。不是streaming solution,但streaming system比如Kafka经常与airflow同时用于完成任务。Kafka用于数据ingestion和实时处理,事件数据写入存储位,airflow用于周期性的执行批数据处理。
案例分析
ETL案例
从外部数据源获取数据存入GCP的Big query, i.e., data warehouse,并执行一系列转换操作。可构建DAG,其中含两个任务
- 从外部数据源拷贝数据到BigQuery
- 执行转换
第二个任务的执行取决于第一个任务是否顺利。
这个case可以用Airflow实现。
Web Server与workers、DAG文件夹、metadata db通信,用于获取任务执行logs,DAG结构和任务的状态。
workers和DAG文件夹通信来推测DAGs的结构和执行任务,也与metadata db通信用于读并存储连接信息、变量和XCOM。
XComs (“Cross-communications”), a system where you can have tasks push and pull small bits of metadata.
Scheduler与DAG文件夹通信以推测DAGs的结构并调度任务,与metadata db通信写入DAG运行和任务的相关信息。与任务队列通信将即将触发的任务推入其中。
案例代码
典型代码案例如下
from datetime import datetime
from airflow import DAG
from airflow.decorators import task
from airflow.operators.bash import BashOperator
# A DAG represents a workflow, a collection of tasks
with DAG(dag_id="demo", start_date=datetime(2022, 1, 1), schedule="0 0 * * *") as dag:
# Tasks are represented as operators
hello = BashOperator(task_id="hello", bash_command="echo hello")
@task()
def airflow():
print("airflow")
# Set dependencies between tasks
hello >> airflow() # redefine the action of symbol >>
TODO:代码分析
Airflow一些初始化设置
(2022.11.20 Sun)
安装好Airflow之后,i.e.,pip install apache-airflow[==x]
,首先修改环境变量用于存储配置文件airflow.cfg
的路径。
进入文件~/.bashrc
,修改环境变量AIRFLOW_HOME
为指定路径用于存放配置文件。
export AIRFLOW_HOME=/home/airflow
修改配置文件中,DAGs文件的存放路径。此外,还可将默认的SQLite数据库换成MySQL或PostgreSQL。在更换默认数据库时,注意在对应的数据库中创建相应的账户、db和table以及相应权限。
>> nano /home/airflow/airflow.cfg
dags_folder = /home/airflow/dags
# sql_alchemy_conn = sqlite:////home/airflow/airflow.db
sql_alchemy_conn = mysql+pymysql://airflow:airflow@localhost:3306/airflow
数据库初始化
>> airflow db init
[2022-11-20 11:56:02,860] {migration.py:204} INFO - Context impl SQLiteImpl.
[2022-11-20 11:56:02,860] {migration.py:207} INFO - Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running stamp_revision -> b0d31815b5a6
WARNI [airflow.models.crypto] empty cryptography key - values will not be stored encrypted.
Initialization done
直到出现Initialisation done
则表示初始化数据库成功。
创建用户,赋Admin权限。
>> airflow users create
--role Admin
--username admin
--email admin
--firstname admin
--lastname admin
--password admin
[2022-11-20 12:05:12,797] {manager.py:824} WARNING - No user yet created, use flask fab command to do it.
[2022-11-20 12:05:15,293] {manager.py:212} INFO - Added user admin
User "admin" created with role "Admin"
启动Airflow
做好如上的配置,可启动Airflow,分别需要启动webserver
和scheduler
。加入选项-D
设置为守护进程。
>> airflow webserver -D
>> airflow scheduler -D
启动之后可在浏览器打开Airflow的UI,http://0.0.0.0:8080/home
,按之前设定的admin账户密码登录,即可看到Airflow的UI界面。
关闭webserver和scheduler,因webserver开启多个gunicorn进程,分别关闭相对低效,使用如下命令关闭
# 停止airflow webserver
ps -ef | grep 'airflow' | grep 'webserver' | awk '{print $2}' | xargs kill -9
cd $AIRFLOW_HOME
rm -rf airflow-webserver.pid
rm -rf airflow-webserver-monitor.pid
# 停止airflow scheduler
ps -ef | grep 'airflow' | grep 'scheduler' | awk '{print $2}' | xargs kill -9
cd $AIRFLOW_HOME
rm -rf airflow-scheduler.pid
Airflow的常用命令
(2022.12.04 Sun)
# 测试任务,格式:airflow test dag_id task_id execution_time
airflow test test_task test1 2019-09-10
# 查看生效的 dags
airflow list_dags -sd $AIRFLOW_HOME/dags
# 开始运行任务(同web界面点trigger按钮)
airflow trigger_dag test_task
# 暂停任务
airflow pause dag_id
# 取消暂停,等同于在web管理界面打开off按钮
airflow unpause dag_id
# 查看task列表
airflow list_tasks dag_id 查看task列表
# 清空任务状态
airflow clear dag_id
# 运行task
airflow run dag_id task_id execution_date
Reference
1 Apache airflow official website
2 towardsdatascience, Apache Airflow architecture, Giorgos Myrianthous