パフォーマンス・チューニング Rails編

こんにちは。
Ruby on Railsでの開発を担当している中山です。

ウェブページの表示の早さは、快適なサービスを提供するためにとても大切です。
そこで今回は、マネーフォワードにおけるパフォーマンスチューニングの取り組みについてご紹介します。

なぜウェブページの表示に時間がかかるのか

Chromeのデベロッパーツールを使うと、ウェブページの表示に必要な各リソースのローディングにかかった時間を計測することができます。
マネーフォワードのログイン後のホームは以下のような結果になりました。

ChromeのDeveloper Tools

1行目がHTML、2行目以降がCSSやJavaScriptや画像などが並んでいます。青い縦線はメインコンテンツのローディングと解析が完了した時間を示しています。HTMLが約7割を占めています。その他のリソースの大部分は、Size/Content欄に(from cache)と書かれているとおり、ブラウザのキャッシュ機能のおかげでとても短時間で済むようになっています。HTMLのローディングをいかに短時間で済ませるかがポイントになることが分かります。

Ruby on Railsは、レスポンスヘッダーのX-Runtimeに、処理にかかった時間を出力するようになっています。先ほどHTMLのローディングにかかった844ミリ秒のうち、687ミリ秒がRuby on Railsでの処理時間であると分かります。

Response Header

マネーフォワードで表示される情報は、口座の残高や入出金の情報が中心なので、ユーザー毎に異なる情報であり、ユーザーの操作やアカウントアグリゲーションによって頻繁に変化します。そのため、ページ全体をキャッシュしたり、あらかじめ生成しておくことが難しいので、ブラウザからのリクエストがあるたびにデータベースからデータを取得し、Ruby on RailsでHTMLを動的に生成するページがほとんどです。また、セキュリティを優先するために、速度との両立が難しい部分もあります。いかにHTMLを速く生成するか、あるいはHTMLを生成しなくて済むようにするかのどちらかが、ウェブページの表示の高速化のカギとなります。

モニタリング

どのページがどのような状況で遅いか分かっていれば、前述のようなブラウザで計測すれば良いのですが、実際は多数のページがあって機能追加やユーザーの使い方等が日々変化していくので、全体的なモニタリングの仕組みが必要です。

マネーフォワードでは、ウェブサーバーのログファイルをFluentdで収集して、GrowthForecastでグラフにしています。一定時間(30分間隔など)におけるウェブアクセスのレスポンスタイムの内訳を色分けして表示されます。これを日々観察すると変化に気づくことができます。変化があったときに行われた新機能のリリースやユーザーの使い方の変化など、そのときに起こったことを考えて原因を探っていきます。

GrowthForecast

また、データベースのスロークエリなども定期的に調査しています。
 

原因調査

Ruby on Railsのログファイルは、MVCモデルのレイヤー別の処理時間が載っているので、処理時間の要因分解ができます。developmentモードでは、実行したSQL文とその処理時間も載っているので、眺めるだけでかなり多くのことが分かります。

本番サービスのようにログファイルの量が膨大な場合にはRequest-log-analyzerを使って集計します。アクション別にViewやデータベース操作の呼出回数、累積処理時間、平均処理時間などを集計してくれます。これらから、改善の余地が大きい箇所の見当をつけていきます。
 

パフォーマンス・チューニング

Ruby on Railsは、シンプルな記述で自動的に様々なことを行ってくれるので、高度なウェブアプリケーションを手軽に作ることができます。その半面、大きなデータを扱ったり複雑なページを作る際には、効率的な動作をさせるために少し工夫が要ります。
具体的には、次のような方法で高速化していきます。

  • キャッシュを使う。
  • データベース操作回数を減らす。1テーブル1回を目指す。
  • データベースから取得するレコードとカラムを最小限にする。
  • データベースのインデックスの張り方を工夫する。インデックスが使えるようなクエリにする。
  • マルチスレッドで処理する。
  • 高速なライブラリを導入する。
  • HTML作成(の一部)をJavaScriptに任せる。
  • Ajaxでレスポンスを返し、ページの一部分の更新のみで済ませる。

そのほか、RubyやRailsや様々なミドルウェアのバージョンを最新のものに変えたり、速いサーバーに乗り換えたり、サーバーの数を増やしたり、ネットワークを高速なものに変えるなど、インフラ面の対策も行っています。
(コード例などは別の機会に解説したいと思います)
 

ヌルヌルサクサク動くサービスを作るのが好きなRailsエンジニアの方へ

日々、ユーザーの増加と機能の高度化に伴って、パフォーマンス改善の余地がたくさん残っているのが現状です。
快適に動くサービスを一緒に創ってくれるRailsエンジニアを募集しています。
パフォーマンス・チューニングは、パズルを解くみたいで面白いですよ!

マネーフォワード採用サイト
https://recruit.moneyforward.com/

日本No.1お金のサービスを創り上げるRailsエンジニアWanted!
https://www.wantedly.com/projects/9979

Pocket