英文:
Efficient Way to get the number of File Handles Open By a Process in Go?
问题
我有一个名为scollector的监控代理程序,在我们的负载均衡器上使用了更多的CPU。Perf显示CPU主要是由于__d_lookup
引起的。我监控的其中一件事是打开文件句柄的数量 - 我通过以下代码来实现:
fds, e := ioutil.ReadDir("/proc/" + pid + "/fd")
if e != nil {
w.Remove(pid)
continue
}
...
Add(md, "linux.proc.num_fds", len(fds), tags, metadata.Gauge, metadata.Files, descLinuxProcFd)
当我使用strace跟踪该进程时,我发现它在/fd
目录中的每个文件上都调用了lstat
(对于我们活跃的负载均衡器来说,这将是很多文件 - 至少有50万个文件描述符),因此我推测这可能是导致该进程的dentry缓存CPU使用率高的原因。
有人对如何更好地完成这个任务有什么建议吗?
英文:
I have a monitoring agent called scollector that is using more cpu on our loadbalancer. Perf says the CPU is mostly due to __d_lookup
. One of the things I monitor is the number of open file handles - I do this via the following code:
fds, e := ioutil.ReadDir("/proc/" + pid + "/fd")
if e != nil {
w.Remove(pid)
continue
}
...
Add(md, "linux.proc.num_fds", len(fds), tags, metadata.Gauge, metadata.Files, descLinuxProcFd)
When I strace the process, I see it calling lstat
on every file in the /fd
directory (which is going to be a lot for our active load balancer (at least .5 million fds) - so I hypothesizing that this is the source of the high dentry cache cpu usage for the process.
Anyone have a suggestion on a better way to do this?
答案1
得分: 4
ioutil.Readdir
的问题在于它调用了file.Readdir
,而后者对每个文件执行了lstat
操作。
似乎Readdirnames
不会执行这个操作,它只返回文件名。而且由于你只需要计数,这应该已经足够了。
英文:
The trouble with ioutil.Readdir
is that it does file.Readdir
which says that it does an lstat
for every file.
It seems Readdirnames
doesn't do this, returning only the names. And since you only want the count, that should be enough.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论