🐙

Fly.io+SQLiteでSolid Queueを使う

2024/02/08に公開

Solid Queueとは

Solid Queueは、Rails 7.1から利用可能なActive Job向けのqueueバックエンドです。

次期RailsはRedis依存をDBに寄せる方向になっていて新たに開発された

https://fly.io/ruby-dispatch/the-plan-for-rails-8/

https://dev.37signals.com/introducing-solid-queue/

この記事の要点

  • Fly.ioとSQLiteでアプリケーションを構築すると使う時だけ起動して永続化もできる
  • Solid Queueを使うとRedisなしで非同期処理も書ける
  • 安い

インストール方法

以下を参照

https://github.com/basecamp/solid_queue

migrateするとsolid_queue_*系のテーブルが作成される

設定

SQLiteはFOR UPDATE SKIP LOCKED句をサポートしてないので明示的にオフにしておく

config/environments/production.rb
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を別途実行しなくてよくなる

config/puma.rb
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ユーザー向けのドキュメントは以下

https://fly.io/docs/rails/

rails newしてfly launchしたらそのまま動く(すごい)

そのままだとデプロイする度にDBが消えちゃうのでボリュームをアタッチする

fly.toml
+[[mounts]]
+  source = 'data'
+  destination = '/rails/storage'

注意点

SQLiteファイルが置いてあるボリュームは1つのVMから読み書きしているだけなので複数のインスタンスやリージョンで並列に読み書きするという使い方はできない

その用途はLiteFSを追加する

あとvmが自動停止するとqueueのプロセスたちも止まる

スケジューリングjobはこれでは厳しいが最小起動台数を設定できる

ただゼロスケールしなくなるのでコストは増える

またFOR UPDATE SKIP LOCKEDがない環境でシーケンシャルに書き込んでどの程度性能が出るのか不明

一応queueに専用DBを指定するオプションはあったが複数のSQLiteファイルを設定しても自動で書き込みを振り分けてくれるわけではなかった

Discussion