Celery Workerの監視:FlowerとPrometheusで「ブラックボックス」から完全な制御へ

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

数千ものタスクが跡形もなく「消えた」とき

週明けの月曜日、注文確認メールが届かないという苦情が顧客から数多く寄せられます。システムを確認すると、すべて”Success”(成功)と表示されています。しかし実際には、5,000通のメールが処理されずにキューのどこかで待機したままになっています。

数GBものログファイルを調べても、明らかなエラーは見つかりません。Celery workerは稼働していますが、なぜタスクが実行されないのでしょうか?キューはどこで詰まっているのか?無限ループに陥ってボトルネックになっているタスクはないか?ここで初めて気づくのです。Celeryを動かせるのは道のりの50%に過ぎず、残りの50%は何が起きているかを可視化することであると。

なぜCeleryは「ブラックボックス」になりがちなのか?

バックグラウンドタスク(background tasks)は、通常のRequest-Responseの流れから完全に切り離されて動作します。HTTPリクエストが失敗すればすぐに500エラーが返りますが、Celeryタスクが死んだ場合、多くは音もなく消え去るか、Broker(Redis/RabbitMQ)内でアラートも出さずに永遠に待機し続けます。

システムが「フリーズ」する最も一般的な3つの原因は以下の通りです:

  • Brokerの滞留: タスクの投入が早すぎ(例:1000タスク/秒)、Workerの処理が追いつかない(例:100タスク/秒)状態。
  • Workerのゾンビ化: プロセスは存在しているが、メモリリークなどのエラーにより新しいタスクを受け付けられなくなっている状態。
  • 重いタスクによるリソース占有: 20MBの画像処理タスクなどがCPUを使い果たし、軽いメール送信タスクがキューの最後に追いやられてしまう状態。

「ログを眺める」だけの監視はやめよう

多くの開発者が依然として手動でのデバッグを続けていますが、この方法はスケールさせるのが非常に困難です:

  1. tail -f を使う: ローカル開発では有効ですが、Docker上で20個のWorkerが動いているようなシステムで、各コンテナのログを監視するのは苦行です。
  2. Celery Inspect: celery -A proj inspect active コマンドは瞬時の数値は出せますが、履歴や傾向を把握する全体像に欠けます。
  3. Flower単体: UIは非常に優れていますが、Flowerを再起動すると履歴データが消えてしまいます。また、能動的なアラート(alerting)機能も不足しています。

黄金の組み合わせ:Flower + Prometheus + Grafana

度重なる深夜の障害対応を経て、私は最適解にたどり着きました。可視化管理のための Flower、時系列メトリクス保存のための Prometheus、そしてダッシュボード描画のための Grafana です。この構成により、タスクが10回以上リトライされたり、WorkerのRAMが80%を超えたりした際に即座に検知できるようになります。

ステップ1:FlowerでPrometheusメトリクスを有効にする

最新のFlowerには、Prometheus用のエンドポイントが標準で組み込まれています。まずは最新バージョンをインストールしてください:

pip install flower

通常の起動コマンドに --prometheus_enable フラグを追加して、FlowerがPrometheus形式のデータを出力するようにします:

celery -A your_project flower --address=0.0.0.0 --port=5555 --prometheus_enable

http://localhost:5555/metrics にアクセスして確認してください。celery_tasks_total のような行が表示されていれば、正しく設定されています。

ステップ2:Prometheusのデータ収集設定

Prometheusが15秒ごとにFlowerからデータを取得するように設定します。prometheus.yml ファイルを開き、以下の内容を追加してください:

scrape_configs:
  - job_name: 'celery-monitor'
    static_configs:
      - targets: ['192.168.1.10:5555'] # Flowerが動作しているサーバーのIP
    scrape_interval: 15s

ステップ3:Grafanaによる可視化

Prometheusの生データは読み取りにくいため、Grafanaを使ってグラフを作成しましょう。注目すべき3つの「黄金」メトリクスは以下の通りです:

  • celery_tasks_total (status=”failure”): このグラフが急上昇している場合、システムで深刻なエラーが発生しています。
  • celery_queues_length: この数値は常に0に近い必要があります。時間とともに上昇している場合は、すぐにWorkerを増設する必要があります。
  • celery_workers_online: 期待されるWorker数が稼働しているかを確認します(例:常に4つのWorkerがアクティブであること)。

Tips:Grafana LabsのダッシュボードID 14195 を使用すると、Celery用の標準的なインターフェースを素早くインポートできます。

実運用における「血の滲むような」教訓

1日100万件以上のタスクを処理するシステムを運用する中で得られた、3つの重要な注意点を紹介します:

1. Flowerのメモリ制限: Flowerはタスクの履歴をRAMに保存します。制限を設けないとサーバーがクラッシュする原因になります。--max_tasks=10000 フラグを使用して、Flowerを軽量な状態に保ちましょう。

2. セキュリティを最優先に: Flowerのダッシュボードをパスワードなしでインターネットに公開してはいけません。Basic認証を使用して、未承認のアクセスをブロックしてください:

celery -A proj flower --basic_auth=admin:mypassword123

3. 能動的なアラート設定: ダッシュボードを眺めるのを待ってはいけません。celery_queues_length > 500 が5分間続いた場合に、すぐにTelegramメッセージを送信するようAlertmanagerを設定しましょう。これにより、顧客が気づく前にボトルネックを解消できます。

結論

監視とは単にツールをインストールすることではなく、データフローの「健康状態」を深く理解することです。FlowerとPrometheusを活用すれば、タスクが「行方不明」になる心配はもうありません。設定には30分ほどしかかかりませんが、それによって何時間ものデバッグ時間を節約し、本番環境におけるアプリケーションの信頼性を守ることができるのです。

Share: