ulimit、lsof、cat /proc/sys/fs/file-max 之间的区别

ulimit、lsof、cat /proc/sys/fs/file-max 之间的区别

我在运行 Kafka 实例并使用具有 1000 个分区的一个主题时遇到了问题java.io.IOException: Too many open files,因此我开始研究我的 ec2 虚拟机中的文件描述符限制。我无法理解 Centos 7 机器上打开文件的确切限制,因为以下所有命令都会产生不同的结果。命令是:

  • ulimit -a:打开文件1024
  • lsof | wc -l:298280
  • cat /proc/sys/fs/file-max:758881(与 一致/proc/sys/fs/file-nr

如果实际限制是最后一个命令产生的限制,那么我远远低于它(lsof | wc -l:298280)。但如果是这种情况,命令的输出ulimit对我来说相当不清楚,因为我远远高于 1024 个打开的文件。

根据官方文档,在 Centos 中检查文件描述符的最佳方法是/proc/sys/fs/file-max文件但是这些命令之间是否存在所有这些看似“不一致”的情况?

答案1

  1. file-max是整个系统可以打开的最大文件数。这是在内核级别强制执行的。

  2. 手册页指出lsof

如果没有任何选项,lsof 会列出属于所有活动进程的所有打开文件。

这与您的观察结果一致,因为报告的文件数量lsof远低于file-max设置。

  1. 最后,ulimit用于在用户级别强制实施资源限制。参数“打开文件的数量”在用户级别设置,但应用于该用户启动的每个进程。在这种情况下,单个 Kafka 进程最多可以打开 1024 个文件句柄(软限制)。

您可以自行将此限制提高到硬限制 4096。要提高硬限制,需要 root 访问权限。

如果 Kafka 作为单个进程运行,您可以使用 查找该进程打开的文件数lsof -p [PID]

希望这能解决问题。

答案2

这是一个常见的错误:将原始调用的结果lsof与假定的限制进行比较。

对于全局限制 ( /proc/sys/fs/file-max),您应该看看/proc/sys/fs/file-nr;第一个值表示使用的内容,最后一个值是限制。

OpenFile 限制针对每个进程,但可以针对用户定义;ulimit -Hn有关用户限制,请参阅命令并参阅/etc/security/limits.conf定义。通常与“app user”一起应用,例如:“tomcat”:将限制设置为 65000 给用户 tomcat,该限制将应用于其运行的 java 进程。

如果您想检查对进程应用的限制,请获取其 PID,然后:

cat /proc/${PID}/limits

如果您想检查某个进程打开了多少个文件,请获取其 PID,然后:

ls -1 /proc/${PID}/fd | wc -l(注意 ls 是“减一”,不要与“减 el”混淆)

如果您想了解 lsof 的详细信息,但只想了解那些计入限制的文件句柄,请尝试以下操作:

lsof -p ${PID} | grep -P "^(\w+\s+){3}\d+\D+"

lsof -p ${PID} -d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt' -a

备注:“文件”是文件/管道/tcp连接/等。

请注意,有时您可能需要成为 root 用户或使用 sudo 才能获得命令的正确结果;如果没有特权,有时您不会看到错误,只会得到更少的结果。

最后,如果您想知道进程访问文件系统上的哪些文件,请查看:

lsof -p ${PID} | grep / | awk '{print $9}' | sort | uniq

相关内容