其实怎么部署  airflow 又哪些特性,然后功能又是如何全面都可以在 Reference 的文章里面找到,都不是重点这里就不赘述了。

这里重点谈一下我在部署完成仔细阅读文档之后觉得可以总结的一些东西,或者踩到的一些坑。

首选明确 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 实例化的实例。

在使用过程中,需要谨记这些概念不然很容易就被绕晕。

TimeZone:

时区问题可以说是 airflow 中根本绕不开的一个问题,官方文档也拿整整一章来阐述时区给 airflow 带来的影响。

官方默认使用 UTC+0 时间来作为 airflow 的时间,并且在 airflow 提供的 webserver 上,这个时区直到现在 1.10.1 版本上依旧是无法被配置的。所以我们在 server 上看到的时间默认都是 UTC+0 的时间。但是系统启动的时间,以及写入数据库元数据的时间确是可以配置时区的。他的格式遵循 IANA 格式。可以通过配置 airflow 的配置文件 airflow.cfg 改变这个时区。例如我在启动的时候就配置了中国时间:

  1. # Default timezone in case supplied date times are naive
  2. # can be utc (default), system, or any IANA timezone string (e.g. Europe/Amsterdam)
  3. #default_timezone = utc
  4. default_timezone = Asia/Chongqing

当配置了这个生效之后,我们给任务配置的启动时间,以及 runtime 之类的时间会遵循这个时间(虽然在 ui 界面上看还是 UTC+0 的非常分裂。。。)

例如我们来看一个执行任务:

可以看到 Last Run 字段指明了该字段是 2018-12-09 16:00 被执行了。按照我们刚才的配置 UTC+8 应该是 10号的 0点被执行了。我们来看下数据库里是否真的是这样呢?

可以通过下图发现完全按照我们预期:

  1. mysql> select * from task_instance where task_id = 'sensors'\G;
  2. *************************** . row ***************************
  3. task_id: sensors
  4. dag_id: sensors_dag
  5. execution_date: -- ::00.000000
  6. start_date: -- ::04.547631
  7. end_date: -- ::50.686937
  8. duration: 286.139
  9. state: success
  10. try_number:
  11. hostname: zed-2
  12. unixname: apache-airflow
  13. job_id:
  14. pool: NULL
  15. queue: default
  16. priority_weight:
  17. operator: BashOperator
  18. queued_dttm: -- ::03.302928
  19. pid:
  20. max_tries:
  21. executor_config: }q .

所以说,证明了只要我们设置了刚才的参数之后,只有 ui 界面依然继续展示 UTC+0 的时间,其实我们真正的执行操作的时区已经被修改过来了。

另外还需要注意的一个地方在于任务的申明那里,在申明一个 dag 的时候同样需要指明自己的时区,否则一脸懵逼为啥到了时间为什么没有正常调度起来。

  1. import pendulum
  2. import datetime
  3.  
  4. local_tz = pendulum.timezone("Asia/Chongqing")
  5.  
  6. # start 接收一个 %Y-%m-%d %H:%M:%S 的字符串时间
  7. def init_default_args(owner, start_time, retry=, email=None):
  8. if not email:
  9. email = []
  10. if not isinstance(start_time, datetime.datetime):
  11. raise TypeError('start_date must be datetime.')
  12.  
  13. d = start_time.replace(tzinfo=local_tz)
  14.  
  15. return {
  16. 'owner': owner,
  17. 'depends_on_past': False,
  18. 'start_date': d,
  19. 'email': email,
  20. 'email_on_failure': False,
  21. 'email_on_retry': False,
  22. 'retries': retry,
  23. 'retry_delay': datetime.timedelta(minutes=),
  24. }

这里我在申明默认 default_args 参数的时候就显示的指明了时区并且赋值给 start_date 让他开始的时间复合我们的预期。

Backfill:

感觉这个也非常让人懵逼值得拿出来多多少少谈一下。

光从字面意思来理解作为一个中国人我真的是一下没有 get 到他的点,但是后来去查了一下文档结合他的行为看了一下可以把它简单的理解成当你错过了某一次执行时间之后,往回去补充执行的行为。我们可以使用手动方法来执行这个行为

  1. airflow backfill sensors -s -- -e --

