一、编码
1、库包引入
import airflow
from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from datetime import timedelta
2、配置运行上下文参数
default_args = {
'owner': 'airflow', #所有者
'depends_on_past': False, #是否依赖上次DAG的运行结果,建议为False,True容易出BUG
'start_date': airflow.utils.dates.days_ago(2), #DAG启动时间
'email': ['[email protected]'],
'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'
}
3、实例化DAG,以及DAG启动间隔等上下文
dag = DAG(
'test2', #在整个DAGS中的唯一ID或者唯一名称
default_args=default_args, #上下文参数
description='A simple tutorial DAG',
schedule_interval='* * * * *') #DAG启动间隔
4、实例化任务
t1 = BashOperator( #算子或者节点或者任务
task_id='print_date', #DAG中的唯一ID
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)
t4 = BashOperator(
task_id='shell',
bash_command='(cd /home/airflow/airflow/test; python run.py) ',
dag=dag)
5、配置任务流图及任务间依赖
t2.set_upstream(t1)
t3.set_upstream(t1)
t4.set_upstream(t3)
其他编码要点
使用Xcom在task之间传参
可以直接使用jinja模板语言,在{{}}中调用ti的xcom_push和xcom_pull方法,下面的例子为t1使用xcom_push推出了一个kv,t2通过taskid和key来接收
dag = DAG(
dag_id='xcomtest', default_args=default_args, schedule_interval='*/2 * ** *')
t1 = BashOperator(
task_id='xcom',
bash_command='''{{ ti.xcom_push(key='aaa', value='bbb') }}''',
dag=dag)
t2 = BashOperator(
task_id='xcom2',
bash_command='''echo"{{ ti.xcom_pull(key='aaa', task_ids='xcom') }}" ''',
dag=dag)
t2.set_upstream(t1)
BashOperator运行shell
当使用BashOperator时,command需要调用脚本时,脚本后需要有个空格,否则报错,只有在执行 bash 脚本(末尾是.sh扩展名)时才会有这种问题,并不是任何 shell 命令都有。
t1 = BashOperator(
task_id='process_rankinglist',
bash_command='/home/rankinglist_processor/run.sh ',
dag=dag)
airflow提供了很多Macros Variables,可以直接使用jinja模板语言调用宏变量
templated_command = """
echo "dag_run:{{ dag_run }}"
echo "run_id:{{ run_id }}"
echo "execution_date:{{ execution_date }}"
echo "ts:{{ ts }}"
echo "ti:{{ ti }}"
sleep 3
"""
t1 = BashOperator(
task_id='xcom',
bash_command=templated_command,
dag=dag)
from airflow.models import Variable
foo = Variable.get("foo")
bar = Variable.get("bar", deserialize_json=True)
但是需要注意,其中的execution_date并不是task的真正执行时间,而是上一周期task的执行时间。
即可以理解为“actual_execution_date= execution_date +schedual_interval”,或者我们换一种说法,我们在airflow上看到一个任务是6am执行的,而且interval=4hours,那么execution_date的值是2am,而不是6am,所以获取某个task的真正执行时间,需要获取execution_date的下个执行周期时间,即使用dag.following_schedule(execution_date)
pool
池用来控制同个pool的task并行度。
aggregate_db_message_job = BashOperator(
task_id='aggregate_db_message_job',
execution_timeout=timedelta(hours=3),
pool='ep_data_pipeline_db_msg_agg',
bash_command=aggregate_db_message_job_cmd,
dag=dag)
aggregate_db_message_job.set_upstream(wait_for_empty_queue)
上例中,aggregate_db_message_job设置了pool,如果pool的最大并行度为1,当其它任务也设置该池时,如果aggregate_db_message_job在运行,则其它任务必须等待。
特定任务只在特殊机器上运行
可以给DAG中的task指定一个queue, 然后在特定的机器上运行 airflow worker -q=QUEUE_NAME 即可实现
主动通知DAG本Operator运行失败
1. PythonOperator 直接抛出异常
2. BashOperator
a ) shell脚本: exit 1(任何非0值)
b ) python: raise ValueError('This will exit bash with an error.');
删除DAG
- 删除DAG文件;
- 删除数据库记录:
set @dag_id = 'xxxdagname';
delete from airflow.xcom where dag_id = @dag_id;
delete from airflow.task_instance where dag_id = @dag_id;
delete from airflow.sla_miss where dag_id = @dag_id;
delete from airflow.log where dag_id = @dag_id;
delete from airflow.job where dag_id = @dag_id;
delete from airflow.dag_run where dag_id = @dag_id;
delete from airflow.dag where dag_id = @dag_id;
delete from airflow.dag_stats where dag_id = @dag_id;
delete from airflow.task_fail where dag_id = @dag_id;
commit;
二、部署DAG
把DAG文件放到$AIRFLOW_HIME/dags下,然后执行:
python testFile.py
这样dag就被创建了
三、启动dag
在web上,点击最左边按钮,将off切换为on ,这样dag就启动了。dag启后,会根据自生的调度情况执行。