我一直java.io.IOException: Too many open files
在运行 Kafka 实例并使用一个具有 1000 个分区的主题,因此我开始调查我的 ec2 vm 中的文件描述符限制。我无法理解 Centos 7 机器上打开文件的确切限制是什么,因为以下所有命令都会产生不同的结果。命令是:
ulimit -a
: 打开文件 1024lsof | wc -l
: 298280cat /proc/sys/fs/file-max
: 758881(与 一致/proc/sys/fs/file-nr
)
如果实际限制是最后一个命令产生的限制,那么我远低于它(lsof | wc -l
:298280)。但如果是这种情况,ulimit
命令的输出对我来说很不清楚,因为我远远高于 1024 个打开的文件。
根据官方文档,在 Centos 中检查文件描述符的最佳方法是/proc/sys/fs/file-max
文件,但是这些命令之间是否存在所有这些看似“不一致”的地方?
file-max
是可以在整个系统中打开的最大文件数。这是在内核级别强制执行的。的手册页
lsof
指出:这与您的观察结果一致,因为报告的文件数量
lsof
远低于file-max
设置。ulimit
用于在用户级别强制执行资源限制。参数“打开文件数”在用户级别设置,但应用于该用户启动的每个进程。在这种情况下,单个 Kafka 进程最多可以打开 1024 个文件句柄(软限制)。您可以自行将此限制提高到硬限制 4096。要提高硬限制,需要 root 访问权限。
如果 Kafka 作为单个进程运行,您可以使用
lsof -p [PID]
.希望这可以解决问题。
这是一个常见的错误:将原始
lsof
调用的结果与假定的限制进行比较。对于全局限制 (
/proc/sys/fs/file-max
),您应该查看/proc/sys/fs/file-nr
; 第一个值表示使用什么,最后一个值是限制。OpenFile 限制适用于每个进程,但可以在用户上定义;请参阅命令
ulimit -Hn
了解用户限制并了解/etc/security/limits.conf
定义。通常与“app user”一起使用,例如:“tomcat”:将用户tomcat的限制设置为65000,这将应用于它运行的java进程。如果要检查应用于进程的限制,请获取其 PID,然后:
cat /proc/${PID}/limits
如果要检查进程打开了多少文件,请获取其 PID,然后:
ls -1 /proc/${PID}/fd | wc -l
(注意 ls 是 'minus one',不要与 'minus 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