在RedHat系Linux上部署Python的Celery框架的教程


Posted in Python onApril 07, 2015

 Celery (芹菜)是基于Python开发的分布式任务队列。它支持使用任务队列的方式在分布的机器/进程/线程上执行任务调度。
架构设计

在RedHat系Linux上部署Python的Celery框架的教程

 Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。

1. 消息中间件

    Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括,RabbitMQ, Redis, MongoDB (experimental), Amazon SQS (experimental),CouchDB (experimental), SQLAlchemy (experimental),Django ORM (experimental), IronMQ

2.任务执行单元

    Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。

3.任务结果存储

    Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括AMQP, Redis,memcached, MongoDB,SQLAlchemy, Django ORM,Apache Cassandra, IronCache

另外, Celery还支持不同的并发和序列化的手段

1.并发

    Prefork, Eventlet, gevent, threads/single threaded

2.序列化

    pickle, json, yaml, msgpack. zlib, bzip2 compression, Cryptographic message signing 等等

安装和运行

Celery的安装过程略为复杂,下面的安装过程是基于我的AWS EC2的Linux版本的安装过程,不同的系统安装过程可能会有差异。大家可以参考官方文档。

首先我选择RabbitMQ作为消息中间件,所以要先安装RabbitMQ。作为安装准备,先更新YUM。
 

sudo yum -y update

RabbitMQ是基于erlang的,所以先安装erlang
 
# Add and enable relevant application repositories:
# Note: We are also enabling third party remi package repositories.
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
sudo rpm -Uvh remi-release-6*.rpm epel-release-6*.rpm
 
# Finally, download and install Erlang:
yum install -y erlang

然后安装RabbitMQ
 

# Download the latest RabbitMQ package using wget:
wget 
# Add the necessary keys for verification:
rpm --import 
# Install the .RPM package using YUM:
yum install rabbitmq-server-3.2.2-1.noarch.rpm

启动RabbitMQ服务
 

rabbitmq-server start
RabbitMQ服务已经准备好了,然后安装Celery, 假定你使用pip来管理你的python安装包
pip install Celery

 

为了测试Celery是否工作,我们运行一个最简单的任务,编写tasks.py
 
from celery import Celery
 
app = Celery('tasks', backend='amqp', broker='amqp://guest@localhost//')
app.conf.CELERY_RESULT_BACKEND = 'db+sqlite:///results.sqlite'
 
@app.task
def add(x, y):
 return x + y

在当前目录运行一个worker,用来执行这个加法的task
 

celery -A tasks worker --loglevel=info

其中-A参数表示的是Celery App的名字。注意这里我使用的是SQLAlchemy作为结果存储。对应的python包要事先安装好。

worker日志中我们会看到这样的信息
 

- ** ---------- [config]
- ** ---------- .> app:   tasks:0x1e68d50
- ** ---------- .> transport: amqp://guest:**@localhost:5672//
- ** ---------- .> results:  db+sqlite:///results.sqlite
- *** --- * --- .> concurrency: 8 (prefork)

其中,我们可以看到worker缺省使用prefork来执行并发,并设置并发数为8

下面的任务执行的客户端代码:
 

from tasks import add
import time
result = add.delay(4,4)
 
while not result.ready():
 print "not ready yet"
 time.sleep(5)
 
print result.get()

用python执行这段客户端代码,在客户端,结果如下
 

not ready 
8

Work日志显示
 

[2015-03-12 02:54:07,973: INFO/MainProcess] Received task: tasks.add[34c4210f-1bc5-420f-a421-1500361b914f]
[2015-03-12 02:54:08,006: INFO/MainProcess] Task tasks.add[34c4210f-1bc5-420f-a421-1500361b914f] succeeded in 0.0309705100954s: 8

这里我们可以发现,每一个task有一个唯一的ID,task异步执行在worker上。

这里要注意的是,如果你运行官方文档中的例子,你是无法在客户端得到结果的,这也是我为什么要使用SQLAlchemy来存储任务执行结果的原因。官方的例子使用AMPQ,有可能Worker在打印日志的时候取出了task的运行结果显示在worker日志中,然而AMPQ作为一个消息队列,当消息被取走后,队列中就没有了,于是客户端总是无法得到任务的执行结果。不知道为什么官方文档对这样的错误视而不见。

