異常に高いdentryキャッシュの使用


34

問題

カーネル2.6.32と128 GBの物理RAMを備えたCentOSマシンは、数日前にトラブルに遭遇しました。担当のシステム管理者は、PHP-FPMアプリケーションがスワッピングのためにタイムリーにリクエストに応答しなくなったことを教えてくれ、freeメモリがほとんど残っていないことを見て、マシンをリブートすることにしました。

Linuxでは、空きメモリは混乱を招く概念になる可能性があり、再起動はおそらく間違ったことだと思います。ただし、前述の管理者は、PHPアプリケーション(私が担当している)を非難し、さらに調査することを拒否します。

私が自分で見つけることができたのはこれです:

  • 再起動前は、空きメモリ(バッファとキャッシュを含む)はわずか数百MBでした。
  • 再起動の前に、/proc/meminfo約90 GB(はい、GB)のスラブメモリ使用量を報告しました。
  • 再起動後、PHP-FPMワーカー(約600人)が復活し、それぞれが30〜40 MBを示していたため、空きメモリは119 GBで、1時間以内に約100 GBになりました。上部のRES列(これは何ヶ月もこの方法であり、PHPアプリケーションの性質を考えると完全に合理的です)。プロセスリストには、異常な量または注目に値する量のRAMを消費するものは他にありません。
  • 再起動後、スラブメモリは約300 MBでした

それ以降、システムを監視している場合、最も顕著なのは、スラブのメモリが1日に約5 GBの割合で直線的に増加していることです。報告される空きメモリfree/proc/meminfo同じ割合で減少します。スラブは現在46 GBです。よると、slabtopそれを最大限に使用されdentryたエントリ:

空きメモリ:

free -m
             total       used       free     shared    buffers     cached
Mem:        129048      76435      52612          0        144       7675
-/+ buffers/cache:      68615      60432
Swap:         8191          0       8191

Meminfo:

cat /proc/meminfo
MemTotal:       132145324 kB
MemFree:        53620068 kB
Buffers:          147760 kB
Cached:          8239072 kB
SwapCached:            0 kB
Active:         20300940 kB
Inactive:        6512716 kB
Active(anon):   18408460 kB
Inactive(anon):    24736 kB
Active(file):    1892480 kB
Inactive(file):  6487980 kB
Unevictable:        8608 kB
Mlocked:            8608 kB
SwapTotal:       8388600 kB
SwapFree:        8388600 kB
Dirty:             11416 kB
Writeback:             0 kB
AnonPages:      18436224 kB
Mapped:            94536 kB
Shmem:              6364 kB
Slab:           46240380 kB
SReclaimable:   44561644 kB
SUnreclaim:      1678736 kB
KernelStack:        9336 kB
PageTables:       457516 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    72364108 kB
Committed_AS:   22305444 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      480164 kB
VmallocChunk:   34290830848 kB
HardwareCorrupted:     0 kB
AnonHugePages:  12216320 kB
HugePages_Total:    2048
HugePages_Free:     2048
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:        5604 kB
DirectMap2M:     2078720 kB
DirectMap1G:    132120576 kB

スラブトップ:

slabtop --once
Active / Total Objects (% used)    : 225920064 / 226193412 (99.9%)
 Active / Total Slabs (% used)      : 11556364 / 11556415 (100.0%)
 Active / Total Caches (% used)     : 110 / 194 (56.7%)
 Active / Total Size (% used)       : 43278793.73K / 43315465.42K (99.9%)
 Minimum / Average / Maximum Object : 0.02K / 0.19K / 4096.00K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
221416340 221416039   3%    0.19K 11070817       20  44283268K dentry                 
1123443 1122739  99%    0.41K 124827        9    499308K fuse_request           
1122320 1122180  99%    0.75K 224464        5    897856K fuse_inode             
761539 754272  99%    0.20K  40081       19    160324K vm_area_struct         
437858 223259  50%    0.10K  11834       37     47336K buffer_head            
353353 347519  98%    0.05K   4589       77     18356K anon_vma_chain         
325090 324190  99%    0.06K   5510       59     22040K size-64                
146272 145422  99%    0.03K   1306      112      5224K size-32                
137625 137614  99%    1.02K  45875        3    183500K nfs_inode_cache        
128800 118407  91%    0.04K   1400       92      5600K anon_vma               
 59101  46853  79%    0.55K   8443        7     33772K radix_tree_node        
 52620  52009  98%    0.12K   1754       30      7016K size-128               
 19359  19253  99%    0.14K    717       27      2868K sysfs_dir_cache        
 10240   7746  75%    0.19K    512       20      2048K filp  

