📋

Solid Queue(Rails)

Redisなし DBだけで — Rails 8デフォルトバックグラウンドジョブシステム

GitHub: rails/solid_queue

Solid Queueは37signalsが作ったDB基盤のActiveJobバックエンドで、Rails 8からデフォルト含まれます。「本当にRedisが必要か?」という問いから始まったプロジェクトです。

詳細なアーキテクチャ分析については韓国語版を参照してください。statusカラムの代わりに別テーブルで状態を管理するコアアイデア、10テーブルのDBスキーマ、ジョブライフサイクル(enqueue → dispatch → claim & execute)、3つのプロセスタイプ(Worker/Dispatcher/Scheduler)、非ブロッキングポーリングのためのFOR UPDATE SKIP LOCKED、enqueue_after_transaction_commit?によるトランザクション安全性が含まれます。

構造ダイアグラム

ジョブ状態別テーブル分離 (ERD)

📋 solid_queue_jobs GitHub ↗
queue_name, class_name, arguments, priority, scheduled_at, finished_at
ON DELETE CASCADE
ready_executions
実行待ち
scheduled_executions
予約待ち
🔄
claimed_executions
処理中
failed_executions
失敗
🔒
blocked_executions
同時性待ち
🔑
semaphores
同時性制御
ポイント: <strong>statusカラム</strong>の代わりに<strong>状態別テーブル分離</strong>
各テーブルに最適化されたインデックス = 高速ポーリング

ジョブライフサイクル

MyJob.perform_later(args) Job.rb ↗
solid_queue_jobs INSERT + after_create :prepare_for_execution
即時実行?
予約?
同時性制限?
ready_executions
scheduled_executions
blocked_executions
Dispatcher がscheduled → readyに移動 dispatcher.rb ↗
Worker: claim (FOR UPDATE SKIP LOCKED)
ready → claimed (トランザクション)
worker.rb ↗
ActiveJob::Base.execute(arguments)
成功
finished_at更新
失敗
failed_executions

3つのプロセスタイプ

⚙️
Worker
ready_executionsポーリング
claim (SKIP LOCKED)
スレッドプールで実行
worker.rb ↗
📡
Dispatcher
scheduled_executionsポーリング
due済みジョブ → readyに移動
同時性メンテナンス
dispatcher.rb ↗
🔁
Scheduler
cronスケジュール確認
繰り返しジョブenqueue
重複実行防止
scheduler.rb ↗

キーポイント

1

GitHubでrails/solid_queueリポジトリを開く

2

db/migrate/ → 10テーブルスキーマを確認(状態別テーブル分離パターン)

3

lib/solid_queue/worker.rb → ポーリングループとclaimロジックを分析

4

lib/solid_queue/dispatcher.rb → 予約ジョブディスパッチロジックを分析

5

app/models/solid_queue/job.rb → enqueueフローを確認

6

app/models/solid_queue/ready_execution.rb → FOR UPDATE SKIP LOCKEDを確認

7

app/models/solid_queue/claimed_execution.rb → 実行/成功/失敗処理

8

lib/solid_queue/supervisor.rb → Fork vs Asyncプロセス管理

メリット

  • Redis不要 — DBだけで完全なジョブシステム
  • Rails 8デフォルト — 別途インストール不要ですぐ使用可能
  • ActiveJob互換 — 既存ジョブコード変更なしで切替可能
  • FOR UPDATE SKIP LOCKED — ワーカー間の非ブロッキング競合
  • 同時性制御内蔵 — セマフォ基盤concurrency limit
  • Pumaプラグイン — 開発時に別プロセス不要

デメリット

  • Redis基盤Sidekiqよりスループットが低い場合がある
  • DB負荷増加 — ジョブが多いとDBに書き込み負担
  • SQLiteでSKIP LOCKED未サポート(graceful fallback)
  • 大規模サービスでは依然としてSidekiq/Redisが有利
  • Web UIがSidekiqより成熟度が低い(Mission Control別途)

ユースケース

メール送信: UserMailer.welcome.deliver_later データ処理: CsvImportJob.perform_later(file) 定期作業: Schedulerで毎日深夜にレポート生成 同時性制御: 同じユーザーの決済ジョブを順次実行 Sidekiq → Solid Queueマイグレーション インストール型アプリでRedisなしでバックグラウンドジョブ処理