【ITニュース解説】Our service got forty percent more expensive and nothing could say where
2026年09月25日に「Dev.to」が公開したITニュース「Our service got forty percent more expensive and nothing could say where」について初心者にもわかりやすく解説しています。
ITニュース概要
サービスでCPU使用量が40%急増し、既存の監視ツールでは原因不明だった。継続的プロファイラを導入した結果、正規表現のコンパイルが原因と判明、設定修正で解決。今後は常時プロファイリングで性能劣化を早期発見・防止する仕組みを構築した。
ITニュース解説
あるシステムが突然、性能劣化に見舞われた。注文処理サービスにおいて、システム全体の基盤となるプラットフォームの更新後、同じ量の処理を行うためにCPUの使用量が40%も増加したのだ。ユーザーからのリクエスト数は変わらないにもかかわらず、リクエストの95%が処理されるまでの応答速度(p95)は60ミリ秒悪化し、サービスを稼働させるコンピュータの台数(ノード数)も4台増加した。しかし、システムはエラーを発生させず、アラートも上がらなかった。原因特定と解決には3週間を要し、既存の監視ツールはほとんど役に立たなかった。
通常、システムの問題では、CPU使用率やメモリ使用量などの数値データ(メトリクス)、システムの活動記録(ログ)、そして一つの処理がシステム内でどのように流れたかを追跡する機能(トレース)が利用される。これらのツールは、サービスが重くなったという事実を明確に示していた。しかし、トレース機能を使ってコードの細部、例えばデータベースアクセスや外部システムとの通信まで追跡しても、特定の処理で極端に時間がかかっている箇所は見つからなかった。余分にかかっていた時間は、個々のリクエスト全体に薄く分散しており、これは外部との連携ではなく、アプリケーションの内部で何かが起こっていることを示唆していた。具体的には、データの形式変換(シリアライズ)、使われなくなったメモリの自動回収(ガベージコレクション)、データの同時アクセス制御(ロック)、あるいは文字列のパターン認識ルール(正規表現)のコンパイルなどが疑われた。
問題の複雑さを増していたのは、プラットフォームの更新により、サービスが利用する34個ものプログラム部品(依存関係)が一度に更新されていた点だった。どの変更が性能劣化を引き起こしたのかを特定するのは困難を極めた。
そこで開発チームは、「バイセクション」という地道な手法を試みた。これは、変更された依存関係を一つずつ古いバージョンに戻し、本番環境に近いテスト環境(カナリア環境)で1時間実際のトラフィックを流して、リクエストあたりのCPU使用量が改善するかどうかを比較する作業だ。問題が多くのリクエストが同時に処理される負荷でなければ現れなかったため、この作業は合計で5日間かかり、さらにチームが他の業務も兼務していたため実質2週間近くを要した。
あらゆる手段が尽きた後、開発チームは「継続的なプロファイラ」というツールを導入した。これは、プログラムが実行されている間、CPUがどの処理にどれくらい時間を使っているか、メモリをどのように利用しているかなどを常に記録し続けるツールである。このプロファイラは導入後わずか2時間足らずで、長期間悩まされてきた原因を特定した。
プロファイラの解析結果は、CPU時間の31%が正規表現のコンパイルに費やされていたことを明らかにした。原因は、利用していた入力検証ライブラリの新しいバージョンが、以前のバージョンとは異なり、一度コンパイルした正規表現のパターンをキャッシュしなくなっていたためだった。これにより、同じ正規表現パターンがリクエストごとに何度もコンパイルされ、CPUに大きな負担をかけていた。解決策は、設定クラスに正規表現のキャッシュを有効にするフラグを1行追加するだけだった。
この経験から、開発チームはシステムの監視とデバッグに対するアプローチを根本的に見直した。現在では、すべてのアプリケーション実行単位(Pod)からCPUとメモリの使用状況(CPUプロファイルとヒーププロファイル)を継続的に収集している。この収集にかかるシステム負荷は2%未満で、データは30日間保持され、リリースごとにラベル付けされる。これにより、異なるバージョン間の性能比較を客観的に行えるようになった。
さらに、メモリ不足(Out of Memory)が発生した際には、その時点でのメモリの詳細な状態を示す「ヒープダンプ」を、大量のデータを保管できるストレージ(オブジェクトストレージ)に自動的に書き出すようにした。これは、原因となったコンテナがすぐに消えてしまう前に、重要な情報を確実に記録するためである。
また、リリースごとにリクエストあたりのCPU使用時間と確保されたメモリのバイト数を表示するパネルが導入された。このパネルは、前のリリースと比較して性能が10%以上劣化している場合、そのリリースのデプロイを自動的にブロックするように設定されている。この仕組みにより、既に2つの性能劣化がリリース前に検出され、そのうち1つは開発チーム自身が引き起こしたものだったという。
この一連の出来事は、「システムが遅い」という「何が起きているか」を教えてくれる監視ツールと、「なぜ遅いのか」という「どのコードが原因か」を教えてくれるツールは別物であることを明確に示した。既存のダッシュボードを改善するだけでは不十分であり、システムの深部を探るためのプロファイラのような「別の計器」が不可欠であるという教訓がそこにはあった。