linux num_fds文件描述符数量限制 & too many openfiles 错误

前言

写了一个循环函数,每次循环使用一个wandb.run记录数据。
最后报错 OSError: [Errno 24] Too many open files
国内用wandb的人好像还不是很多…隔壁tensorboard的为主。
自食其力。

问题探索

可以用psutil库持续跟踪进程的句柄和描述符数量。

import psutil
def num_open_files():
	s = psutil.Process()
	num_open_files = len(s.open_files())
	num_file_descriptions = s.num_fds()
	return num_open_files ,num_file_descriptions

在我跑的代码中,
在这里插入图片描述
这个num open files的2,在wandb.finish()之后就清0了。
但是num_fds持续增加。
每过一个循环+4。

可以看出来问题还是在file description的数量上。这样一直增加下去,达到上限可不就报错了么。

通过命令可以查看当前进程(11448)下的所有文件描述符。

ls -l \proc\11448\fd
linux num_fds文件描述符数量限制 & too many openfiles 错误_第1张图片

从这个图已经能看出来为什么每个循环num_fd会 +4了。
每个循环里,都会打开2个描述符,指向 ‘/dev/pts/92’ 。
然后打开2个描述符,指向2个wandb上传管道。
这样一共是4个fd。
符合观察。

python里的文件描述符需要显式关闭

我遇到的这个问题,
归根结底是wandb会持续打开新的连接,创建新的管道,向服务器传数据。
但python没有很好的自动回收机制处理这些句柄。

注意:python打开的文件描述符需要显式进行关闭

这是python的特性决定的。
一般的文件操作中,我们用with scope的话,会自动关闭这个fd。
或者用os.close(file)自己关闭。

但wandb没有写好这个功能。只打开,不关闭。
(去提issue)

解决方案

在官方解决这个问题之前,我们可以试着增加系统对文件描述符的限制。
linux默认一般是1024,每个循环+4,那么最多256个循环就满了。

软硬限制

硬限制是实际的限制,而软限制,是warnning限制,只会做出warning

分析句柄数

分析句柄数,查找原因,这是解决问题最根本的办法。那么如何分析那,就需要用到lsof这个命令了(关于这个命令大家可以在网上学习学习)。

1 统计各进程打开句柄数:lsof -n|awk ‘{print $2}’|sort|uniq -c|sort -nr
2 统计各用户打开句柄数:lsof -n|awk ‘{print $3}’|sort|uniq -c|sort -nr
3 统计各命令打开句柄数:lsof -n|awk ‘{print $1}’|sort|uniq -c|sort -nr

文件打开数量

Check Hard/Soft Limit in Linux

ulimit -Hn
ulimit -Sn

查看

ulimit -n

设置2个一起提高(直到下次reboot前有效)

ulimit -SHn 65535

写入文件

vim /etc/security/limits.conf
加两行
soft nofile 65535
hard nofile 65535

文件描述符数量

全局设置文件描述符数量
Check System wide File Descriptors Limits in Linux

整个系统所有用户的最大打开数量

cat /proc/sys/fs/file-max
26357916

可以直接vim

vim /proc/sys/fs/file-max
加一行

# To increase open file limit to 500000, the change remain active until the next reboot
sysctl -w fs.file-max=500000
# apply them permanently
vi /etc/sysctl.conf
# add the following line 
fs.file-max=500000
# Users will need to logout and login again for the changes to take effect, if you want to apply the limit immediately, you can use:
sysctl -p

为单用户设置文件描述符数量

vi /etc/security/limits.conf

//https://www.cnblogs.com/feng0815/p/8620564.html
//https://www.tecmint.com/increase-set-open-file-limits-in-linux/

你可能感兴趣的:(linux,linux,服务器,运维)