Docker在使用PHP创建和删除文件后不会释放内存
我有一个PHP守护程序脚本,在上传到对象存储之前,下载远程图像并将它们临时存储在本地 PHP内部内存使用率保持稳定,但Docker/Kubernetes报告的内存使用率不断增加 我不确定这是否与PHP、Docker或预期的Linux行为有关 复制问题的示例: Docker image:Docker在使用PHP创建和删除文件后不会释放内存,php,docker,memory,debian,kubernetes,Php,Docker,Memory,Debian,Kubernetes,我有一个PHP守护程序脚本,在上传到对象存储之前,下载远程图像并将它们临时存储在本地 PHP内部内存使用率保持稳定,但Docker/Kubernetes报告的内存使用率不断增加 我不确定这是否与PHP、Docker或预期的Linux行为有关 复制问题的示例: Docker image:php:7.2.2-apache <?php for ($i = 0; $i < 100000; $i++) { $fp = fopen('/tmp/' . $i, 'w+'); fcl
php:7.2.2-apache
<?php
for ($i = 0; $i < 100000; $i++) {
$fp = fopen('/tmp/' . $i, 'w+');
fclose($fp);
unlink('/tmp/' . $i);
unset($fp);
}
在执行脚本之后:
total used free shared buff/cache available
Mem: 3929 2277 155 38 1496 1310
Swap: 1023 167 856
显然,内存已释放,但从主机调用docker stats php apache
表明存在其他问题:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
ccc19719078f php-apache 0.00% 222.1MiB / 3.837GiB 5.65% 1.21kB / 0B 1.02MB / 4.1kB 7
docker stats php apache报告的初始内存使用量为16.04MiB
原因是什么?如何释放内存
在资源有限的Kubernetes群集中运行此控制器会导致pod失败并重复重新启动。是,已报告类似问题 关于CoolJT0725,作者之一,在回答为什么
top
输出中的RES
列显示了与docker stats
不同的内容时(我只想按原样引用他):
如果我理解正确,docker stats中的内存使用量是从容器的内存cgroup中读取的,您可以看到该值与从cat/sys/fs/cgroup/memory/docker/665E99F8B760C0300F10D3D9B35B1A55E5FDCF1B7E4A0E27C1B6FF100981D9A69/memory.usage中读取的490270720值相同,单位为字节,该限制也是内存cgroup限制,在创建容器时由-m设置。RES和memory cgroup的统计数据是不同的,RES不考虑缓存,但memory cgroup考虑缓存,这就是为什么docker stats中MEM的使用要比top中的RES多得多
用户的建议实际上可能会帮助您了解实际的内存消耗情况:
尝试设置docker run--memory
的参数,然后检查您的
/sys/fs/cgroup/memory/docker//memory.usage(以字节为单位)
应该是对的
--memory
或-m
描述如下:
-m
,-memory=”“
-内存限制(格式:[]
)。数字是一个正整数。单位可以是b
、k
、m
或g
中的一种。最小值为4M
现在如何避免不必要的内存消耗。正如您所发布的,在PHP中取消文件链接并不需要立即删除内存缓存。相反,在特权模式下运行Docker容器(使用--privileged
标志),然后可以周期性地调用echo 3>/proc/sys/vm/drop_caches
或sync&&sysctl-w vm.drop_caches=3
以清除内存页面缓存
作为奖励,使用
fopen('php://temp“,“w+”)
将文件临时存储在内存中可以避免整个问题。Alex提到的问题解释了容器内的free-m
和主机中的docker stats
之间的内存使用差异。后者包括缓冲区/缓存
在PHP中取消文件链接并不需要立即删除内存缓存
相反,在特权模式下运行Docker容器时,我可以周期性地调用
echo3>/proc/sys/vm/drop\u caches来清除内存页面缓存。内存被进程和内核使用。如果不是PHP,请使用所有内存查找进程。感谢您的回答和参考!这就解释了内存使用的差异。不幸的是,在这种情况下,cgroup是最敏感的。PHP脚本中的文件操作增加了缓冲区/缓存,容器无法释放它。只有主机可以调用echo3>/proc/sys/vm/drop\u缓存
。您知道从容器访问文件系统时如何避免OOM吗?那么,为什么fopen('php://temp“,“w+”)
工作起来很有魅力,但是fopen(“/tmp/”.$i,“w+”)
不能释放内存吗?原因是什么@mpskovvang@AlexKarshin@Q-bart您可以在文档中阅读:php://temp 一旦存储的数据量达到预定义的限制(默认值为2 MB),将使用临时文件。
。收到了,谢谢。实际上,我还有一个小问题:docker容器不能从将大量数据写入文件(logger)的进程中释放内存,所以我很感兴趣的是为什么它是可能的,以及如何在我的电脑中修复它case@Q-巴特:你应该单独提出一个问题,然后我是否应该将你的答案合并到我的答案中,形成一个综合完整的答案?是的,如果有一个详细完整的答案,那就太好了。我还发现了一个更漂亮的命令sync&&sysctl-wvm.drop\u caches=3
。作为奖励信息,我发现使用fopen('php://temp“,”w+”)
将文件临时存储在内存中可以避免整个问题。没有未刷新的记忆挂起。我编辑了我的答案。如果我遗漏了什么,请随意编辑
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
ccc19719078f php-apache 0.00% 222.1MiB / 3.837GiB 5.65% 1.21kB / 0B 1.02MB / 4.1kB 7