Fly.io+SQLiteでSolid Queueを使う
Solid Queueとは
Solid Queueは、Rails 7.1から利用可能なActive Job向けのqueueバックエンドです。
次期RailsはRedis依存をDBに寄せる方向になっていて新たに開発された
この記事の要点
- Fly.ioとSQLiteでアプリケーションを構築すると使う時だけ起動して永続化もできる
- Solid Queueを使うとRedisなしで非同期処理も書ける
- 安い
インストール方法
以下を参照
migrateするとsolid_queue_*
系のテーブルが作成される
設定
SQLiteはFOR UPDATE SKIP LOCKED
句をサポートしてないので明示的にオフにしておく
config.active_job.queue_adapter = :solid_queue
+ config.solid_queue.use_skip_locked = false
デバッグ方法
config/environments/development.rb
にも同じ設定を追加しないとローカルでは非同期に動かない
./bin/rake solid_queue:start
でSupervisor, Worker, Dispatcherといったプロセスが起動される
プロセス情報はsolid_queue_processes
テーブルに保持されている
SELECT * FROM "solid_queue_processes" ORDER BY "id" LIMIT 300 OFFSET 0;
Fly.ioへのデプロイ
Puma pluginが用意されているのでそれを使うとsolid_queue:start
を別途実行しなくてよくなる
if ENV["RAILS_ENV"] == "production"
require "concurrent-ruby"
worker_count = Integer(ENV.fetch("WEB_CONCURRENCY") { Concurrent.physical_processor_count })
workers worker_count if worker_count > 1
+ plugin :solid_queue
end
Railsユーザー向けのドキュメントは以下
rails new
してfly launch
したらそのまま動く(すごい)
そのままだとデプロイする度にDBが消えちゃうのでボリュームをアタッチする
+[[mounts]]
+ source = 'data'
+ destination = '/rails/storage'
注意点
SQLiteファイルが置いてあるボリュームは1つのVMから読み書きしているだけなので複数のインスタンスやリージョンで並列に読み書きするという使い方はできない
その用途はLiteFSを追加する
あとvmが自動停止するとqueueのプロセスたちも止まる
スケジューリングjobはこれでは厳しいが最小起動台数を設定できる
ただゼロスケールしなくなるのでコストは増える
またFOR UPDATE SKIP LOCKED
がない環境でシーケンシャルに書き込んでどの程度性能が出るのか不明
一応queueに専用DBを指定するオプションはあったが複数のSQLiteファイルを設定しても自動で書き込みを振り分けてくれるわけではなかった
Discussion