昨年末12月25日にRubyの最新バージョン3.4がリリースされました。従業員体験プラットフォームTUNAG(ツナグ)を開発・運用している私たちのチームでは、この最新バージョンにいち早く追従。複数のRuby on Railsアプリケーションのバージョンを、すべて3.4.1にアップデートしました(2025年1月10日現在)。アップデート後1週間ほど問題なく運用できていますので、速報として記事化します。
移行前はRuby 3.3.6+YJIT、移行後はRuby 3.4.1+YJITとなります。
$ ruby -V ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +YJIT +PRISM [x86_64-linux]
過去のTUNAGにおいてRuby/Railsのアップデート実績については以下の記事もご覧ください。
YJIT 3.4
今回はYJIT 3.3からYJIT 3.4への移行最終局面でMaxime Chevalier-Boisvertさんによる記事 https://railsatscale.com/2025-01-10-yjit-3-4-even-faster-and-more-memory-efficient/ が公開されたので、最終チェックとして、この情報を活用しました。 特に今回のアプリケーションでRubyの影響を受けるのはActiveRecordの箇所だと捉えると、その高速化は+2.6%と推測していました。
--yjit-mem-sizeの調整
Ruby 3.1から提供されてきた --yjit-exec-mem-size オプションに加え、YJIT 3.4では --yjit-mem-size オプションが2024年10月に新たに導入されています(https://github.com/ruby/ruby/pull/11810)。--yjit-exec-mem-size
オプションはこれまでRuby 3.3においてもデフォルト48 MiBのままで運用していたため、--yjit-mem-size=128
(in MiB) で運用を開始し目立った問題は発生していません。
全体のメモリ消費量
メモリ使用量については過去のRuby 3.1-3.3周辺のアップデートの中でやや苦労した Ruby/YJITエコシステム的にもメモリの問題はある程度落ち着いてきており、チーム組織内でも特に新たな発見はなく、スムーズにリリースに至りました。
実際のパフォーマンス差
実際に移行前後でのRailsアプリ (puma サーバで実行)のレイテンシー差異は軽微で、有意な差がある高速化は全体平均値や主要な個別箇所では確認できませんでした。今回はcanaryリリースをしない選択をしており、production環境において同一ソースコードの実行結果の差を取得していません。
native gem
システム内部通信にgRPCを使っていることもあり、native gemに依存している状況です。Rubyマイナーバージョンアップ時はnative gemの最新マイナーバージョンへの追従が例年遅れる傾向にあります。
Ruby 3.3リリース直後と同様に、Ruby 3.4リリース直後もこれらのgemではネイティブビルドが利用できなくなりました。DevExはやや低下しますが、最新技術の活用を優先しています。この制約は約1ヶ月程度で解消される見込みで、通常は毎年2月ごろに改善されています。
native gemはfat gemと呼ばれることもあり、廃止したいという意見もあるようです。が、RubyGemsのキャッシュの兼ね合いからnative build gemは開発・運用業務をする上ではまだ必須かなという認識です。
特に grpc gem はローメモリでのビルドが難しくCI環境などでメモリ不足が起因でビルドに失敗するケースに遭遇しています。こちらの問題はRuby 3.4対応のgrpc native gem (grpc 1.70.0予定) で解消される見込みです。
Stacktraceにクラス名が含まれることでSentryでFingerprintが変わる
2024年2月に、stacktraceにメソッド名のみが含まれていたものがクラス名+メソッド名が出力されるようになりました。
Ruby 3.3以前に「後回しにした」(*1)エラーが、再度新規エラーとして扱われるようになりました。幸い、該当するエラーは数件程度だったため、手動でグルーピングすることで問題なく対応することができました。
事前準備は大事
プレリリース版より検証することが重要です。今回のRuby 3.4シリーズのプレリリースのうちpreview2とrc1を利用して、2024年中より評価・検証を進めました。
- Ruby 3.4.0-rc1 2024-12-12
- Ruby 3.4.0-preview2 2024-10-07
オフラインで開催されるRuby/Rails勉強会も有用な情報として助かりました。特にFukuoka.rb / 株式会社Ruby開発共催の福岡 Rubyist会議 04への参加は内部構造を理解するのにとても参考になりました。
毎週のように都内ではRuby関連勉強会は実施されているので、タイミングが合えば今後も積極的に参加していこうと思います。また、年次カンファレンスRubyKaigiも最もRubyについて深い議論ができるため、参加したいと考えています。 今年もスタメンからRubyエンジニアを中心にプロダクトメンバー複数名で参加する予定です。
いつやるのかという意思決定
プロジェクト実施を意思決定する以前から利用していたRuby 3.3は、2027年3月にEOLを迎えることが確定していました。そのため、今回のバージョンアップはそれまでの約2年間で実施する必要がありました。組織・プロダクトの状況を考慮すると、最大2年間は後回しにすることも可能でしたが、2024年のコミュニティへのフィードバックという貢献を最大化するため、このタイミングでの実施に至りました(実際には12月末はホリデーシーズンでチームは稼働していなかったため、年明けからの開始となりました)。
投資開始タイミング
2025年第1週には最終プロセスに入り、すべて完了しています。しかし、productionレベルでの投資は2024年10月頃から緩やかに開始していました。例年以上に、特に今年の1月はチームに多くの新入社員が参画したこともあり、最初の週の実施はハードスケジュールでした。個人的には、2週目の実施でもよかったのではないかと感じています。
早期に実施することにリスクを感じる方もいるかと思いますが、私たちのチームではプロダクト内でのリスク回避策を講じることで、リスクを限定的に抑えられています。このあたりについては、読者の皆様が技術選定をどのように行っているのか、今後お伝えできればと思っていますし、他社の事例についても情報交換したいと考えています(執筆時点では、一定規模以上でRuby 3.4にアップデートしたという報告事例はあまり見つけられませんでした)。
我々もRuby 3.4力をつけて4月に愛媛で開催されるRubyKaigi 2025に参加し、各社でのRuby 3.4利用状況について議論できることを楽しみにしています。