長期休暇のときは要注意!pumaのメモリ管理をしよう ~計測こそ正義~

みんなのウェディングのインフラエンジニア横山です。

今回はpuma利用時のメモリ管理と、計測の大切さについてお話ししたいと思います。

何が起きたか

始まりは今年の1月1日、元旦でした。 インフラエンジニアの携帯に1通のアラートが届きました。それは、appサーバのAvailable Memory低下を表すものでした。 その当時のグラフを以下に貼ります。

原因がすぐにはわからなかったため、緊急対応としてappサーバの再起動を行ったところ、Available Memoryの値は回復しました。

原因究明

1月4日、新年初出社の初仕事はAvailable Memory低下の原因究明でした。 まず、ステージング環境のAvailable Memoryの値を確認すると、ステージング環境では起きていないことがわかりました。 そこで、アクセス数が関係しているのでは?と考えました。 また、コードフリーズ日である12月27日から減少し続けていることから、デプロイに伴う再起動が行われていないことも一因かな?と考えました。

しかし、これだけではなにが原因か確証を掴むことはできません。 そこで、いくつかのメトリクスについて計測し、原因究明の一助とすることにしました。

何を計測したのか

計測対象としたのは以下の三点です。

  • pumaプロセス1つあたりのスレッド数
  • pumaプロセス1つあたりの仮想メモリ使用量(vsz)
  • pumaプロセス1つあたりの物理メモリ使用量(rss)

弊社ではZabbixを利用しているので、ZabbixのUserParameterに以下の設定を行い、それぞれの値を計測しました。

UserParameter=puma.process.thread_count[*],ps auxm -L |sed -ne '/puma: cluster worker [$1]/p' | awk '{print $$5}'
UserParameter=puma.process.memory_usage.vsz[*],ps auxm -L |sed -ne '/puma: cluster worker [$1]/p' | awk '{print $$7}'
UserParameter=puma.process.memory_usage.rss[*],ps auxm -L |sed -ne '/puma: cluster worker [$1]/p' | awk '{print $$8}'

計測してわかったこと

計測を開始すると、これまで見えていなかったステージングと本番環境の違いがわかりました。

  • 本番環境のグラフ

  • ステージング環境のグラフ

二つのグラフを見比べると、本番環境では1プロセスあたりのスレッド数が激しく増減していることがわかります。 それに対してステージング環境では多少の増減はありますが、本番環境ほどではありません。

この結果をもとに、pumaのスレッド数のチューニングを行いました。 変更前はスレッド数が0~16で、アクセス数に応じて可変になっていましたが、計測した値を元に下限値を修正し、10~16に変更しました。

-threads 0, 16
+threads 10, 16

どうなったか

こちらが変更前から変更後にかけてのグラフです。スレッド数のチューニング前には、スレッド数の計測はしていないので、グラフは途中からとなります。

明らかにスレッド数の下限値を変更してからAvailable Memory、スレッド数の値が安定しています。 また、お正月後初の長期休暇であるGWでも無事にAvailable Memoryが低下せず乗り切ることができました。

まとめ

今回のトラブルを通して、あれこれ憶測をたてるより、計測することの大切さを再認識することができました。 この記事が同様の事象に悩んでいる方の助けになれば幸いです。