25
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

django+Celeryによる非同期処理について

Last updated at Posted at 2018-12-13

はじめに

Gaiax Group Advent Calendar 2018の13日の記事です。ギリギリロスタイム以内なので13日目です。(すみません)

最近Djangoで開発したアプリケーションの中でジョブキューを使いたいシチュエーションがあったのでCeleryを用いて実現ししました。その際に学んだことについて備忘録的に記録しておきたいと思います。
django+Celeryの環境構築についてはいろんな記事があると思いますので、私が勘違いしたりなどして詰まった部分などを中心に共有します。

そもそもジョブキューとは

ジョブキューとは読んで字のごとく、何かしらの処理(ジョブ)をキューと呼ばれる先入れ先出しのリストに登録して順番に処理していくものです。主にウェブアプリケーションなどで、例えばクロールやcsv吐き出しなどの実行に時間がかかる重い処理がユーザからリクエストされた際などに利用します。
具体的には以下のようなイメージです。

HrpqQCaa5sYDvvHU-28CBF.png
参照:ヌーラボのサービスを支える動脈「 ジョブキュー 」の仕組みを紹介します!

このように、ユーザーからのリクエストに対するレスポンスをジョブキューにジョブが登録されたタイミングで返すことで、ユーザーに重い処理が実行されている間レスポンスを待たせず、裏で処理を走らせることができるようになります。

Celeryを使う際に出てくる用語

次にCeleryを扱う上で最低限理解しておくべき用語を整理します。

celery

celeryとはpythonのジョブキュー処理フレームワークです。workerと呼ばれるdeamonプロセスを待機させて非同期処理の仕組みを作ったり、beat deamonを起動してジョブの定時実行を行ったりできます。(定時実行についてはdjangoを利用する場合はdjango-celery-beatというライブラリを使うと制御が簡単になるのでオススメです。)

Broker

Brokerはジョブキューの根幹となるメッセージを受け取ってqueueに登録し、queueからworkerにジョブメッセージを渡す部分です。BrokerにはRabbitMQ、Redisなどが指定できます。

Result Backend

ResultBackendはタスクを追跡したり、または戻り値が必要な場合にタスクの実行結果を格納しておく部分です。

Consumer(worker)

キューからのメッセージを受け取って実際に処理を行うプロセスです。
以下のコマンドで立ち上げることができます。

$ celery -A [project_name] worker -l info

queue

クライアントから受け取ったジョブを登録しておくキューのことです。
workerを立ち上げる時に任意のqueue名を指定することで、workerとqueueを紐づけることができます。
何も指定せずにworkerを立ち上げた場合は、デフォルトで設定されている「celery」という名前のqueueに全てのジョブが登録されます。

$ celery -A [project_name] worker -l info -Q [queue_name]

また、concurrencyを指定することでそのqueueに登録されているジョブを幾つのworkerに処理させるかを指定できます。(デフォルトではお使いのPCで利用可能なCPU数が設定されています)

$ celery -A [project_name] worker -l info -Q [queue_name] --concurrency=10

ちなみに、この立ち上げたqueueに対してジョブを格納する際には、以下のようにジョブを定義する際にqueueを指定することで任意のqueueにジョブを登録することができます。

task.py
from __future__ import absolute_import, unicode_literals
from celery import shared_task

@shared_task(queue='queue_name')
def sample_task(self, name):
    print(f"hello {name}")

もしくは、ジョブを呼び出す際に以下のように指定することでも同様に任意のqueueにジョブを登録することができます。

sample_task.apply_async(args=["name"], queue='queue_name')

RabbitMQを利用している際のこれらの概念の関係性

最後に、Broker・ResultBackend・worker・queue・(concurrency)の関係性を図にまとめると以下のようになります。

celery_architecture_final.png

参照:Python Celery & RabbitMQ Tutorial

おわりに

今回はdjangoでのジョブキュー実装によく利用されているceleryについてまとめてみました。
最近勉強会などで登壇することは増えてきたのですが、qiitaなどへの記事投稿が滞っていたなあと思っていたので、これを機にちょっとずつ投稿していこうかな〜と思いました。

25
23
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
25
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?