読者です 読者をやめる 読者になる 読者になる

White Box技術部

WEB開発のあれこれ(と何か)

【Linux】メモリがカツカツなサーバのメモリを復活させる

メモリ枯渇の背景

仕事で、PHPのPhalcon FWで作ったAPIアプリケーションが乗ったphp-fpmサーバを運用しているのですが、 こやつで大量のリクエストをさばけるよう、負荷試験を行ってチューニングした結果、 現在php-fpmプロセスは、staticでリクエストを待つようになっています。

そのせいなのか、リクエストが少ないとプロセスのリフレッシュまで時間がかかり、 結果、APIサーバのメモリを食い潰すという事態にちょいちょいなります。

これは負荷試験で大量リクエストを投げているときは出てこない事象なので、完全に盲点でした。

問題発覚後は、設定値チューニングしたり、php-fpmをreloadしたりして適時対応してきたのですが、 本日ふと、サーバ上のメモリのほとんどが、reloadでも開放されていないことに気付きました。

・解放前
$ free -m
             total       used       free     shared    buffers     cached
Mem:          7871       7592        279          1        167        308
-/+ buffers/cache:       7116        755
Swap:         1023          0       1023

・reloadで解放
$ sudo service php-fpm reload
Reload service php-fpm  done

・解放後
$ free -m
             total       used       free     shared    buffers     cached
Mem:          7871       5080       2791          1        167        308
-/+ buffers/cache:       4603       3267
Swap:         1023          0       1023

そういえば、php-fpmのrestart/reloadは公式ドキュメントにGracefull restartと書かれていますが、 実際には期待する動作をしませんでした。この件の対応法についてはまた別途記事にしようと思います。

メモリ使用の詳細を確認する

以下のコマンドでメモリ情報を確認したところ、Slabという領域が4Gほど確保していることに気付きました。

$ view /proc/meminfo

Slabとは?

わからなかったので調べました。
以下のサイトにお世話になった結果、どうもKernelキャッシュの一種のようですね。

詳細はリンク先で☆

Slabキャッシュをクリアした話 – CLARA ONLINE techblog

Slabキャッシュの確認

slabtopコマンドで上位2つの消費が多いものを見たところ、 参考サイトと同様にdentryのキャッシュが肥大化しているようでしたので、 このキャッシュをクリアすることにしました。

Slabキャッシュのクリア

以下が各フェーズの実行結果です。

・slabtopの結果(reload後)
  OBJS ACTIVE      USE OBJ SIZE   SLABS OBJ/SLAB CACHE SIZE NAME
20941060 20940019  99%    0.19K 1047053       20   4188212K dentry
  302198   301745  99%    0.06K    5122       59     20488K size-64

・Slabキャッシュクリアとその後のfree
# sync
# echo 2 > /proc/sys/vm/drop_caches
# free -m
             total       used       free     shared    buffers     cached
Mem:          7871        791       7080          1        167         56
-/+ buffers/cache:        567       7304
Swap:         1023          0       1023

・slabtopの結果(Slabキャッシュクリア後)
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
110580 110572  99%    0.19K   5529       20     22116K dentry
 83068  82608  99%    0.20K   4372       19     17488K vm_area_struct

drop_cachesを変更するにはrootになって実行する必要がありました。

Slabキャッシュクリアの結果

freeコマンドの結果だけからもわかるように、3Gなかったメモリの空き量が、 一気に7Gまで上昇しました。これはすごい!

そしてその後の経過を1日Zabbixで見守っていたのですが、 クリアしたSlabキャッシュをすぐに同じレベルまで確保することはなさそうでしたし、 アプリケーションにも不具合が出てなかったので、この対応で一旦メモリ枯渇の心配は(しばらく)なくなりました。

結論

アクセスが少ないうちは、php-fpmのプロセス管理をdynamicにしましょう。