VFSキャッシュプレッシャー:

cat /proc/sys/vm/vfs_cache_pressure
125

Swappiness:

cat /proc/sys/vm/swappiness
0

未使用のメモリは無駄なメモリであることを知っているので、これは必ずしも悪いことではないはずです(特に44 GBがSReclaimableとして表示されている場合)。しかし、どうやらマシンに問題が発生したようで、スラブが90 GBを超える数日後には同じことが再び起こるのではないかと思います。

ご質問

これらの質問があります:

  • スラブのメモリは常に物理RAMであり、MemFreeの値からすでに数字が減算されていると考えるのは正しいですか?
  • このような多数のdentryエントリは正常ですか?PHPアプリケーションは約150万のファイルにアクセスできますが、それらのほとんどはアーカイブであり、通常のWebトラフィックではまったくアクセスされません。
  • キャッシュされたinodeの数がキャッシュされたdentriesの数よりもはるかに少ないという事実の説明はどうでしょうか。
  • システムでメモリの問題が発生した場合、カーネルはいくつかのデントリを自動的に解放しないのですか?これが起こらない理由は何でしょうか?
  • dentryキャッシュを「調べて」、このすべてのメモリが何であるか(つまり、キャッシュされているパスは何であるか)を確認する方法はありますか?おそらく、これはある種のメモリリーク、シンボリックリンクループ、または実際にPHPアプリケーションが間違っていることを示しています。
  • PHPアプリケーションコードとすべてのアセットファイルはGlusterFSネットワークファイルシステムを介してマウントされますが、それは何か関係があるのでしょうか?

通常のユーザーとしてのみrootとして調査することはできず、管理者が支援を拒否することに注意してください。彼はecho 2 > /proc/sys/vm/drop_caches、スラブのメモリが実際に再生可能であるかどうかを確認するための典型的なテストさえ実行しません。

何が起こっているのか、どのようにさらに調査できるのかについての洞察は大歓迎です。

更新情報

さらにいくつかの診断情報:

マウント:

cat /proc/self/mounts
rootfs / rootfs rw 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,relatime 0 0
devtmpfs /dev devtmpfs rw,relatime,size=66063000k,nr_inodes=16515750,mode=755 0 0
devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /dev/shm tmpfs rw,relatime 0 0
/dev/mapper/sysvg-lv_root / ext4 rw,relatime,barrier=1,data=ordered 0 0
/proc/bus/usb /proc/bus/usb usbfs rw,relatime 0 0
/dev/sda1 /boot ext4 rw,relatime,barrier=1,data=ordered 0 0
tmpfs /phptmp tmpfs rw,noatime,size=1048576k,nr_inodes=15728640,mode=777 0 0
tmpfs /wsdltmp tmpfs rw,noatime,size=1048576k,nr_inodes=15728640,mode=777 0 0
none /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0
cgroup /cgroup/cpuset cgroup rw,relatime,cpuset 0 0
cgroup /cgroup/cpu cgroup rw,relatime,cpu 0 0
cgroup /cgroup/cpuacct cgroup rw,relatime,cpuacct 0 0
cgroup /cgroup/memory cgroup rw,relatime,memory 0 0
cgroup /cgroup/devices cgroup rw,relatime,devices 0 0
cgroup /cgroup/freezer cgroup rw,relatime,freezer 0 0
cgroup /cgroup/net_cls cgroup rw,relatime,net_cls 0 0
cgroup /cgroup/blkio cgroup rw,relatime,blkio 0 0
/etc/glusterfs/glusterfs-www.vol /var/www fuse.glusterfs rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072 0 0
/etc/glusterfs/glusterfs-upload.vol /var/upload fuse.glusterfs rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072 0 0
sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0
172.17.39.78:/www /data/www nfs rw,relatime,vers=3,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,port=38467,timeo=600,retrans=2,sec=sys,mountaddr=172.17.39.78,mountvers=3,mountport=38465,mountproto=tcp,local_lock=none,addr=172.17.39.78 0 0

マウント情報:

