問題
Rails は Connection Pooling を前提に作られている。
しかし、サービスの規模が大きくなるとデータベースへの接続数が多くなってしまい、メモリを無駄に消費してしまう。
解決方法
コネクションプールをやめ、リクエスト毎やワーカ毎等でデータベースへ接続を行う様にする。
Resque の場合
フォーク後に全てのコネクションをクリアしてしまう。
config/initializers/resque.rb
# Clear connection pooling
Resque.after_fork do
ActiveRecord::Base.clear_all_connections!
end
以下のコマンドでIP毎のプロセス数を見ておくといいかもしれない。
$ mysql YOUR_DATABASE -e 'SHOW PROCESSLIST;' | grep -v + | cut -f 3 | cut -d ':' -f 1 | sort | uniq -c
上記対応を入れないとワーカ数の 2〜3 倍程度の接続数になる。
対応後は、起動しているワーカ数とおおよそ同じコネクション数になる。
Web サーバの場合
下記の Gem を入れればサクッとできます。
disable_connection_pooling
https://bitbucket.org/winebarrel/disable_connection_pooling