他会回补这个时间段开始的 和 -e 后面时间段结束期间所有的任务执行。回补的意思就是把没有执行的操作都执行一遍。

这个特性想法很好,但是自自动触发的时候不注意就会产生非常不可预期的问题。

比如刚才在上面我们谈到的在给 dag 配置的时候指定的 default_args 上面有一个参数 start_date。如果我们不给 dag 指定不回补,那么 airflow 会默认回补从系统当前时间到我们指定的 start_date 期间的任务。如果这个参数设置得不恰当会打来恐怖的回补,所以一般我都会禁用回补。

  1. sensors_dag = DAG(
  2. 'sensors_dag',
  3. default_args=default_args,
  4. schedule_interval=u'0 0 * * *',
  5. catchup=False)

指定 catchup=False 。让他从最新的任务时间点开始执行。这个在官方文档 Scheduling & Triggers 一章有详细提到。

Operator:

现在这一章我只有一个地方觉得有点坑。可能是我还没有深度使用吧

由于 airflow 支持模版 jinja 的模版功能,所以说在使用 BashOperator 的时候要注意自己的写法,官方文档对此有描述

  1. Troubleshooting
  2. Jinja template not found
  3. Add a space after the script name when directly calling a Bash script with the bash_command argument. This is because Airflow tries to apply a Jinja template to it, which will fail.
  4.  
  5. t2 = BashOperator(
  6. task_id='bash_example',
  7.  
  8. # This fails with `Jinja template not found` error
  9. # bash_command="/home/batcher/test.sh",
  10.  
  11. # This works (has a space after)
  12. bash_command="/home/batcher/test.sh ",
  13. dag=dag)

我觉得这个。。。还蛮坑的- -

这一章其实应该有蛮多的内容可以延伸,包括社区也给 airflow 贡献了非常多的 Operator。等我深度使用之后再来 backfill 吧哈哈哈哈。

--------------------------------------------分割线--------------------------------------------

最近遇到一个这样的问题,我们有一次 scheduler 死了,然后一下启起来发现全部任务被一块执行了。甚至每个 dag 多天没有跑完的任务直接起来,把我们的服务器直接按死了。

后面我们需要让该类情况得到控制,至少让一个 dag 同一时刻只有一天被调度起来,而不是单一 dag 多天同时被拉起来,这样直接把服务器打挂的概率非常高。

需要将全局文件 airflow.cfg 的参数 max_active_runs_per_dag 从默认的 16 改为 1

Reference:

https://airflow.apache.org  airflow 官方文档

https://zhuanlan.zhihu.com/p/44768244  如何部署一个健壮的 apache-airflow 调度系统

http://www.shuhegroup.com/newsmedias/%E6%B5%85%E8%B0%88%E8%B0%83%E5%BA%A6%E5%B7%A5%E5%85%B7airflow/  浅谈调度工具——Airflow

https://stackoverflow.com/questions/49231340/how-to-limit-airflow-to-run-only-1-dag-run-at-a-time  How to limit Airflow to run only 1 DAG run at a time?

https://airflow.apache.org/faq.html

