在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实现获取客户机上指定文件并传输到服务器的方法
Mar 16 Python
Python缩进和冒号详解
Jun 01 Python
python timestamp和datetime之间转换详解
Dec 11 Python
python迭代dict的key和value的方法
Jul 06 Python
wtfPython—Python中一组有趣微妙的代码【收藏】
Aug 31 Python
Flask框架重定向,错误显示,Responses响应及Sessions会话操作示例
Aug 01 Python
python中用logging实现日志滚动和过期日志删除功能
Aug 20 Python
Python 文件操作之读取文件(read),文件指针与写入文件(write),文件打开方式示例
Sep 29 Python
python实现指定ip端口扫描方式
Dec 17 Python
pytorch 自定义卷积核进行卷积操作方式
Dec 30 Python
浅析Python 条件控制语句
Jul 15 Python
Django haystack实现全文搜索代码示例
Nov 28 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
【动漫杂谈】关于《请在T台上微笑》
2020/03/03 日漫
基于PHP静态类的原罪详解
2013/05/06 PHP
ThinkPHP之M方法实例详解
2014/06/20 PHP
PHP调用存储过程返回值不一致问题的解决方法分析
2016/04/26 PHP
JS中把字符转成ASCII值的函数示例代码
2013/11/21 Javascript
node.js中的fs.rmdir方法使用说明
2014/12/16 Javascript
JavaScript中数组成员的添加、删除介绍
2014/12/30 Javascript
js实现从右向左缓缓浮出网页浮动层广告的方法
2015/05/09 Javascript
js自定义回调函数
2015/12/13 Javascript
jQuery Ajax和getJSON获取后台普通json数据和层级json数据用法分析
2016/06/08 Javascript
Node.js Express 框架 POST方法详解
2017/01/23 Javascript
微信小程序 wx.login解密出现乱码的问题解决办法
2017/03/10 Javascript
JavaScript图片处理与合成总结
2018/03/04 Javascript
Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案
2018/05/15 Javascript
为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置
2019/09/29 Javascript
JS如何在数组指定位置插入元素
2020/03/10 Javascript
js+canvas绘制图形验证码
2020/09/21 Javascript
一波神奇的Python语句、函数与方法的使用技巧总结
2015/12/08 Python
Python编程在flask中模拟进行Restful的CRUD操作
2018/12/28 Python
基于Python测试程序是否有错误
2020/05/16 Python
波兰家具和室内装饰品购物网站:Vivre
2018/04/10 全球购物
工商企业管理实习自我鉴定
2013/12/04 职场文书
经销商培训邀请函
2014/01/21 职场文书
快餐店的创业计划书范文
2014/01/29 职场文书
军训拉歌口号
2014/06/13 职场文书
分公司总经理岗位职责
2014/08/03 职场文书
党的群众路线教育实践活动个人对照检查材料(校长)
2014/11/05 职场文书
共青团员自我评价
2015/03/10 职场文书
小学六一儿童节活动总结
2015/05/05 职场文书
2015秋季小学开学寄语
2015/05/27 职场文书
遗愿清单观后感
2015/06/09 职场文书
公司员工奖惩制度
2015/08/04 职场文书
珍爱生命主题班会
2015/08/13 职场文书
先进个人主要事迹范文
2015/11/04 职场文书
优秀班干部主要事迹材料
2015/11/04 职场文书
GTX1660显卡搭配显示器推荐
2022/04/19 数码科技