helen's blog

ずっとおもしろいことしてたいな。

dentryキャッシュ対応に悩まされた話

原因は完全にこれ↓で

tools.knetik.io

要約すると、余裕がある時はめっちゃcurlしてキャッシュするっていう機能があって
放置するとmemoryをどんどん使っていくので
nss-softokenを3.16以上にしてオプション有効にしようね、という話

Bug 1044666 – Can curl HTTPS requests make fewer access system calls?
でも報告されていて、NSS_SDB_USE_CACHEをYESかNOにすると
sdb_measureAccessを呼ばなくなるらしい

自分のところではswap領域を使わないまま
約24時間でusedが7GB弱増えていました

export NSS_SDB_USE_CACHE=YES

を/etc/sysconfig/httpdに追加して経過観察してたけど全然効き目がなく
適当に設定をNOにしてみたり無意味に大文字小文字を変えてみたりの無駄な手順を試したけど当然効かず
でも放置するわけにもいかないので毎日dentryキャッシュを削除していました

f:id:heleeen:20180223021506p:plain

↑ キャッシュを削除する日々の図
最初はアラートで呼ばれたので対応して、
次の3回くらいはアラートを飛ばさないためにキャッシュ削除しただけで
その後は設定を入れてもうまくいかない戦いです
すごい徒労感があるね!

諸々のバージョン

$ httpd -V
Server version: Apache/2.4.25 (Amazon)

$ sudo yum list nss-softokn
nss-softokn.x86_64              3.16.2.3-14.4.39.amzn1 

$ curl -V
curl 7.51.0 (x86_64-redhat-linux-gnu) libcurl/7.51.0 NSS/3.28.4 

やってたこと

NSS_SDB_USE_CACHE=yesが効きそうか見る

access回数が減るので効果はあるはずなのに
apacheを再起動して数時間待つとなぜかメモリ消費してた
See. アプリケーション内でhttpsによる外部APIを叩いているサーバのメモリ使用量が増加し続ける件について - s_tajima:TechBlog

$ strace -fc -e trace=access curl 'https://www.google.com' > /dev/null
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.000065           0      1626      1622 access # ここがおかしい
------ ----------- ----------- --------- --------- ----------------
100.00    0.000065                  1626      1622 total

$ NSS_SDB_USE_CACHE=yes strace -fc -e trace=access curl 'https://www.google.com' > /dev/null
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0        32        30 access # 効いてる
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    32        30 total

# noでもこれくらい
$ NSS_SDB_USE_CACHE=no strace -fc -e trace=access curl 'https://www.google.com' > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   272  100   272    0     0   1786      0 --:--:-- --:--:-- --:--:--  1789
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0        58        56 access
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    58        56 total

オプションをつけずにcurlすると何度もaccessされるのがわかる

$ strace -e trace=access curl 'https://www.google.com' > /dev/null
...
access("/$HOME/.pki/nssdb/cert3.db", F_OK) = -1 ENOENT (No such file or directory)
access("/$HOME/.pki/nssdb/cert2.db", F_OK) = -1 ENOENT (No such file or directory)
access("/$HOME/.pki/nssdb/key3.db", F_OK) = -1 ENOENT (No such file or directory)
access("/$HOME/.pki/nssdb/key2.db", F_OK) = -1 ENOENT (No such file or directory)
access("/$HOME/.pki/nssdb/secmod.db", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/pki/nssdb/.3550898456_dOeSnotExist_.db", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/pki/nssdb/.3550898457_dOeSnotExist_.db", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/pki/nssdb/.3550898458_dOeSnotExist_.db", F_OK) = -1 ENOENT (No such file or directory)
...
設定反映されてないのかな

環境変数を見ると入っているのになぁ・・って思ってました

$ sudo od -S1 -An /proc/4057/environ # httpd
TERM=xterm
PATH=/sbin:/usr/sbin:/bin:/usr/bin
PWD=/
LANG=C
SHLVL=2
NSS_SDB_USE_CACHE=YES # ここ
_=/usr/sbin/httpd
直線で増加していくのっておかしくない?

httpdが原因ならアクセス数に比例するはずなのに
直線で増加していくのっておかしくない?ってようやく気づきました

内部でずっと動いてくれているものにすごく心当たりがあって・・・
出来心で/etc/sysconfig/mackerel-agentにも同じ内容追加して
エージェント再起動したのがこちら

f:id:heleeen:20180223153718p:plain

キャッシュ増加が止まったのがはっきりわかって
嬉しくて思わずslackにも流してしまったやつ

最初のブログにもhttpd以外にも必要なら入れてね!って書いてあったのに!!
逆にhttpdからその環境変数外すとどうなるんだろうと思って外したら
増加の仕方はとてもゆっくりという結果になりました・・
アプリケーションの負荷ェ.....

他のメトリックにも特に影響は見られなかったので
ひとまずは解決で良さそうだけど
特定プロセスに対してしか設定してないから
たとえばサーバ内でcurlされるとキャッシュは増加するまんま・・・(。ŏ﹏ŏ)
他にそういうツールとかいれたらまた同じことが発生するなぁ・・