celeryを使う(CentOS)

概要

Celery(セロリ)は、非同期処理を行うタスクキュー/ジョブキューで、メッセージブローカーと呼ばれる、メッセージ送受信する仕組みと組み合わせて使用する。
メッセージブローカーは、RabbitMQ、Redis、Databaseなどから選択できるが、お勧めは、RabbitMQらしい。

Celeryの説明〜本家サイトより〜

Celery is an asynchronous task queue/job queue based on distributed message passing. It is focused on real-time operation, but supports scheduling as well.
The execution units, called tasks, are executed concurrently on a single or more worker servers using multiprocessing, Eventlet, or gevent. Tasks can execute asynchronously (in the background) or synchronously (wait until ready).

背景

非同期処理を仲介する、ありもののmodule/applicationとして、celeryの調査を行った。
pythonでは、multi thread処理ではGILの問題があるので、当初multiprocessing moduleを利用して複数process化(worker)+server化+queueを用意、などを考えていた。
結論としては、今回の用途にはceleryを使えば一発で済む。
また、設定も比較的容易にできた。
上記のような目的の場合であれば、celeryを使えば容易に済んだので、そういった方は利用を検討してみてもいいかもしれない。

以下の設定手順では、RabbitMQ+Celeryでの動作例を記載する。




以下の設定手順では、RabbitMQ+Celeryでの動作例を記載する。

設定手順

[[erlang*1]]とrabbitmq-serverのinstall

repositoryの設定

# wget http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/6/x86_64/epel-release-6-7.noarch.rpm
# rpm -ivh epel-release-6-7.noarch.rpm 

erlangのinstall

# yum install erlang

rabbitmq-serverのinstall

# wget http://www.rabbitmq.com/releases/rabbitmq-server/v2.8.4/rabbitmq-server-2.8.4-1.noarch.rpm
# rpm -ivh rabbitmq-server-2.8.4-1.noarch.rpm

serverの起動

# service rabbitmq-server start
celeryの設定

celeryのinstall

# yum install gcc
# yum install python-devel 
# easy_install celery

celeryのサンプルコードと起動

セロリアプリとして、tasks.pyを以下のように用意する。(以降、本家チュートリアルより)

from celery import Celery

celery = Celery('tasks', broker='amqp://guest@localhost//')

@celery.task
def add(x, y):
    return x + y

作成したtasks.pyを呼び出してceleryを起動する。
workerとしてプログラムを動作させる。

$ celery -A tasks worker --loglevel=info

celery_test.pyとして以下を作成する。
delay()メソッドを使うことで、celeryを使える。

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from tasks import add
add.delay(4, 4)

実行する。

$ ./celery_test.py

すると、celeryを起動したconsoleで、以下のように出力され、実行されたことがわかる。
log末尾に計算結果の"8"が見える。

[Tasks]
  . tasks.add

[2012-07-12 01:45:22,873: WARNING/MainProcess] celery@localhost.localdomain has started.
[2012-07-12 01:45:27,038: INFO/MainProcess] Got task from broker: tasks.add[d4ccee7e-2f4a-4f75-84fc-e91846bfe6f9]
[2012-07-12 01:45:27,052: INFO/MainProcess] Task tasks.add[d4ccee7e-2f4a-4f75-84fc-e91846bfe6f9] succeeded in 0.000603914260864s: 8

先の、tasks.pyにtime.sleep(3)等を入れると、celery_test.pyとtasks.pyが非同期に処理されることがわかる。(celery_test.pyはメッセージを投げてすぐ返る。tasks.pyはメッセージをceleryから受けて処理して返る。)

後日、djangoとの連携についても書きます。

*1:erlang(アーラン)とは、「コンピュータにおいて汎用的な用途に使うことができる並行処理指向のプログラミング言語および実行環境」とのこと。http://ow.ly/caBTG RabbitMQはerlangで実装されている。