Celery + AWS Redis で使ってみる
目的
Celeryなるツールを使ってみる。勉強目的。
この記事でやること
Celery + Redisを使ってみる。Djangoは使わない。とりあえずCeleryのマニュアルのFirst Stepsは理解したい。
First Steps with Celery — Celery 4.1.0 documentation
環境
AWS EC2 Oregon
ubuntu-xenial-16.04-amd64-server-20170619.1 (ami-835b4efa)
Celeryってなに?
・非同期処理が作れる
・スケジューリングもできる
・上記の機能を使用する際にpythonでスタンダードなツール
Message Brokerなるものが必要
タスクメッセージをCeleryに登録したり、そのタスクを取り出すBrokerなるツールが必要で、以下のツールをサポートしている。
Brokers — Celery 4.1.0 documentation
この記事ではRedisを使用してみる。Amazon SQSも気になるけど単体で使用するツールではなさそうなので、単体でも使用できそうなRedisを指定する。
Redisってなに?
以下のSlide Shareを見てもらうと手っ取り早い。RDBのデータをキャッシュする感じで使うのですかね。便利そうですね。
AWSにRedisでも立ててみる
料金について。無料利用枠があるとのことなのでcache.t2.microを使う。
AWS コンソールから作成してみる
クライアントのEC2と同じセキュリティーグループにいれて、inboudを許可したらコネクトできました。
ElastiCacheのredisをEC2で使う - Qiita
CeleryとRedisはどうやってつながるの?
Celery instanceが必要だというので立ててみる。
tasks.pyをつくる
from celery import Celery
app = Celery('tasks', broker='redis://ubuntu@your.primary.endpoint.cache.amazonaws.com')
@app.task
def add(x, y):
return x + y
Celeryデーモンの起動
celery -A tasks worker --loglevel=info
なんかサーバたった。
別のプロセスを立ち上げでタスクを投げてみる
>>> from tasks import add
>>> result = add.delay(4, 4)
<AsyncResult: bf6d2799-2461-4b42-8ee1-f5bddb867f05>
>>> result.get()
(省略)
NotImplementedError: No result backend is configured.
returnされたけど見えない。(ここでは見えなくて正解。backendの処理が必要)
結果を保持する
tasks.pyを更新する。赤字の設定を追加
backendに指定したストアに結果が保持される保持する。
from celery import Celery
app = Celery('tasks', broker='redis://ubuntu@your.primary.endpoint.cache.amazonaws.com', backend='redis://ubuntu@your.primary.endpoint.cache.amazonaws.com')
@app.task
def add(x, y):
return x + y
再実行
Ctrl + C (サーバ止める)
celery -A tasks worker --loglevel=info
結果
>>> from tasks import add
>>> result = add.delay(4, 4)
>>> result.get()
8
Redisのデータがどうなっているか気になるので見てみる
redis-cliを使用する
# redisに接続
redis-cli -h your.primary.endpoint.cache.amazonaws.com
# key検索
> keys *
"celery-task-meta-xxxxxxxx-xxxx-xxxx-xxxxxxxxx"
# 登録したタスクがいっぱい出てくる
# 登録したタスクの検索
get celery-task-meta-xxxxxxxx-xxxx-xxxx-xxxxxxxxx
# 格納されてた
"{\"status\": \"SUCCESS\", \"traceback\": null, \"result\": 8, \"task_id\": \"xxxxxxxx-xxxx-xxxx-xxxxxxxxx\", \"children\": []}"
使ってみて感想
簡単に非同期処理ができてとても便利。いろいろと使えそう。
参考
http://docs.celeryproject.org/en/latest/index.html
https://www.slideshare.net/yujiotani16/redis-76504393