この記事は ex-crowdworks Advent Calendar 2024の21日目の記事です。
はじめに
今年、株式会社クラウドワークスを退職した@nisyuuです。今年行ってよかった温泉地は伊香保温泉です。
エンジニアとしてクラウドワークステック(旧クラウドテック)というフリーランスと企業をマッチングするエージェントサービスを開発していました。
テックではHerokuサーバーを使っていたのですが、ある日、ステージング環境でパフォーマンスが悪化してタイムアウトエラーが頻発するという問題に直面しました。
ステージング環境を使えない状態が続くと、リリース前の重要な機能を本番環境に近い環境で確認することができなくなります。リリース前にステークホルダーの確認が必要になる場合もあるため、今後の開発に影響が出ることは間違いありませんでした。
インフラエンジニア不在の中、下っ端エンジニアの私が早急に対処する必要がありましたが、この時遭遇した問題はサーバーのパフォーマンスチューニングをすることで解決することができました。
本記事では、実際に取り組んだチューニング方法を紹介します。
実施したチューニング
問題の解決を図るため、以下のような多角的なアプローチを採用しました。これにより、環境全体のパフォーマンスを向上させることができました。
WEB_CONCURRENCYのチューニング
WEB_CONCURRENCYは、Heroku上のアプリケーションで同時に実行できるプロセス数(ワーカー数)を設定する環境変数です。
これにより、複数のリクエストを並列処理する能力が決まります。
主にCPUリソースの効率的な利用を目的として調整されます。
今回は、設定されている値を下げることでワーカー数を減らし、CPUの使用を抑えることで負荷を軽減させました。
-
ワーカー数の設定について
- ワーカー数を調整することで、1度に処理可能なタスク数を増やすことができます
- ワーカー数を増やしすぎると、CPUの使用量が過剰に増加し、全体のパフォーマンスを低下させる可能性があります
- ワーカー数が少なすぎると処理が滞り、リクエストの応答時間が増加する原因となります
MALLOC_ARENA_MAXの調整
MALLOC_ARENA_MAXは、glibcが提供するメモリ管理機能の一部で、メモリプール(アリーナ)の最大数を指定する環境変数です。
この設定は、アプリケーションのメモリ割り当ての挙動に影響を与え、特に高負荷環境でメモリ使用量の制御に役立ちます。
問題発生時のステージング環境の割り当てメモリは少なかったため、MALLOC_ARENA_MAXの設定値を下げることでメモリを使い過ぎないように変更しました。
-
メモリプールの設定について
- MALLOC_ARENA_MAXの値を増やしすぎるとメモリ消費量が過剰に増加し、システムに負荷がかかる場合もあります
- 値を小さくしすぎると処理速度が低下する可能性もあるため、バランスの取れた設定が重要です
jemallocの導入
jemallocは、効率的なメモリアロケータとして知られており、標準的なmalloc
と比較してパフォーマンスの向上が期待できます。
主に大規模なアプリケーションや高負荷なシステムで使用され、メモリの断片化を減少させる特徴があります。
メモリの不足はログを見ても顕著に表れていたため、Rubyがコンパイル時に使用するメモリアロケータを標準のmalloc
からjemalloc
に変更しました。
-
メモリアロケータの最適化
-
jemalloc
は、メモリアロケーションの効率が高く、特に高負荷環境でその効果を発揮します - この変更により、メモリ使用量が削減され、全体的な応答性が向上しました
-
おわりに
上記の対策を実施した結果、メモリ使用量を100MB以上削減することができました。割り当てメモリが500MBで上限いっぱいまで使用していたため、5分の1を節約できたことになります。
これにより、ステージング環境での応答速度が改善され、安定してステージング環境での動作確認ができるようになりました。
インフラエンジニア不在のチームでは、インフラの重要な話が蔑ろにされがちです。
もしチームにインフラエンジニアがいないのであれば、意志を持ってチーム全員でインフラに関わってください。
何か問題を提起している人がいれば、傾聴力を持って積極的に聞き入ってください。
絶対200%達成でよろしくお願いします。