在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设置tmpfs来加速项目的教程
Apr 17 Python
Python中遍历字典过程中更改元素导致异常的解决方法
May 12 Python
python+pandas+时间、日期以及时间序列处理方法
Jul 10 Python
Python中的单行、多行、中文注释方法
Jul 19 Python
python中的subprocess.Popen()使用详解
Dec 25 Python
TensorFlow实现打印每一层的输出
Jan 21 Python
Django用数据库表反向生成models类知识点详解
Mar 25 Python
django 数据库返回queryset实现封装为字典
May 19 Python
实例讲解Python 迭代器与生成器
Jul 08 Python
python3跳出一个循环的实例操作
Aug 18 Python
python中reload重载实例用法
Dec 15 Python
python中出现invalid syntax报错的几种原因分析
Feb 12 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
windows下zendframework项目环境搭建(通过命令行配置)
2012/12/06 PHP
PHP获取当前页面完整URL的实现代码
2013/06/10 PHP
php更新修改excel中的内容实例代码
2014/02/26 PHP
php二分查找二种实现示例
2014/03/12 PHP
php实现在限定区域里自动调整字体大小的类实例
2015/04/02 PHP
jquery获取多个checkbox的值异步提交给php的方法
2015/06/24 PHP
PHP中key和current,next的联合运用实例分析
2016/03/29 PHP
Laravel框架在本地虚拟机快速安装的方法详解
2018/06/11 PHP
PHP基础之输出缓冲区基本概念、原理分析
2019/06/19 PHP
围观tangram js库
2010/12/28 Javascript
精通JavaScript的this关键字
2020/05/28 Javascript
AngularJS 路由详解和简单实例
2016/07/28 Javascript
ionic隐藏tabs的方法
2016/08/29 Javascript
解析微信JS-SDK配置授权,实现分享接口
2016/12/09 Javascript
jQuery实现动态给table赋值的方法示例
2017/07/04 jQuery
vue中如何实现pdf文件预览的方法
2018/07/12 Javascript
node.js微信小程序配置消息推送的实现
2019/02/13 Javascript
基于Vue2-Calendar改进的日历组件(含中文使用说明)
2019/04/14 Javascript
解决layer.open弹出框不能获取input框的值为空的问题
2019/09/10 Javascript
浅析vue-cli3配置webpack-bundle-analyzer插件【推荐】
2019/10/23 Javascript
vue实现前端分页完整代码
2020/06/17 Javascript
[02:15]2014DOTA2国际邀请赛 赛后退役选手回顾
2014/08/01 DOTA
教你用一行Python代码实现并行任务(附代码)
2018/02/02 Python
python实现监控某个服务 服务崩溃即发送邮件报告
2018/06/21 Python
python机器学习实现决策树
2019/11/11 Python
MoviePy常用剪辑类及Python视频剪辑自动化
2020/12/18 Python
Otticanet澳大利亚:最顶尖的世界名牌眼镜, 能得到打折季的价格
2018/08/23 全球购物
.NET初级开发工程师面试题
2014/04/18 面试题
自动化专业个人求职信范文
2013/11/29 职场文书
中秋晚会活动方案
2014/08/31 职场文书
2014年国庆节寄语
2014/09/19 职场文书
初中家长评语和期望
2014/12/26 职场文书
新教师个人工作总结
2015/02/06 职场文书
音乐研修感悟
2015/11/18 职场文书
Html5通过数据流方式播放视频的实现
2021/04/27 HTML / CSS
5道关于python基础 while循环练习题
2021/11/27 Python