Airflow CeleryExecutor安装和配置说明

Airflow这个神器似乎在国内用的并不算多,所以很多文档都不是很全。Celery也是个神器。本文主要记录Airflow如何将Executor切换成CeleryExecutor——只有切换成CeleryExecutor,才能实现sub节点的单节点重跑,否则整个sub节点都需要重跑。配置的坑比较多,也修改了源码,特此记录说明。

##1. 安装RabbitMQ
RabbitMQ是Celery官方推荐的生产级Broker(消息代理),RabbitMQ介绍有很多,建议仔细阅读一份,了解下再继续下面的配置,否则会碰到很多坑。

安装Erlang: CenterOS 7有默认安装
安装rabbitmq: yum install -y rabbitmq
启动rabbitmq: rabbitmq-server -detached
开机启动rabbitmq: chkconfig rabbitmq-server on
启动web监控台:rabbitmq-plugins enable rabbitmq_management
这里没有做特殊的设置,暂时使用默认配置
添加用户:

rabbitmqctl add_user celery celery@2017
rabbitmqctl add_vhost Celery
rabbitmqctl set_permissions -p Celery celery “." ".” “.*”

2. 安装Celery及组件安装

pip install celery
配置CeleryExecutor (rabbitmq支持)
安装airflow的celery和rabbitmq组件

pip install airflow[celery, rabbitmq]

3. 配置Airflow

主要配置四个参数,其他的并发量各位视自己的环境资源,适当配置大小

更改executor为 executor = CeleryExecutor
更改broker_url
broker_url = amqp://celery:celery@2017@localhost:5672/celery
Format explanation: transport://userid:password@hostname:port/virtual_host
更改celery_result_backend,我使用MySQL作为backend
celery_result_backend = db+mysql://airflow:airflow@2017@localhost:3306/airflow
Format explanation: transport://userid:password@hostname:port/virtual_host

另外,容易碰到一个问题

File "/usr/lib64/python2.7/site-packages/librabbitmq/__init__.py", line 199, in __init__
    self.connect()
OperationalError: Couldn't log in: a socket error occurred

这个问题原因是因为broker_url写错了,结果vhost末尾不应该有/,即配置amqp://celery:[email protected]:5672/celery/不应该有末尾的//本身也是一个vhost。

##问题说明
搞了很久,查看了RabbitMQ控制页面,发现如果不启动work,消息是有正常写入MQ的,但是worker总是没有生效,后来查看日志,发现是问题1导致。问题1解决后,还是不能正常启动任务(注意,webserver页面没有任何错误提示,一定要跟踪日志),再跟踪日志,发现了问题2

问题1-不能使用根用户启动work

我的解决方式是开启,这个celery并不推荐。具体修改方式是:进入/usr/lib/python2.7/site-packages/airflow/executors,修改celery_executor.py源码文件

from celery import Celery, platforms
在app = Celery(…)后新增
platforms.C_FORCE_ROOT = True

如上图中,红框圈定的就是修改的内容。再次重启airflow worker即可。

###问题2-Received and deleted unknown message. Wrong destination?!?
该问题导致比较奇葩,目测以为是broker_url配置错了,但是不是滴,谷歌才知道:
处理方式是
https://github.com/celery/celery/issues/3675
即卸载librabbitmq库,并且将ampq更改为pyampq,具体原因是
librabbitmq 1.6.1 doesn’t work with Celery4.0.2 #93
celery4.0.2版本与librabbitmq冲突,好吧,这样的bug一直没有修复。

###问题3-Unrecoverable error: PreconditionFailed(406, u"PRECONDITION_FAILED
又是个迷糊的问题,具体报错日志如下

[2017-02-20 15:34:40,265: CRITICAL/MainProcess] Unrecoverable error: PreconditionFailed(406, u"PRECONDITION_FAILED - inequivalent arg 'x-expires'for queue '[email protected]' in vhost 'celery': received the value '10000' of type 'signedint' but current is none", (50, 10), u'Queue.declare')

查看队列
Airflow CeleryExecutor安装和配置说明_第1张图片
发现已经发布成功了,可是就没有消费。。。
由于RabbitMQ控制台无法查看到queues,在服务器上rabbitmq查看队列正确姿势是
/usr/sbin/rabbitmqctl -n 节点名 list_queues -p vhost信息
其中,节点名可以通过rabbitmqctl status | grep node获取到,具体我的队列信息是

> rabbitmqctl -n rabbit@cdh list_queues -p celery
Listing queues ...
448cb450d455429a8342b38f5e123e1f	1
7444da414c6d42eba7ef615c55cd02a0	1
celery	0
[email protected]	0
celeryev.028b3030-bcda-4703-a0a5-10414d3571fc	0
celeryev.9b7e6329-b0b0-4cba-9575-8b4fcc1932e4	0
...done.

看到没有,消息不在celery中,而是在两个临时队列。这个很诡异了,难道是我之前的脏数据。重新再来一遍:
重置RabbitMQ数据
rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl start_app
需要重新设置用户
rabbitmqctl add_user celery celery@2017 rabbitmq add_vhost Celery rabbitmqctl set_permissions -p Celery celery ".*" ".*" ".*"
搞到这儿的时候,有些恍然了,原来自己一直没有配置Celery的Exchange,所以会导致刚才发生的问题——没有按Topic的传递消息!发现这个问题后,不想配置exchange了,我直接偷懒的使用了vhost=/,配置airflow.cfg
broker_url = pyamqp://celery:celery@[email protected]:5672//
重新启动Airflow,OK了
Airflow CeleryExecutor安装和配置说明_第2张图片
这里写图片描述

##小结
可以满足Airflow的sub节点的Run Force的操作了。但是,依旧有蛋疼的事情,就是Run Force只能一个个执行,Sub节点下的Clear DownStream并不能拉起任务的重跑,这个问题,暂时可以通过重启Airflow webserver完成——但是,感觉很不友好。为什么Run的选项没有DownStream的选项?看来,只能在Sub节点Clear的时候,把任务也丢到任务队列中

##参考
http://blog.genesino.com/2016/05/airflow/#celeryexecutor-rabbitmq
http://www.cnblogs.com/Tommy-Yu/p/6230527.html

你可能感兴趣的:(工程开发,分布式,Celery,Airflow)