cat /proc/self/mountinfo
16 21 0:3 / /proc rw,relatime - proc proc rw
17 21 0:0 / /sys rw,relatime - sysfs sysfs rw
18 21 0:5 / /dev rw,relatime - devtmpfs devtmpfs rw,size=66063000k,nr_inodes=16515750,mode=755
19 18 0:11 / /dev/pts rw,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=000
20 18 0:16 / /dev/shm rw,relatime - tmpfs tmpfs rw
21 1 253:1 / / rw,relatime - ext4 /dev/mapper/sysvg-lv_root rw,barrier=1,data=ordered
22 16 0:15 / /proc/bus/usb rw,relatime - usbfs /proc/bus/usb rw
23 21 8:1 / /boot rw,relatime - ext4 /dev/sda1 rw,barrier=1,data=ordered
24 21 0:17 / /phptmp rw,noatime - tmpfs tmpfs rw,size=1048576k,nr_inodes=15728640,mode=777
25 21 0:18 / /wsdltmp rw,noatime - tmpfs tmpfs rw,size=1048576k,nr_inodes=15728640,mode=777
26 16 0:19 / /proc/sys/fs/binfmt_misc rw,relatime - binfmt_misc none rw
27 21 0:20 / /cgroup/cpuset rw,relatime - cgroup cgroup rw,cpuset
28 21 0:21 / /cgroup/cpu rw,relatime - cgroup cgroup rw,cpu
29 21 0:22 / /cgroup/cpuacct rw,relatime - cgroup cgroup rw,cpuacct
30 21 0:23 / /cgroup/memory rw,relatime - cgroup cgroup rw,memory
31 21 0:24 / /cgroup/devices rw,relatime - cgroup cgroup rw,devices
32 21 0:25 / /cgroup/freezer rw,relatime - cgroup cgroup rw,freezer
33 21 0:26 / /cgroup/net_cls rw,relatime - cgroup cgroup rw,net_cls
34 21 0:27 / /cgroup/blkio rw,relatime - cgroup cgroup rw,blkio
35 21 0:28 / /var/www rw,relatime - fuse.glusterfs /etc/glusterfs/glusterfs-www.vol rw,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072
36 21 0:29 / /var/upload rw,relatime - fuse.glusterfs /etc/glusterfs/glusterfs-upload.vol rw,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072
37 21 0:30 / /var/lib/nfs/rpc_pipefs rw,relatime - rpc_pipefs sunrpc rw
39 21 0:31 / /data/www rw,relatime - nfs 172.17.39.78:/www rw,vers=3,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,port=38467,timeo=600,retrans=2,sec=sys,mountaddr=172.17.39.78,mountvers=3,mountport=38465,mountproto=tcp,local_lock=none,addr=172.17.39.78

GlusterFS設定:

cat /etc/glusterfs/glusterfs-www.vol
volume remote1
  type protocol/client
  option transport-type tcp
  option remote-host 172.17.39.71
   option ping-timeout 10
   option transport.socket.nodelay on # undocumented option for speed
    # http://gluster.org/pipermail/gluster-users/2009-September/003158.html
  option remote-subvolume /data/www
end-volume

volume remote2
  type protocol/client
  option transport-type tcp
  option remote-host 172.17.39.72
   option ping-timeout 10
   option transport.socket.nodelay on # undocumented option for speed
        # http://gluster.org/pipermail/gluster-users/2009-September/003158.html
  option remote-subvolume /data/www
end-volume

volume remote3
  type protocol/client
  option transport-type tcp
  option remote-host 172.17.39.73
   option ping-timeout 10
   option transport.socket.nodelay on # undocumented option for speed
        # http://gluster.org/pipermail/gluster-users/2009-September/003158.html
  option remote-subvolume /data/www
end-volume

volume remote4
  type protocol/client
  option transport-type tcp
  option remote-host 172.17.39.74
   option ping-timeout 10
   option transport.socket.nodelay on # undocumented option for speed
        # http://gluster.org/pipermail/gluster-users/2009-September/003158.html
  option remote-subvolume /data/www
end-volume

volume replicate1
  type cluster/replicate
   option lookup-unhashed off    # off will reduce cpu usage, and network
   option local-volume-name 'hostname'
  subvolumes remote1 remote2
end-volume

volume replicate2
  type cluster/replicate
   option lookup-unhashed off    # off will reduce cpu usage, and network
   option local-volume-name 'hostname'
  subvolumes remote3 remote4
