libcurlでメモリーリークの対応記録


概要

Zabbix Agentの外部スクリプトで外部ページの生存確認をシェル実行していて、メモリが徐々に消費していく現象の対応記録として残します
相変わらず先人たちの情報でなんとか問題解決ができたので、この場をお借りしてお礼を申し上げます!

なお、発生時のキャプチャを取得していなかったので、下記の画像の数値の整合性はありませんのでご了承くださいOrz
同様の対応をされる場合は赤枠の箇所を確認して頂ければ良いかと思います。

実装している外部スクリプト

ごく普通のshellスクリプトです


curl -LI -Ss -w '%{http_code}\n'  -H 'Cache-Control: no-store' -A 'XXX-HealthChecker' $URL -o /dev/null

環境

  • Amazon Linux AMI release 2018.03
  • Zabbix agent 3.4.6-1.el6
  • libcurl 7.53.1-16.84.amzn1

問題確認の時系列

1.Zabbixのメモリ使用量がじわじわと増えていく・・・

2. topコマンドでリソース情報を表示
 実装しているjavaアプリは600Mぐらいですが、buffer/cacheが約1.7GBも消費されている
 
3. vmstatコマンドで仮想メモリやディスクI/Oの統計情報を表示
 1秒ごとにメモリ情報を表示

   > vmstat 1

 cacheが徐々に増えていく・・・

4. slabtopコマンドでslabキャッシュ情報を表示
 dentryでやたらメモリ消費されています(本来は1.7GBほど消費されています)

対応

  1. cacheメモリの削除(管理者権限)
    syncコマンドでメモリのデータをファイルに出力してから、メモリの削除を実行!

    # 1・・・ページキャッシュのみ
    # 2・・・Slabキャッシュ
    # 3・・・ページキャッシュ&Slabキャッシュ
    
    > sync && echo 2 > /proc/sys/vm/drop_caches
    
  2. libcurlのキャッシュ利用設定
    curl実行時にキャッシュにひたすら溜め込むのではなく、キャッシュから使えよという設定をします
    とりあえず全ユーザに適用できるように以下の環境変数を設定します
      ユーザ別で指定する場合は、実行ユーザにこの環境変数を適用してください

    /etc/environment
    NSS_SDB_USE_CACHE=yes
    

    ※libcurlやnss-xxxxのバージョンアップなどの対策もあるが、すでに最新のものを使用していたので環境変数で対応した

対応後のグラフ

上記の対応後は一定量で安定します

だがしかし!

ファイルのコピー、作成などをした際にもSlabキャッシュが増えていきますが!
そもそもLinuxの仕組み上ファイルを常にキャッシュすることで処理速度を高めているので、Slabキャッシュで消費されていても必要に応じて解放してくれます。なので、上記のようなバグ以外の時は気にしなくてもいいかも

参考サイト

Slabメモリとは