Linuxで開いているファイルの数を監視できるようにしたいです。現在、/proc/<pid>/fd
合計のファイル数を計算していますfdinfo
。
私のロードバランサーには約100万のFDがあります。したがって、実行には約20秒かかります。
ただし、これによりCPU使用率が高くなります。47.18% [kernel] [k] __d_lookup
この番号を取得するより効率的な方法はありますか?
答え1
専用ロードバランサーの場合は、I / OリソースとCPUリソースをプロセスごとに計算して無駄にするのではなく、システムで開いているファイルの総数を追跡します。不要なプロセスの残りのオープンファイルには、期待される結果に対して意味のない値が必要です。
Linuxシステムでグローバルに開かれたファイル数を確認するために統計は必要ありません。 Linuxカーネルは開いているファイルの数を追跡します。
これを確認するには:
cat /proc/sys/fs/file-nr | awk ' { print $1 } '
または
sysctl fs.file-nr | awk ' { print $1 } '
これは、出力を使用して開かれたすべてのファイルを計算するよりもはるかに効率的です。lsof
これはすべての/proc/$PID/fd
ディレクトリを通過し、システムI / O / CPUリソースに悪影響を及ぼします。
答え2
単純な:
lsof | wc -l
システムに開いているファイルの数を示します。
答え3
あなたのユースケースに対してこのSystemTapコードはどのくらい効率的ですか?これは開始から変更のみを追跡するため(開始前に開かれたすべての項目が欠落しているため)、出力をより明確またはより適切にするために追加の作業が必要になるため、完璧なビューではありません。
global procfdcount
probe begin {
printf("begin trace...\n\n")
}
probe syscall.open {
procfdcount[pid()]++
}
probe syscall.close {
p = pid()
procfdcount[p]--
if (procfdcount[p] < 0) {
procfdcount[p] = 0
}
}
probe kprocess.exit {
p = pid()
if (p in procfdcount) {
delete procfdcount[p]
}
}
probe timer.s(60) {
foreach (p in procfdcount- limit 20) {
printf("%d %lu\n", p, procfdcount[p])
}
printf("\n")
}
同様に実行します。
... (install systemtap here) ...
# stap-prep
... (fix any reported systemtap issues here) ...
# stap procfdcount.stp
このアプローチの欠点は、すべての「オープンファイル」(ソケットなど)を識別し、適切なシステムコールフック(利用可能な場合)を介して数を調整する必要があることです。上記の方法はファイルファイルのみを追跡します。別のオプションは、task_open_file_handles
ジョブをCPUに呼び出し、定期的に最新の数を表示することです。
global taskopenfh
probe begin {
printf("begin trace...\n\n");
}
probe scheduler.cpu_on {
p = pid();
if (p == 0) next;
taskopenfh[p] = task_open_file_handles(pid2task(p));
}
probe timer.s(60) {
foreach (p in taskopenfh-) {
printf("%d %lu\n", p, taskopenfh[p]);
}
delete taskopenfh;
printf("\n");
}
しかし、これはCPUにないすべてを見逃してしまいます。完全なリストには完全なプロセスとタスクが必要ですが、数百万のFDがある場合は遅すぎるか、高価です。
また、プローブが不安定に見えますが、今後eBPFなどを使用することができますか?例えば、Centos 7の2番目のものはしばらくして爆発しました。
ERROR: read fault [man error::fault] at 0x0000000000000008 (((&(fs->fdt))))
near identifier 'task_open_file_handles' at
/usr/share/systemtap/tapset/linux/task.stp:602:10