如果大家想要对Celery做更进一步的了解,请参考官方文档

Python 相关文章推荐
Python 爬虫模拟登陆知乎
Sep 23 Python
Python实现的科学计算器功能示例
Aug 04 Python
Python使用pyh生成HTML文档的方法示例
Mar 10 Python
Python文本处理之按行处理大文件的方法
Apr 09 Python
python实现飞机大战微信小游戏
Mar 21 Python
python3.6.3转化为win-exe文件发布的方法
Oct 31 Python
Python-while 计算100以内奇数和的方法
Jun 11 Python
python动态视频下载器的实现方法
Sep 16 Python
Pandas 解决dataframe的一列进行向下顺移问题
Dec 27 Python
获取python运行输出的数据并解析存为dataFrame实例
Jul 07 Python
python+excel接口自动化获取token并作为请求参数进行传参操作
Nov 10 Python
python绘制简单直方图(质量分布图)的方法
Apr 21 Python
详解Python3.1版本带来的核心变化
Apr 07 #Python
初学Python函数的笔记整理
Apr 07 #Python
利用Python绘制数据的瀑布图的教程
Apr 07 #Python
浅析Python中的多进程与多线程的使用
Apr 07 #Python
Python多线程编程(八):使用Event实现线程间通信
Apr 05 #Python
Python多线程编程(七):使用Condition实现复杂同步
Apr 05 #Python
Python多线程编程(六):可重入锁RLock
Apr 05 #Python
You might like
强烈推荐:php.ini中文版(1)
2006/10/09 PHP
如何从一个php文件向另一个地址post数据,不用表单和隐藏的变量的
2007/03/06 PHP
对于PHP 5.4 你必须要知道的
2013/08/07 PHP
PHP分页类集锦
2014/11/18 PHP
PHP把MSSQL数据导入到MYSQL的方法
2014/12/27 PHP
document.all还是document.getElementsByName?
2006/07/21 Javascript
原生Js页面滚动延迟加载图片实现原理及过程
2013/06/24 Javascript
jqplot通过ajax动态画折线图的方法及思路
2013/12/08 Javascript
JS对话框_JS模态对话框showModalDialog用法总结
2014/01/11 Javascript
jQuery实现鼠标滚轮动态改变样式或效果
2015/01/05 Javascript
javascript数组排序汇总
2015/07/07 Javascript
JavaScript常用判断写法大全(推荐)
2016/05/30 Javascript
Angularjs---项目搭建图文教程
2016/07/08 Javascript
JS简单实现浮动窗口效果示例
2016/09/07 Javascript
JQuery学习总结【二】
2016/12/01 Javascript
JavaScript和JQuery获取DIV值的方法示例
2017/03/07 Javascript
jQuery EasyUI 为Combo,Combobox添加清除值功能的实例
2017/04/13 jQuery
node.js中debug模块的简单介绍与使用
2017/04/25 Javascript
vue使用keep-alive实现数据缓存不刷新
2017/10/21 Javascript
layui switch 开关监听 弹出确定状态转换的例子
2019/09/21 Javascript
微信小程序上传图片并等比列压缩到指定大小的实例代码
2019/10/24 Javascript
关于vue3默认把所有onSomething当作v-on事件绑定的思考
2020/05/15 Javascript
Python操作MySQL数据库的三种方法总结
2018/01/30 Python
python框架中flask知识点总结
2018/08/17 Python
使用 PyTorch 实现 MLP 并在 MNIST 数据集上验证方式
2020/01/08 Python
一文带你了解Python 四种常见基础爬虫方法介绍
2020/12/04 Python
W Concept美国:精选全球独立设计师
2017/02/22 全球购物
英国最全面的橄榄球联盟门票网站:Live Rugby Tickets
2018/10/06 全球购物
校园学雷锋活动月总结
2014/03/09 职场文书
大学生个人求职信
2014/06/02 职场文书
公司总经理任命书
2014/06/05 职场文书
2014年置业顾问工作总结
2014/11/17 职场文书
入党转正申请报告
2015/05/15 职场文书
《詹天佑》教学反思
2016/02/20 职场文书
5种 JavaScript 方式实现数组扁平化
2021/10/05 Javascript
深入讲解Vue中父子组件通信与事件触发
2022/03/22 Vue.js