#0118（2025/05/03）Celery × Redis 入門

# Celery × Redis 入門

Python で **重い処理を非同期化** したいとき、最もポピュラーなのが **Celery + Redis** の組み合わせです。本記事では両者の役割から導入方法までをコンパクトにまとめます。

---

## Celery とは

> **Celery は Python 製の非同期タスクキュー / ジョブキュー実行エンジン**

* 関数（＝タスク）をバックグラウンドで実行できる
* 並列・分散ワーカーを水平スケール可能
* タスクのリトライ・タイムアウト・結果保存を面倒みてくれる
* `Celery Beat` で cron ライクな定期実行もサポート

## Celery の役割

| 目的            | 例                       | 効果                |
| ------------- | ----------------------- | ----------------- |
| **重い処理の非同期化** | 画像リサイズ / AI 推論 / PDF 生成 | Web/API が速く返る     |
| **並列・分散処理**   | 数万件 ETL やバッチ            | マシンリソースをフル活用      |
| **スケジューリング**  | 毎日 0 時の集計               | cron よりコードで管理しやすい |
| **ワークフロー表現**  | 依存タスクチェーン               | 失敗時の自動リトライも簡単     |

---

## Redis とは

> **Redis は超高速インメモリ Key‑Value ストア ＆ メッセージブローカー**

* ミリ秒オーダの read/write
* Pub/Sub, Streams, Sorted Set など多彩なデータ構造
* 永続化もオプションで可能 (AOF / RDB)

## Redis の役割

| 目的             | 例                         | 効果          |
| -------------- | ------------------------- | ----------- |
| **キャッシュ**      | DB クエリ・API レスポンス          | レイテンシ改善     |
| **セッションストア**   | Django/Flask/Express      | 複数台でセッション共有 |
| **Pub/Sub 通知** | チャット更新                    | リアルタイム機能が簡単 |
| **メッセージキュー**   | Celery/RQ/BullMQ の broker | 高速・シンプル     |
| **一時ロック**      | レート制限・分散ロック               | 競合回避        |

---

## Celery × Redis を採用すると実現できること

| カテゴリ                   | 具体ユースケース                                 | なぜ両方必要？                 |
| ---------------------- | ---------------------------------------- | ----------------------- |
| **非同期バックグラウンド処理**      | Web からタスク投入 → Redis キュー → Celery ワーカーで実行 | Celery が実行、Redis が高速キュー |
| **分散 ETL / ML パイプライン** | 画像 DL → 前処理 → 推論 → 保存                    | タスクチェーン＋キュー             |
| **定期ジョブ**              | 5 分ごとに監視・通知                              | Beat + Redis キュー        |
| **イベント駆動マイクロサービス**     | サービス A がタスク投入 → サービス B が処理               | 疎結合メッセージング              |

---

## 基本構成図 

```text
FastAPI / Django (App)
        |
        |  add.delay()
        v
Redis (Broker / Queue)
        |
        |  ├── Worker 1
        |  ├── Worker 2
        |  └── Worker n
        |
        |  (タスクを取り出して実行し、結果を Redis backend へ保存)
```

---

## サンプルコード & 使い方

### ① タスク定義 (`tasks.py`)

```python
from celery import Celery

app = Celery(
    "myapp",
    broker="redis://localhost:6379/0",  # キュー
    backend="redis://localhost:6379/1", # 結果保存
)

@app.task(bind=True, max_retries=3)
def add(self, x, y):
    try:
        return x + y
    except Exception as exc:
        raise self.retry(exc=exc, countdown=5)
```

### ② ワーカー起動

```bash
# 別ターミナルで
celery -A tasks worker --loglevel=info --concurrency=4
```

### ③ タスクを投げる (任意の Python 環境)

```python
from tasks import add

result = add.delay(10, 20)
print(result.get(timeout=10))  # -> 30
```

### ④ 定期ジョブを追加 (例: 毎日 0 時)

```python
from celery.schedules import crontab

app.conf.beat_schedule = {
    "daily-report": {
        "task": "tasks.generate_report",
        "schedule": crontab(minute=0, hour=0),
    },
}
```

---

## まとめ

* **Celery = タスク実行エンジン**
* **Redis = 超高速キュー／キャッシュ**
* 両者を組み合わせると「Python 製アプリで非同期・並列・定期ジョブ」が驚くほど手軽に。
* 小規模 API でも `pip install celery redis` と `redis-server` → `celery worker` だけで本格運用が可能。