👓

【Puma入門】Rails標準サーバーの仕組みをスレッドとワーカーから理解、pumaってなんぞやと

に公開

はじめに

かなり、久しぶりの執筆になります、最近は本業の方が忙しく疲れてしまい、なかなか記事の執筆に手が回りませんでした。
エンジニア2年目を迎えようとしていますが、成長しているのか、どうか分からない不安も少し出てきたこの頃です、後輩も来ますので、一緒に切磋琢磨して成長したいと思います。


Railsを扱った事がある方なら、Railsアプリを開発・デプロイする中で、Pumaという名前を何度も目にしたことがあると思います。

PumaはRailsのデフォルトWebサーバーとして長年使われていますが、
「スレッド?ワーカー?なんとなく設定してるけどよく分からない…」という方も多いのではないでしょうか?
最近、業務でサーバー負荷テストの実装とパフォーマンスチューニングをする際に、pumaの設定について見直したので、pumaについて忘れないように執筆しようと思います。

この記事では、Pumaの基本構造から、スレッド・ワーカーの挙動、設定チューニングの実践方法までを図解と共に丁寧に解説していきます!

Pumaとは何か?

Pumaは、Rubyで記述された軽量・高速なWebサーバーです。

  • Railsでは、Rackアプリケーションとして動作します。
  • Rails 5以降、標準のアプリケーションサーバーとして採用されています(以前はWebrickやUnicornなど)。
  • puma以外にもapplication serverが存在します。

その他のアプリケーションサーバー

サーバー Puma Unicorn Passenger
特徴 スレッドベース プロセスベース 再起動不要
非同期処理に強い 安定だがリソース消費大 使いやすいが商用だと高機能は有料

Pumaのスレッドとワーカーを理解する

Pumaの特徴は、「マルチスレッド・マルチプロセス」のサポートにあります。

🔸 スレッド(threads)
1つのプロセス内で複数のリクエストを同時に処理できます。

非同期的にI/O(DBアクセスなど)を待つことで、スレッドが無駄にブロックされるのを防ぎます。

config/puma.rb
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } # ここの数字でスレッド数を変更
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

workers ENV.fetch("WEB_CONCURRENCY") { 2 } # ここの数字を変更でワーカー数を変更

preload_app!

port        ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
  • threads:スレッドプールのサイズ
  • workers:ワーカープロセス数(HerokuやマルチコアCPUで有効)
  • preload_app!:起動時にアプリを読み込んで、fork後のワーカーでメモリ使用を抑制

スレッド(threads)

1つのプロセス内で複数のリクエストを同時に処理できます。

  • 非同期的にI/O(DBアクセスなど)を待つことで、スレッドが無駄にブロックされるのを防ぎます。
  threads 4, 16
  • 最小 4、最大 16 のスレッドを使う設定。
  • リクエストの急増にも耐えつつ、アイドル状態のときはメモリ消費を抑えられる。

ワーカー(workers)

マルチプロセスを実現するための設定。

  • 各ワーカーは独立したRailsアプリケーションのコピーとして動作。
  • プロセスが分かれているため、メモリを共有しない。
  workers 2
  • 2プロセスを起動し、それぞれが独自のスレッドプールを持つ。
           Puma Master
               │
        ┌──────┴──────┐
        │             │
  Worker 1        Worker 2       ← 各プロセス
  │ │ │ │         │ │ │ │       ← スレッド(リクエスト並列処理)

チューニングの考え方

スレッド数を決める基準

  • アプリがI/O待ちの多い処理(DBアクセスや外部API呼び出しなど)を多用していれば、スレッド数を多めにするのが有効
  • CPUバウンドな処理(画像処理など)が多い場合はスレッドよりワーカーで分散した方が良い

workersとthreadsの使い分け

状況 設定の考え方
メモリ少ないサーバー スレッド多め、ワーカー少なめ
CPUコアが多い ワーカー多め、スレッド控えめ
HerokuやEC2など制限ある環境 WEB_CONCURRENCYとRAILS_MAX_THREADSを適切に設定

まとめ

Pumaはマルチスレッド×マルチプロセスの柔軟なスケーラビリティを持つWebサーバー

適切なthreads・workers設定はアプリの特性と環境によって変わる

設定を見直すだけで、大幅なパフォーマンス改善も可能である
皆さんもぜひ試してみて下さい。

Discussion