note の Ruby バージョンを 3.2.2 へアップグレードしました

この記事は note株式会社 Advent Calendar 2023 の13日目の記事です。

note ではサービス開始当初から Ruby on Rails(以下、Rails)を採用しています。

この半年間で、Rails バージョンを 6.1.7 から 7.0.8 へ、Ruby バージョンを 2.7.8 から 3.2.2(現時点での最新安定版) へアップグレードしました。
昨年は Railsのアップグレード記事 を書いたので、今年は Ruby のアップグレードに焦点を当てて述べます。

はじめに

Ruby 2.7 は、2.7.8 のリリースを以て End of Life(EOL)が宣言されています。

EOL を迎えたバージョンは脆弱性が見つかっても修正されないため、運用中のサービスにセキュリティリスクが生じます。このため、アップグレードを行わないという選択肢は実質的にないです。効率的にアップグレードを進めるためには、依存ライブラリのメンテナンスや非推奨(deprecated)コードの修正といった地道な作業を常に行うことが大事です。

Ruby Warning 対応

Ruby 3.0 では、後方互換性のない変更が含まれています。特にキーワード引数分離の対応には、広範囲に及ぶコード修正が必要でした。

環境変数に `RUBYOPT=-W:deprecated` を指定する、または Rails 起動時に `Warning[:deprecated] = true` をセットすることで、非推奨機能に関するWarning ログを出力することができます。
note では本番環境で Warning ログの出力を有効にし、検出したすべての Warning を対処しました。月に一度しか実行されないスケジュール処理もあるため、この監視・対応には数ヶ月を要しました。また日々新規コードが追加されていくため、RSpec 実行時に Warning を検出したらテストを失敗させるという対策も実施しました。

トラブルシューティング: Ruby 3.1 で IPAddr#include? 処理のパフォーマンスが低下

Ruby 3.0.6 から Ruby 3.1.4 へのアップグレード時に、全体の平均レスポンスタイムが顕著に悪化しました。アップグレード前後のプロファイリングを比較すると ipaddr gem の IPAddr#include? の処理に多くの時間がかかるようになっていることがわかりました。ipaddr は default gemであり、通常は以下のバージョンがインストールされます。

ipaddr の v1.2.2 〜 v1.2.3 間の差分を確認すると、IPAddr#include? メソッドに差分が入っていることがわかりました。これがパフォーマンス低下に繋がったと思われます。
https://github.com/ruby/ipaddr/compare/v1.2.2...v1.2.3

note ではこのメソッドを共通処理部分で使用していたため、全体のレスポンスタイム悪化を引き起こしていました。ひとまず ipaddr を v1.2.2 へダウングレードすることで問題は解消しましたが、そもそも共通処理部分でこのような処理を行わないようにするなど、根本的な対処も行う予定です。

トラブルシューティング: Ruby 3.2.2 で Twemoji.parse 処理のパフォーマンスが低下

Ruby 3.1.4 から Ruby 3.2.2 へのアップグレード時に特定の API 処理でパフォーマンスが低下する問題が起こりました。
当該 API にはサイズの大きな HTML 文字列を twemoji gem の Twemoji.parse する処理がありました。プロファイリングを取ったところその Twemoji.parse 処理内の正規表現パターンマッチに多くの時間がかかるようになっていることがわかりました。
twemoji のバージョンはアップグレード前後で変更していなかったため(v3.1.8 を使用) Ruby 3.2 で入った正規表現関連の差分が影響した可能性があるのではないかと思います。
元々この処理はリアルタイム実行するにはパフォーマンスが良くなかったため、この機会に Twemoji.parse を使わないように改修することで問題を解消しました。

今後の取り組み

  • さらなるパフォーマンス向上のために Ruby YJIT コンパイラの有効化も年明け目処に進めています。

  • 長らく追いついていなかった Ruby バージョンが、これで最新版に追いつきました。この勢いで来たる Ruby 3.3 へのアップグレードも迅速に対応していきます。

この記事が気に入ったらサポートをしてみませんか?