end-volume

volume distribute
  type cluster/distribute
  subvolumes replicate1 replicate2
end-volume

volume iocache
  type performance/io-cache
   option cache-size 8192MB        # default is 32MB
   subvolumes distribute
end-volume

volume writeback
  type performance/write-behind
  option cache-size 1024MB
  option window-size 1MB
  subvolumes iocache
end-volume

### Add io-threads for parallel requisitions
volume iothreads
  type performance/io-threads
  option thread-count 64 # default is 16
  subvolumes writeback
end-volume

volume ra
  type performance/read-ahead
  option page-size 2MB
  option page-count 16
  option force-atime-update no
  subvolumes iothreads
end-volume

cat /proc/self/mountsand の出力を提供してください(たぶんかなり長い)cat /proc/self/mountinfo
マシューイフェ

@MIfe質問を更新しました。両方の出力が追加されます。
ヴォルフガングステンゲル

ここでの私の感覚は、おそらくNFS dentryキャッシングと関係があると思います。興味のない実行することができますcat /etc/nfsmount.conf。また、直接のディレクトリに多くのファイルを含むディレクトリがありますか?
マシューイフェ

1
まあ、vfs_cache_pressure> 100なので、カーネルはdentrieキャッシュメモリを再利用することを好むはずです。これは簡単にバグになる可能性があり、2.6.32はRedHatバックポートパッチを使用していても、かなり古いカーネルです。ところで、正確なカーネルバージョンは何ですか?
poige

2
(あなたのシステム管理者が鳴りひどいそれは私たちに悪い名前を与えます。)
ewwhite

回答:


14

スラブのメモリは常に物理RAMであり、MemFreeの値からすでに数字が減算されていると考えるのは正しいですか?

はい。

このような多数のdentryエントリは正常ですか?PHPアプリケーションは約150万のファイルにアクセスできますが、それらのほとんどはアーカイブであり、通常のWebトラフィックではまったくアクセスされません。

はい、システムがメモリ不足になっていない場合。何かのためにメモリを使用する必要があり、特定の使用パターンでは、これがそのメモリを使用する最良の方法である可能性があります。

キャッシュされたinodeの数がキャッシュされたdentriesの数よりもはるかに少ないという事実の説明はどうでしょうか。

多くのディレクトリ操作が最も可能性の高い説明です。

システムでメモリの問題が発生した場合、カーネルはいくつかのデントリを自動的に解放しないのですか?これが起こらない理由は何でしょうか?

そうすべきであり、そうしない理由は考えられません。これが実際にうまくいかなかったとは確信していません。カーネルをアップグレードするか、vfs_cache_pressureをさらに増やすことを強くお勧めします。

dentryキャッシュを「調べて」、このすべてのメモリが何であるか(つまり、キャッシュされているパスは何であるか)を確認する方法はありますか?おそらく、これはある種のメモリリーク、シンボリックリンクループ、または実際にPHPアプリケーションが間違っていることを示しています。

あるとは思わない。検索やトラバースが行われる、非常に多数のエントリまたは非常に深いディレクトリ構造を持つディレクトリを探します。

PHPアプリケーションコードとすべてのアセットファイルはGlusterFSネットワークファイルシステムを介してマウントされますが、それは何か関係があるのでしょうか?

間違いなく、ファイルシステムの問題である可能性があります。たとえば、歯科が解放されない原因となるファイルシステムのバグが考えられます。


私の質問に個別に回答していただきありがとうございます。キャッシュプレッシャーが最終的にさらに増加し​​、デントリーキャッシュの増加が停止しました。
ウォルフガングステンゲル

責任あるプログラムをまだ追跡できませんでした。詳細がわかったら、この問題を抱えている他の人に報告します。
ウォルフガングステンゲル

1
ありがとう!私の場合、大きなディレクトリ(0.25 milファイル)が問題の原因であり、2GBのRAMがキャッシュに消えてしまうことがありました。
一部のLinuxオタク

20

確認済みの解決策

同じ問題に遭遇するかもしれない人に。今日、データセンターのスタッフはついにそれを理解しました。原因は、LibcurlにバンドルされているNSS(ネットワークセキュリティサービス)ライブラリでした。最新バージョンへのアップグレードで問題は解決しました。

詳細を説明するバグレポートはこちらです:

