LoginSignup
38
14

More than 3 years have passed since last update.

Nginx, Puma, Rails, MySQLのパラメータ設定/チューニング

Last updated at Posted at 2019-06-03

概要

Nginx, Puma, Rails, MySQLのチューニングを行ったときの知見を載せておきます。
ただし、チューニングは色々な要素に依存するため、最終的には自分たちの作っているアプリケーションにあった値を見つけてください。
以下の図のような動きを内部的にしています。では早速、各サービスの設定項目を詳しく見ていきましょう。
スクリーンショット 2019-06-02 23.00.06.png

Nginx

worker数

今回自分はNginxがボトルネックにはならなかったので、Nginxの知見はあまり習得していないですが、色々な人のブログを見ていると auto にしていることが多そうなので、特に理由がない場合以外は auto でいいかと思います。

/etc/nginx.conf
worker_processes auto;

Puma

worker数

workerはCPUのコア数に依存する物理スレッドを示しています。ここで大事なのは、worker数を サーバーのCPUコア数より大きくはしないことです
Pumaのworker数は、次のthread数に関係してくるので次で述べます。

thread数

threadは1worker内での論理スレッド数を示しています。

  • 1worker/16threadの場合、計16thread
  • 2worker/16threadの場合、計32thread

1worker内の最大thread数は、ここにも書いてあるように 16 より大きくしないほうが良さそうです。
※workerとthreadの関係はこちらに記載

実際に設定ファイルに書くときは、2worker/16threadの計32threadの場合は以下の通りに書いてください。

config/puma.rb
# 環境変数 RAILS_MAX_THREADS に 16 をセット
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }

...

# 環境変数 WEB_CONCURRENCY に 2 をセット
workers ENV.fetch("WEB_CONCURRENCY") { 2 }

実験を行った結果、もちろんサーバーのリソース(今回はCPUコア数: 2)にもよりますが以下のようにサーバーが処理できるキャパシティが変わりました。thread数が少ないともちろんさばける処理数が減るため、サーバーのリソースが余っているにもかかわらず、unhealthyになります。つまり、レスポンスで過負荷を示す503 errorが返却されます。

  • 1worker/5threadの場合、CPU15%ぐらいでunhealthyになる
  • 1worker/10threadの場合、CPU30%ぐらいでunhealthyになる
  • 1worker/16threadの場合、CPU45%ぐらいでunhealthyになる
  • 2worker/16threadの場合、CPU90%ぐらいでunhealthyになる

ここで気をつけないといけないのは、アプリケーションサーバーのCPU使用率だけに目がいくとメモリを圧迫してメモリが原因で処理ができなくなる場合もあるので、メモリもしっかり監視してください。また、データベースに負荷のかかる処理を行うような場合はデータベースのCPUやメモリにも注意してベストな組み合わせを見つけてください。
上記の実験条件下で、かつメモリに余裕がある場合は、2worker/16threadがベストだと考えることができます(リソースを無駄なく使いきるという意味です)。

Rails

pool数

database.yml内の pool は、MySQLとの接続数を示しています。
puma worker * puma thread > pool になってしまうとActiveRecord::ConnectionTimeoutError が発生してしまいます。なので、 poolpuma worker * puma thread == pool になるように設定しましょう。
その逆で、MySQLの最大コネクション数を超えるとMySQLの Too many connections エラーが出ます(式で表すと: pool > max_connections )。このコネクション数の最大は、 MySQLの設定に依存しますので、次で詳しく説明します。

MySQL

max_connections数

max_connections は、MySQLの最大コネクション数になります。DBインスタンスの性能によって最大値を変えるのがいいと思いますが、AWSのRDSは初期値が以下の通りに設定されています(インスタンスによって異なります)。

t2.micro : 66
t2.small : 150
t2.medium : 312

上記はRDSの推奨っぽいので、上限を上げることはできますが、あまりおすすめはしません。
最大コネクション数は、以下のSQLで確認可能です。

show variables like "%max_connections%";

まとめ

最初に貼りましたが最終的に以下のように内部的に動いていますので、先程紹介した設定値を参考にしてみてください。ただ、繰り返しにはなりますがサーバーのリソースやアプリケーションの処理する内容によってベストな設定値が変わります。なので、この数値にすればOK!というものがありません。これがチューニングの難しいところです。自社にあった設定値を地道に探していきましょう。その中で、この記事の内容がお役に立てれば幸いです。

スクリーンショット 2019-06-02 23.00.06.png
※上記画像のthread数を5にしているのは矢印線を16本引くのが大変だったので5にしているだけで推奨値とかではありません

38
14
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
38
14