Ariflow DAG编码和部署

一、编码

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)
Ariflow DAG编码和部署_第1张图片
image

其他编码要点

使用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

  1. 删除DAG文件;
  2. 删除数据库记录:
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启后,会根据自生的调度情况执行。


image

你可能感兴趣的:(Ariflow DAG编码和部署)