こんにちは!
イタンジ株式会社でバックエンドエンジニアをしている藤崎 (https://x.com/aki19035vc) です。
イタンジの各種サービスの要である物件基盤システムを開発をしています。
私がメインで見ているRailsアプリケーションのRubyバージョンを3.3系にアップデートしましたので、その結果についてご紹介いたします。
前提
今回アップデートしたRailsアプリケーションの特徴は下記の通りです。
- Ruby 3.2.1
- Rails 7.0.6
- YJITは有効になっていない
- APIモードで動作しており、レスポンスはJSONしか返さない
- テストのラインカバレッジは100%
- 型の記載率は(ほぼ)100%
記載の通りテストのラインカバレッジを100%に維持しています。
また、型に関しても「appディレクトリ以下」は100%書かれています。
ハッシュの中身などは untyped
していますが、メソッドの引数や戻り値そのものを untyped
にしている箇所はありません。
メタプロしている場合はgeneratorを作ったり自前で頑張って書いたりしています。
そのため、既存のテストや型検査が通ればアプリケーションに重大な破綻が起きていない事に自信を持つ事ができます。
なお、デプロイ先はAWS ECS Fargate で、Railsアプリケーションが起動しているタスク定義は下記の通りです。
- タスクサイズ
- CPU: 1024 (1 vCPU)
- メモリ: 2048 (2 GB)
- ランタイムプラットフォーム
- オペレーティングシステムファミリ: LINUX
- CPUアーキテクチャ: ARM64
事前準備: Ruby 3.2でYJITを有効化
Ruby 3.3 の力を最大限引き出すために、まずRuby 3.2の状態でYJITを有効にするところから始めました。
なお、YJITについては調べれば多くの記事が出てくると思いますので、ここでは解説しません。
Ruby 3.2でYJITを有効にするにはいくつか方法がありますが、
- 環境変数
RUBY_OPT
で--yjit
を設定する - 環境変数
RUBY_YJIT_ENABLE=1
を設定する
今回は一番上のRUBY_OPT
を使用する方法でYJITを有効にすることにしました。
YJITを有効にするとメモリ使用量が増加することが予想されますが、RUBY_OPT
に --yjit-exec-mem-size=32
のように設定することでYJITを有効にしつつメモリ使用量も制御することができるためです。
結果
YJITを有効化して様子見をしていましたが、特に問題が発生することはありませんでした。
下記のグラフは、YJITを有効にした前後1週間の6時間ごとのレスポンスタイムです。 0.05秒程度は速くなっていそうです。
※ 1時間ごとで計測すると変化が見づらいので6時間ごとにしました。
想定の範囲内でしたが、メモリ使用率も増加していました。 こちらは1時間ごとのものになります。
本題: Ruby 3.3へアップデート
ようやくRuby 3.3のアップデートの話に入れます。
といっても、DockerfileやGemfileを変えたりするくらいです。RUBY_OPT
で指定している値も変更する必要はありません。
Ruby 3.3 からはRubyVM::YJIT.enable
を使用してアプリケーションの初期化時に動的にYJITを有効にすることもできますが、アップデートが無事終わった後に以下のPRを参考にイニシャライザで有効化しようと考えています。
結果
Ruby 3.3にアップデートして2週間ほど様子見をしていましたが、特に問題が発生することはありませんでした。
下記はアップデート前後1週間の、1時間ごとのレスポンスタイムです。
速くなっていますね!素晴らしいです!!
更にECSタスクの起動台数も減りました!
CPU使用率が一定の割合になるようにオートスケーリングが設定されているのですが、1日の平均起動台数が下記のように変化しました。
※ 1時間ごとにすると分かりづらいため、1日の平均起動台数にしています。
まとめ
本記事では、YJITが有効になっていないRuby 3.2のRailsアプリケーションをRuby 3.3にアップデートした結果についてご紹介いたしました。
Ruby 3.3にアップデートしYJITを有効にするだけで、パフォーマンスが改善するだけなく、ECSタスクの起動台数が減ってコストまで下げることができました。
※ 今回の結果はあくまで弊社の事例であり、あらゆるケースで必ずしもパフォーマンスが改善するとは限りません。
最後に
Rubyのアップデート後にRails 7.1へのアップデートも行ったのですが、その際にいくつかハマりポイントがありました。
その時の話は別の記事として書いていますので、ぜひご一読いただけますと幸いです。