ニコニコ漫画をRuby3.2.0に更新してYJIT有効化するとパフォーマンス改善された話

はじめに

こんにちは。ニコニコ漫画の開発をしているyotaとtukiyoです。 この記事はペアブロギングによって執筆しています。 本記事ではニコニコ漫画で利用しているRubyのバージョンを3.2.0へ更新したこととYJITの有効化によるパフォーマンスの変化について紹介します。

ニコニコ漫画のインフラ構成についてにある通り、ニコニコ漫画は4つのプロダクトによって運用されています。 このうち本記事の対象となるのは、Rubyを利用している「新バックエンド」と「課金サブシステム」になります。

今回、Rubyのバージョンが3.2.0になったことでYJITが実験段階ではなくなりました。*1 ニコニコ漫画のバックエンドシステム内では複雑な処理も多く、恩恵に与ることを期待して更新を行いました。 結果として大きなパフォーマンスの向上が見られました。

更新に関する作業

まずは使用しているRubyのバージョンを3.2.0に更新します。 ニコニコ漫画の新バックエンドでは自動テストを充実させる方針で開発を進めており、ライブラリや言語のバージョン更新を積極的に取り入れることができています。

ニコニコ漫画ではサービスのインフラにECSを利用しているため、アプリケーションはコンテナ上で動作しています。 Ruby 3.2.0のコンテナイメージはYJITの組み込まれたRubyとなっているため*2*3、特別な作業は必要ありませんでした。 本番環境の環境変数に RUBY_YJIT_ENABLE=1 を設定しただけです。

更新前後のパフォーマンス比較

新バックエンドのパフォーマンス変化

以下のグラフは新バックエンドにおける平均レスポンスタイムについての1週間前との比較グラフです。 実線がYJIT有効化後で、破線がYJIT有効化前の平均レスポンスタイムの推移を表しています。

ピークタイム前後における新バックエンドへの平均レスポンスタイムの1週間前との比較グラフ
ピークタイム前後における新バックエンドへの平均レスポンスタイムの1週間前との比較グラフ

全体的に2~3割のレスポンスタイムの削減がなされていることがわかります。 11時頃に見られる急激なレスポンスタイムの伸びは、ピークタイムの突入負荷*4*5によるもので、これは定常的に発生しています。 特にピークタイム突入時のパフォーマンス改善は大きく、6割程度のレスポンスタイムの削減ができています。

ちなみに当日のリクエスト数の推移は以下のグラフで示されているように、1週間前と比べてYJIT有効化後のほうがむしろリクエスト数が多いことが読み取れます。

ピークタイム前後における新バックエンドへのリクエスト数の1週間前との比較グラフ
ピークタイム前後における新バックエンドへのリクエスト数の1週間前との比較グラフ

これまで突入負荷への対応として午前10:30頃からECSタスク数をスケールさせ、暖気運転を行う運用で乗り切っていました。 想定以上の突入負荷に怯えながら運用をしていましたが、この更新によって心の余裕が生まれそうです。

ピークタイムの戦いについてはこちらもぜひご覧ください。 developers.bookwalker.jp

課金サブシステムのパフォーマンス変化

次に、課金サブシステムのパフォーマンス変化を見ていきます。

以下のグラフは、課金サブシステムにおける平均レスポンスタイムについての1週間前との比較グラフです。 こちらのグラフも実線がYJIT有効化後で、破線がYJIT有効化前の平均レスポンスタイムの推移を表しています。

ピークタイム前後における課金サブシステムへのリクエスト数の1週間前との比較グラフ
ピークタイム前後における課金サブシステムへのリクエスト数の1週間前との比較グラフ

こちらは、1割程度レスポンスタイムが削減されていることが見て取れます。 新バックエンドと比べると改善の効果が薄いですが、これは課金サブシステムがシンプルなアプリケーションであるためだと考えられます。

新バックエンドほどではないですが、以下のグラフのようにピークタイムには急激にリクエスト数が増える傾向にあります。 それにもかかわらずレスポンスタイムは削減されているため、更新による恩恵に与ることができています。

ピークタイム前後における課金サブシステムへのリクエスト数の1週間前との比較グラフ
ピークタイム前後における課金サブシステムへのリクエスト数の1週間前との比較グラフ

CPU使用率/メモリ使用率/ECSタスク数

以下のグラフは新バックエンドにおけるCPU使用率/メモリ使用率/ECSタスク数についてのグラフです。 1枚目がYJIT有効化前で、2枚目がYJIT有効化後となっています。

YJIT有効化前の新バックエンドのCPU使用率/メモリ使用率/ECSタスク数
YJIT有効化前の新バックエンドのCPU使用率/メモリ使用率/ECSタスク数

YJIT有効化後の新バックエンドのCPU使用率/メモリ使用率/ECSタスク数

YJIT有効化によって、より少ないECSタスク数で動作していることがわかります。 なお、赤線が跳ねている部分は本番リリースをおこなったタイミングのため、ECSタスク数が2倍になっています。

まとめ

本記事では、ニコニコ漫画のRubyを3.2.0へ更新したこととYJITの有効化によって起こったパフォーマンス変化について紹介しました。 大きな作業もなくこれだけのパフォーマンス改善の効果を得ることができ、開発者の方々の凄さを実感しまくっています。

最後に

ブックウォーカーでは、最新のRubyを使ったWebサービスの開発に関心がある仲間を募集しています。 興味がありましたらぜひ、ブックウォーカーの採用情報ページからご応募ください。

*1:https://www.ruby-lang.org/ja/news/2022/12/25/ruby-3-2-0-released/

*2:https://github.com/ruby/ruby-docker-images/pull/40

*3:https://github.com/docker-library/official-images/pull/13886

*4:プッシュ通知の送信などに伴う急激なアクセスの増加に対する社内用語

*5:サービスの特性上、午前11:00に公開される漫画エピソードが多数を占めているため