0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RailsのジョブシステムとActiveJob・Redisの基礎知識

0
Posted at

背景

  • レポートを自動生成するジョブのコードリーディングをする機会があった
  • Active Job、Redis、Solid Queueなどの用語が出てきたが、それぞれの役割と関係性を正確に理解できていなかった
  • 「Active Jobとは何か」「Redisはなぜジョブの文脈で出てくるのか」「バックエンドの選び方」を整理する

ジョブ(バックグラウンドジョブ)とは

Webアプリの処理は大きく2種類に分けられる

  1. フォアグラウンド処理 — ユーザーのリクエストに即座に応答する処理(画面表示、フォーム送信など)
  2. バックグラウンド処理 — 時間がかかるため、裏側で非同期に実行したい処理

後者がバックグラウンドジョブだ。具体例を挙げると:

  • メール送信 — SMTPサーバーとの通信に数秒かかることがある
  • 外部API呼び出し — 相手側のレスポンス時間に依存する
  • レポート・PDF生成 — 大量データの集計・変換が必要
  • データの一括取り込み(CSV/APIインポート) — 件数次第で数分〜数時間

これらの処理はキュー(待ち行列)に入れられ、ワーカー(実行役のプロセス)が順番に取り出して処理していく

[ユーザーのリクエスト]
    ↓
[Railsアプリ] → ジョブをキューに投入 → レスポンスを即返す
                         ↓
               [ワーカープロセス] → ジョブを取り出して実行

ユーザーにはすぐレスポンスを返しつつ、重い処理は裏で動く。これがジョブの基本的な仕組みだ


Active Jobとは

Active JobはRails標準の「ジョブの書き方を統一するインターフェース」だ

重要なのは、Active Job自体がジョブを実行するわけではないということ。実際にジョブを管理・実行するのは裏側のバックエンド(Sidekiq、Solid Queueなど)で、Active Jobはその間に立つ共通規格・翻訳者のような存在

[ジョブのコード(Active Job)]
    ↓ 共通のAPI
[アダプター]
    ↓
[バックエンド(Sidekiq / Solid Queue / Good Job など)]

Active Jobでできること

メソッド 動作 用途
perform_later キューに入れて非同期実行 本番での通常利用
perform_now その場で即時実行 テスト・デバッグ
set(wait: 1.hour).perform_later 指定時間後に実行 リマインダー等
set(wait_until: Date.tomorrow.noon).perform_later 指定日時に実行 定期処理

さらに、以下の機能も備えている:

  • 失敗時の自動リトライretry_onで例外ごとにリトライ戦略を定義できる
  • バックエンドの自由な切り替えconfig/application.rbの設定1行でバックエンドを変更可能。ジョブのコード自体は変更不要

コード例

# app/jobs/send_weekly_report_job.rb
class SendWeeklyReportJob < ApplicationJob
  queue_as :default

  retry_on Net::OpenTimeout, wait: :polynomially_longer, attempts: 5

  def perform(user_id)
    user = User.find(user_id)
    ReportMailer.weekly(user).deliver_now
  end
end
# コントローラーなどからの呼び出し
SendWeeklyReportJob.perform_later(current_user.id)

ApplicationJobを継承してperformメソッドを定義するだけでジョブが作れる。呼び出し側はperform_laterでキューに投入するだけなので非常にシンプルだ


Redisとは

Redis(Remote Dictionary Server)は、データをメモリ(RAM)上に保存するインメモリデータベースだ

なぜ速いのか

通常のデータベース(PostgreSQL、MySQLなど)はデータをディスクに書き込むが、Redisはメモリ上で動作する。ディスクI/Oがボトルネックにならないため、読み書きが約100〜1000倍速い

データ構造

Redisはキーと値のペア(Key-Value)でデータを保存する。値には複数のデータ型が使える

用途の例
String キャッシュ、セッション
List ジョブキュー、タイムライン
Hash ユーザー情報のような構造化データ
Set タグ管理、ユニーク集合
Sorted Set ランキング、スコアボード
Stream イベントログ、リアルタイム処理

Railsでの主な用途

  • ジョブキュー(Sidekiqのバックエンド)
  • キャッシュストア(フラグメントキャッシュ等)
  • セッションストア
  • Action Cableのバックエンド(WebSocket通信)

注意点

  • メモリは有限かつ高価 → 大量データの永続保存には不向き
  • デフォルトでは揮発性(電源断でデータ消失の可能性あり)。RDB/AOFの設定でディスク永続化は可能
  • Redisサーバー自体の運用・監視コストが発生する

主要なジョブシステム(バックエンド)の比較

Active Jobの裏側で実際にジョブを管理・実行するバックエンドは複数ある。代表的な4つを比較する

バックエンド データ保存先 追加インフラ 速度 向いてるケース
Solid Queue DB(PostgreSQL/MySQL/SQLite) 不要 普通 小〜中規模、Rails 8デフォルト
Sidekiq Redis Redis必要 非常に速い 大量ジョブ、大規模サービス
Good Job PostgreSQL 不要(※PG必須) 良い PG環境でRedisを増やしたくない場合
Delayed Job DB 不要 遅め レガシーRailsアプリの保守

Solid Queue(Rails 8〜のデフォルト)

Rails 8からデフォルトのジョブバックエンドになった。ジョブ情報をRDB(既存のデータベース)に保存するため、Redisのような追加インフラが不要なのが最大の利点

PostgreSQL/MySQLではFOR UPDATE SKIP LOCKEDを活用した効率的なジョブ取得が行われる。SQLiteでも動作するが、本番環境ではPostgreSQLかMySQLの利用が推奨されている

定期実行の設定例:

# config/recurring.yml
send_weekly_reports:
  class: SendWeeklyReportJob
  schedule: "0 9 * * 1" # 毎週月曜 9:00

Sidekiq

Redisをバックエンドに使い、マルチスレッドでジョブを並行処理する。大量のジョブを高速にさばく必要がある大規模サービスで選ばれることが多い。ただしRedisサーバーの運用コストが加わる

どう選ぶか

  • とりあえず始めたい / 小〜中規模 → Solid Queue(Rails 8なら何も設定しなくてもこれ)
  • 大量のジョブを高速処理したい → Sidekiq
  • PostgreSQL環境でRedisを増やしたくない → Good Job
  • 既存のレガシーアプリを保守している → Delayed Job(新規採用は非推奨)

まとめ

概念 役割
バックグラウンドジョブ ユーザーを待たせない非同期処理の仕組み
Active Job ジョブの書き方を統一するRails標準インターフェース
Redis インメモリで超高速なデータストア(Sidekiqのバックエンドとして利用)
バックエンド(Solid Queue等) 実際にジョブを管理・実行するエンジン

Active Jobは「共通規格」、Redisは「高速データストア」で役割がまったく異なるが、Sidekiqを介してセットで語られることが多い。Active Jobの規格に沿ってジョブを書いておけば、将来バックエンドを変えたくなっても移行コストが低いがメリット

感想

  • 「Sidekiq = Redis」みたいに漠然と思っていたが、Active Job・バックエンド・データストアの3層構造が分かると全体像がスッキリした
  • Rails 8からSolid Queueがデフォルトになったのは、「小〜中規模ならRedis不要」という判断ができるようになった点で大きい変化だと思う

参考

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?