LoginSignup
89
74

More than 5 years have passed since last update.

celery

Last updated at Posted at 2016-04-05

celery とは

セロリ。python job queue 処理のフレームワーク。worker daemon を待機させて async 処理の仕組みを作ったり、beat daemon を起動して定時バッチ処理を組んだりする。ドキュメントはよく整備されている。

  • RDBよりも効率よく
  • backend は rabbitmq cluster や redis cluster を使う。RDB 使えるけど使わないのが best practice
  • job の流量制御は変更しやすいようにと考えられている
  • worker daemon 起動。一台に複数起動してもよし。クラスター分散させて起動してもよし。
  • job 依頼側と受け手側の両方が python で共通ライブラリ使うとかだと、どんぴしゃ

処理フロー的には AWS lambda や IBM bluemix OpenWhisk みたいな処理部分に、タスクスケジューラがついたものと考えても近い。API 定義とか気にせず処理分割を進められるのはありがたい。

worker

async job を使いたい場合は、worker daemon を起動させる。

celery -A proj worker でデーモン起動させるのだけど、proj の指定方法がわかりにくい!

ざっくりルールはこんな感じ。

  • カレントディレクトリと module 検索パスを検査対象として、Celery instance を探す
  • proj の文字列中に : があると modname:varname が Celery instance に違いない
  • proj.app がモジュールでなければ Celery instance に違いない(おいおい)
  • proj.celery がモジュールでなければ Celery instance に違いない(うーむ)
  • proj.celery がモジュールなら
    • proj.celery.app がモジュールでなければ Celery instance に違いない(おいおい)
    • proj.celery.celery がモジュールでなければ Celery instance に違いない(うーむ)
    • proj.celery 内の変数に Celery のサブクラスインスタンスが無いか調べる
  • proj 内の変数に Celery のサブクラスインスタンスが無いか調べる

つまり例示すると…

  • カレントディレクトリにある somename.py ファイルに Celery instance の変数 x が存在する場合
    • celery -A somename:x worker で起動する。あるいは
    • celery -A somename worker でも起動できる。
  • カレントディレクトリから見て somename/__init__.py ファイルに Celery instance の変数 x が存在すれば
    • celery -A somename worker:x で起動する。あるいは
    • celery -A somename worker でも起動できる。
  • カレントディレクトリから見て somename/__init__.py が存在し、 somename/celery.py ファイルに Celery instance の変数 x が存在すれば
    • celery -A somename.celery:x worker で起動する。あるいは
    • celery -A somename.celery worker で起動する。あるいは
    • celery -A somename worker で起動する。
    • from __future__ import absolute_import を使うべし(python 2)
  • カレントディレクトリから見て somename/__init__.py が存在し、 somename/subname.py ファイルに Celery instance の変数 x が存在すれば
    • celery -A somename.subname:x worker で起動する。あるいは
    • celery -A somename.subname worker で起動する。
  • モジュール検索パスの somename のモジュールに app 変数が存在すれば、それを Celery instance だと思い込む。
    • celery -A somename:app worker で起動する。
    • celery -A somename worker で起動する。
  • モジュール検索パスの somename のモジュールに Celery instance の変数 x が存在すれば
    • celery -A somename:x worker で起動する。
    • celery -A somename worker で起動する。
  • モジュール検索パスの somename.celery がロードできて、その中に Celery instance の変数 x が存在すれば
    • celery -A somename.celery:x worker で起動する
    • celery -A somename.celery worker で起動する。
    • celery -A somename worker で起動する。
    • from __future__ import absolute_import を使うべし(python 2)

注意深く見ていると、パターンによって app の表示が少し変わる。

celery -A somename worker
...
- ** ---------- [config]
- ** ---------- .> app:         __main__:0x106a950
celery -A somename worker
...
- ** ---------- [config]
- ** ---------- .> app:         somename:0x1585410

ややこしい元凶は proj.appproj.celery という特殊ルール。

極端にややこしいケースは Flask のドキュメント で説明がないところ。Flask は一般的には Flask instance な app 変数を作る。ところが celery も app 変数が見つかればCelery instance に違いないと思い込むので、食い違いが起こる。

回避策は例えばこのようになる:

  • Flask instance の変数名を app 以外にする
  • : 付きの文字列で指定する celery -A your_application:celery worker

beat

定時 batch を組みたいときは beat な daemon を起動させる。

celery -A somename beat

worker daemon とは別に起動させる。こちらは基本的にはスケールアウトしないので、注意して使わないといけない。

スケジュールの設定もプログラムには埋め込めず、基本設定ファイルに列挙することになるのも注意。

ところで

job queue とセロリの関係がよくわからない…そういうイメージなの…?

追記 : 今なら kafka + faust という選択肢もありますぞ。

89
74
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
89
74