我们经营阿帕奇·卡桑德拉集群中每个主机在任意时刻都会打开几十万个文件。
我们希望能够定期获取打开文件的数量,并将该数字输入到石墨,但当我们lsof
运行collectd
,它最终需要几分钟才能完成,同时消耗大量的 CPU。
我想知道是否有其他更友好的方法来获取 lsof 提供的相同数据,或者是否有一种运行 lsof 的方法不会明显消耗 CPU?(虽然我认为后一种方法可能比现在需要更长的时间才能完成……并不理想)。
也许内核在某处维护着一些变量,其中包含打开文件的数量?这只是一厢情愿的想法?
更新:
针对其中一个答案,我们已经使用了-b
和-n
标志。这是我在下运行的完整命令collectd
:
sudo lsof -b -n -w | stdbuf -i0 -o0 -e0 wc -l
答案1
您可能不需要解析套接字的网络地址,因此至少使用开关-n
。然后您可能还想使用跳过阻塞操作-b
。
这两个第一个开关确实会使它更快。
然后-l
避免解析 uid。-L
避免计算链接数。等等。请参阅人 lsof。
或者,使用 Linux,您可以编写一个脚本来简单地计算下面的链接数,/proc/<PID>/fd
如下所示:
find /proc -mindepth 3 -maxdepth 3 -type l | awk -F/ '$4 == "fd" { s++ } END { print s }'
答案2
你这样做是错的。
从man proc
/proc/sys/fs/file-nr
此(只读)文件包含三个数字:已分配文件句柄的数量(即,当前打开的文件数量);可用文件句柄的数量;以及文件句柄的最大数量(即,与 /proc/sys/fs/file-max 相同的值)。如果已分配文件句柄的数量接近最大值,则应考虑增加最大值。在 Linux 2.6 之前,内核会动态分配文件句柄,但不会再次释放它们。相反,将可用文件句柄保存在列表中以供重新分配;“可用文件句柄”值表示该列表的大小。大量可用文件句柄表示打开文件句柄的使用量过去达到峰值。自 Linux 2.6 以来,内核会释放已释放的文件句柄,并且“可用文件句柄”值始终为零。
如果您喜欢猫,则第一个值会准确地给出您想要的东西。
为了记录,lsof
即使进行了一些弄虚作假,我也无法获得与之匹配的输出,但我认为,如果这是内核所说的,那么它比你从中获得的列表更权威lsof
。