大批量解析文件之后,批量失败报错:OSError: [Errno 24] Too many open files
问题解析:
这个报错指的是进程文件描述符 耗尽了,在 Linux 中,一切都是文件(包括 socket、pipe、普通文件等)。一个进程能同时打开的文件数有上限(ulimit 限制),超出以后再打开新文件/连接就会报这个错。
问题定位:
docker exec 进到容器里, 查看限制数
bash
docker exec -it ragflow-server /bin/bash
ulimit -n
输出:
1024
首先找到你进程的id,这里ragflow启动了两个python服务,ragflow-server和task-executor, 依次查看pid
bash
ps -ef | grep ragflow
输出:
root 18 14 4 Aug26 ? 11:34:48 python3 api/ragflow_server.py
root 99300 99286 0 17:29 pts/7 00:00:00 grep --color=auto ragflow
ls -l /proc/18/fd | wc -l
输出:
105
ps -ef | grep task_executor
输出:
root 41 17 0 Aug26 ? 00:41:55 python3 rag/svr/task_executor.py d6bcbdbc7b76_0
root 42 20 0 Aug26 ? 00:42:38 python3 rag/svr/task_executor.py d6bcbdbc7b76_1
root 44 22 0 Aug26 ? 00:41:20 python3 rag/svr/task_executor.py d6bcbdbc7b76_2
root 46 25 0 Aug26 ? 00:41:11 python3 rag/svr/task_executor.py d6bcbdbc7b76_3
root 47 28 0 Aug26 ? 00:43:13 python3 rag/svr/task_executor.py d6bcbdbc7b76_4
ls -l /proc/41/fd | wc -l
输出:
1025
......
可以看出,task-executor 的文件资源数已经超出了最大上限。因此后续的操作就会报错 Too many open files
原因分析与方案:
- 同时打开的文件超过了1024,这时候需要修改最大上限
bash
## 容器里执行:
ulimit -n 65535
可以临时设置为最大65535
## 永久改动需要修改docker-compose
ulimits:
nofile:
soft: 65535
hard: 65535
- 每次解析没有释放文件资源,导致一直累积,文件资源泄露导致超过了1024
这个错误原因比较多,常见的有 文件资源、网络请求资源等未释放 使用with语法可以做到在结束后 自动释放资源
with
是 上下文管理器(Context Manager) 语法,它用于在一段代码执行前自动获取资源,并在代码执行完毕后自动清理资源,无论中间是否发生异常。
python
with open("file.txt", "r") as f:
content = f.read()
# 这里 f 已经自动关闭,无需手动调用 f.close()
import requests
with requests.get("http://example.com", stream=True) as r:
...