airflow整体架构
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
airflow整体架构
run命令运⾏过程
读取dag⽂件⽣成task依赖关系,然后⽣成封装airflow run的command命令,通过celery发送到executor端,重新执⾏该airflow run命令。
scheduler命令运⾏过程:
调度器通过SchedulerJob类run⽅法执⾏整个流程,包括使⽤多进程处理DagDir,包括⽣成Dag,产⽣DagRun,每个DagRun下⼜⽣成多个TaskInstance,然后将任务通过
Executor分发到执⾏节点运⾏。
涉及到的⽅法有:SchedulerJob类create_dag_run创建DagRun,DagRun类verify_integrity⽣成TaskInstance,任务封装为command命令后发送
到执⾏节点,执⾏节点通过airflow run命令执⾏该command,此时Job类型为LocalTaskJob
数据库表关系:
dag_run表通过execution_date和task_instance关联
task_instance通过job_id和job表关联
通过airflow run命令观察整个流程
cli.py的run函数
关键语句dag = get_dag(args),根据dag_id获取dag实例
进⼊get_dag函数,关键语句dagbag = DagBag(process_subdir(args.subdir))
进⼊DagBag类__init__函数,关键语句self.collect_dags(dag_folder)
进⼊collect_dags函数,关键语句self.process_file(dag_folder, only_if_updated=only_if_updated)
进⼊process_file函数,关键语句
m = imp.load_source(mod_name, filepath) //filepath:DagDir⽬录下的⼀个Dag⽂件,假设为test.py
通过该语句test.py会被导⼊,语句被执⾏。
在语句被执⾏时,⽐如test.py中有操作为:run_this_last = DummyOperator(task_id='run_this_last', dag=dag),在基类BaseOperator的__init__函数中存在语句self.dag = dag,进⽽调⽤dag的setter⽅法所有的dag被保存在⼀个字典中。
task = dag.get_task(task_id=args.task_id),所有task的实例已经被添加到dag实例的字典中
_run(args, dag, ti)
进⼊_run函数,我们查看else项针对远程执⾏任务的分⽀。
关键语句
executor = GetDefaultExecutor() //获取executor的实例
executor.start()
executor.queue_task_instance(
ti,
mark_success=args.mark_success,
pickle_id=pickle_id,
ignore_all_deps=args.ignore_all_dependencies,
ignore_depends_on_past=args.ignore_depends_on_past,
ignore_task_deps=args.ignore_dependencies,
ignore_ti_state=args.force,
pool=args.pool)
executor.heartbeat() //将命令队列中的命令拿出来调⽤executor的execute_async⽅法发送过去,然后同步等结果
executor.end()
进⼊queue_task_instance函数,此处是CeleryExcutor类的实例,基类BaseExecutor
command = task_mand(
local=True,
mark_success=mark_success,
ignore_all_deps=ignore_all_deps,
ignore_depends_on_past=ignore_depends_on_past,
ignore_task_deps=ignore_task_deps,
ignore_ti_state=ignore_ti_state,
pool=pool,
pickle_id=pickle_id,
cfg_path=cfg_path)
self.queue_command( //将command放⼊队列
task_instance,
command,
priority=task_instance.task.priority_weight_total,
queue=task_instance.task.queue)
再次进⼊command函数,我们发现它依次调⽤了command_as_list、TaskInstance.generate_command
iso = execution_date.isoformat()
cmd = ["airflow", "run", str(dag_id), str(task_id), str(iso)]
cmd.extend(["--mark_success"]) if mark_success else None
cmd.extend(["--pickle", str(pickle_id)]) if pickle_id else None
cmd.extend(["--job_id", str(job_id)]) if job_id else None
cmd.extend(["-A"]) if ignore_all_deps else None
cmd.extend(["-i"]) if ignore_task_deps else None
cmd.extend(["-I"]) if ignore_depends_on_past else None
cmd.extend(["--force"]) if ignore_ti_state else None
cmd.extend(["--local"]) if local else None
cmd.extend(["--pool", pool]) if pool else None
cmd.extend(["--raw"]) if raw else None
cmd.extend(["-sd", file_path]) if file_path else None
cmd.extend(["--cfg_path", cfg_path]) if cfg_path else None
return cmd
结果就是:服务端发送⼀个airflow run命令到executor,然后通过Celery执⾏shell命令,命令内容就是上⾯的cmd结果。
然后executor端会重新执⾏⼀遍airflow run命令。
整个流程结束。