https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=1044666

どうやら、一部のパスがローカルまたはネットワークドライブ上にあるかどうかを判断するために、NSSは存在しないファイルを検索し、ファイルシステムがレポートを返すまでにかかった時間を測定していました。十分な数のCurlリクエストと十分なメモリがある場合、これらのリクエストはすべてキャッシュされ、スタックされます。


15

私はこの正確な問題にぶつかりました。Wolfgangは原因については正しいのですが、いくつかの重要な詳細が欠落しています。

  • この問題は、curlまたはlibcurl、またはmozilla NSSを使用して安全な接続を行うその他のソフトウェアで実行されるSSL要求に影響します。安全でないリクエストは問題を引き起こしません。

  • この問題は、同時curl要求を必要としません。curl呼び出しが、RAMを再利用するOSの努力を追い越すほど頻繁である限り、dentryの蓄積が発生します。

  • NSSの新しいバージョンである3.16.0には、この修正が含まれています。ただし、NSSをアップグレードしても無料で修正プログラムを入手することはできません。また、NSSをすべてアップグレードする必要はありません。nss-softokn(nss-utilsに必要な依存関係があります)を最低限アップグレードするだけです。利点を得るには、libcurlを使用しているプロセスの環境変数NSS_SDB_USE_CACHEを設定する必要があります。その環境変数が存在することで、コストのかかる存在しないファイルチェックをスキップできます。

FWIW、私は誰かがそれを必要とする場合のために、もう少し背景/詳細でブログエントリを書きました。


素晴らしいブログ投稿をありがとうございますが、CentOS / RHELでnss-softoknがバージョン3.16に更新されていないことに言及したいと思います。おそらくバージョン6.6で修正されるでしょう。
Strahinja Kustudic 14年

1
注意していただきありがとうございます。おそらく、Amazonはマネージドレポジトリでこれよりも先に(おそらく私たちのリクエストでさえ)出てきました。古いバージョン(3.14-3.15)では、適切な環境変数を設定することにより、半分のメリットが得られます。ノウハウがあれば、v3.16を直接ビルドできる場合があります。そうでない場合、信頼性の高いパフォーマンスを得るには、キャッシュプレッシャーを増やし、関連するCPUヒットを取得するのが最善の策です。
J.ポールディング14年

3
これはNSS-softokn-3.14.3-17とCentOSに6.6に固定されている
Strahinja Kustudic

1
ただ、簡単な修正を探している人々のために明確にする:あなたは両方の更新に持ってnss-softokenRPMをAND設定NSS_SDB_USE_CACHE=YESカールHTTPSを持っているのenv VARは、あなたのdentryキャッシュをフラッディング停止呼び出します。
スティーブケレー

4

https://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.7/2.6.7-mm1/broken-out/vfs-shrinkage-tuning.patchを参照してください

vfs_cache_pressureが100よりも高い値に設定されている場合、いくつかの顕著なdentryメモリの再利用が期待できることを示す数字があります。


私が読んだすべてから、vfs_cache_pressure上記の増加100は、ワークロードに十分なRAMがない場合にのみ意味があります。その場合、値が100を超える方法(10000など)でRAMが解放されます。ただし、全体的なIOは低下します。
ミッコランタライネン

3

実際にはあなたの答えの説明ではありませんが、このシステムのユーザーとしてこの情報を提供しました:

cat /proc/meminfo
MemTotal:       132145324 kB
...
SReclaimable:   44561644 kB
SUnreclaim:      1678736 kB

これはあなたの問題でなく、適切な説明を提供するシステム管理者の責任ではないことを教えてくれます

ここで失礼に聞こえたくありませんが、

  • このホストの役割に関する特定の情報が不足しています。
  • ホストがリソースに優先順位を付ける方法は、範囲外です。
  • このホストでのストレージの設計と展開になじみがないか、関与していません。
  • ルートではないため、特定のシステム出力を提供できません。

スラブの割り当て異常を正当化または解決するのは、システム管理者の責任です。あなたがこれに至るまでの全体のサガの完全な画像を私たちに与えていないか(率直に言って私は興味がありません)、またはあなたのシステム管理者が彼がこの問題を扱うと考える方法で無責任におよび/または無能にふるまっています。

インターネット上のランダムな見知らぬ人に、自分の責任を真剣に受け止めていないと思うことを彼に自由に伝えてください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.