Airflow 使用随笔(内含 TimeZone 和 Backfill 等的详解)的更多相关文章

  1. Android随笔之——闹钟制作铺垫之AlarmManager详解

    说实话,之前写的两篇博客Android广播机制Broadcast详解.Android时间.日期相关类和方法以及现在要写的,都算是为之后要写的闹钟应用做铺垫,有兴趣的话,大家可以去看看前两篇博客. 一. ...

  2. PyQt(Python+Qt)学习随笔:富文本编辑器QTextEdit功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QTextEdit是一个高级的所见即所得的文档查看器和编辑器 ...

  3. Linux随笔 - Linux LVM逻辑卷配置过程详解[转载]

    许多Linux使用者安装操作系统时都会遇到这样的困境:如何精确评估和分配各个硬盘分区的容量,如果当初评估不准确,一旦系统分区不够用时可能不得不备份.删除相关数据,甚至被迫重新规划分区并重装操作系统,以 ...

  4. PyQt(Python+Qt)学习随笔:纯文本编辑器QPlainTextEdit功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QPlainTextEdit是用于纯文本的一个高级文档编辑器 ...

  5. 【图文+视频新手也友好】Java一维数组详细讲解(内含练习题答案+详解彩蛋喔~)

    目录 视频讲解: 一.数组的概述 二.一维数组的使用 三.Arrays工具类中的sort方法(sort方法用的多,我们具体讲一下) 四.数组中的常见异常 五.一维数组练习题 六.彩蛋(本期视频使用的P ...

  6. Android随笔之——PackageManager详解

    参考:http://www.cnblogs.com/xingfuzzhd/p/3374504.html 今天要讲的是PackageManager.Android系统为我们提供了很多服务管理的类,包括A ...

  7. [转载] Android随笔之——PackageManager详解

    本文转载自: http://www.cnblogs.com/travellife/p/3932823.html 参考:http://www.cnblogs.com/xingfuzzhd/p/33745 ...

  8. php.ini中date.timezone设置详解

    date.timezone设置php5默认date.timezone为utc,改为date.timezone = PRC即可解决时间相差八小时的问题,但我在php的官方文档中看了半天也没找到这个参数啊 ...

  9. 【转】Android随笔之——PackageManager详解

    参考:http://www.cnblogs.com/xingfuzzhd/p/3374504.html 今天要讲的是PackageManager.Android系统为我们提供了很多服务管理的类,包括A ...

随机推荐

  1. ZooKeeper典型应用场景概览

    ZooKeeper是一个高可用的分布式数据管理与系统协调框架.基于对Paxos算法的实现,使该框架保证了分布式环境中数据的强一致性,也正是基于这样的特性,使得ZooKeeper解决很多分布式问题.网上 ...

  2. RandomAccess

    在List集合中,我们经常会用到ArrayList以及LinkedList集合,但是通过查看源码,就会发现ArrayList实现RandomAccess接口,但是RandomAccess接口里面是空的 ...

  3. pytorch Debug —交互式调试工具Pdb (ipdb是增强版的pdb)-1-使用说明

    初学时大多使用print或log调试程序,这在小规模的程序下很方便 但是更好的方法是一边运行一边检查里面的变量和方法 1.Pdb Pdb是一个交互式的调试工具,集成于Python标准库中 Pdb能让你 ...

  4. 初学Python——集合及其运算

    一.集合定义及其功能 集合是一个无序的.不重复的数据组合,和字典列表一样也是一种数据类型. 集合两个最主要的功能:①去重(把一个列表变成集合,就自动去重了) ②关系测试(测试两组数据之间的交.并.差集 ...

  5. 《maven in action》部分知识点总结

    maven in action 的部分知识点总结 今天又将<maven in action>这本书看了一遍,总结了一下,大概需要的知识点 (一)解耦   使用maven,在没有任何实际的J ...

  6. ASP.NET Core中代码使用X509证书,部署到IIS上后报错:System cannot find the specified file 的解决办法(转载)

    问: I am trying to embrace the mysteries of SSL communication and have found a great tutorial on this ...

  7. vi十六进制编辑

    指定行:n 光标行之前或之后的n个字符nl 之后 2l 光标位置两个字符后nh 之前 2h 光标位置两个字符前 光标行之上或之下的n个字符nk 之上 1k 光标位置1个字符之上nj 之下 1j 光标位 ...

  8. Item 14: 如果函数不会抛出异常就把它们声明为noexcept

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 在C++98中,异常规范(exception specificat ...

  9. H5 13-子元素选择器

    13-子元素选择器 p{ color: red; } */ /* #identity>p{ color: blue; } */ div>ul>li>p{ color: purp ...

  10. Verilog语法遗漏点

    1 关于参数定义 Parameter:parameter只能定义在端口生命的前面,如 Input[whith:0] a; Parameter whith=4; 这样的参数定义出现在声明的后面会报错 2 ...