mps*_*ang 4 php memory debian docker kubernetes
我有一个 PHP 守护进程脚本,用于下载远程图像并在上传到对象存储之前将它们临时存储在本地。
PHP 内部内存使用量保持稳定,但 Docker/Kubernetes 报告的内存使用量不断增加。
我不确定这是否与 PHP、Docker 或预期的 Linux 行为有关。
重现问题的示例:
码头工人形象: php:7.2.2-apache
<?php
for ($i = 0; $i < 100000; $i++) {
$fp = fopen('/tmp/' . $i, 'w+');
fclose($fp);
unlink('/tmp/' . $i);
unset($fp);
}
Run Code Online (Sandbox Code Playgroud)
free -m
在执行上述脚本之前调用容器内部:
total used free shared buff/cache available
Mem: 3929 2276 139 38 1513 1311
Swap: 1023 167 856
Run Code Online (Sandbox Code Playgroud)
并在执行脚本后:
total used free shared buff/cache available
Mem: 3929 2277 155 38 1496 1310
Swap: 1023 167 856
Run Code Online (Sandbox Code Playgroud)
显然内存已释放,但从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
Run Code Online (Sandbox Code Playgroud)
报告的初始内存使用量docker stats php-apache
为 16.04MiB。
解释是什么?如何释放内存?
在具有资源限制的 Kubernetes 集群中运行此容器会导致 pod 失败并反复重启。
是的,这里已经报告了类似的问题。
这是贡献者之一的coolljt0725的答案,回答为什么输出中的RES
列top
显示不同的内容,而不是docker stats
(我将按原样引用他):
如果我理解正确的话,docker stats 中的内存使用量是从容器的内存 cgroup 中读取的,您可以看到该值与您从 cat /sys/fs/cgroup/memory/docker/665e99f8b760c0300f10d3d9b35b1a5e7b1dc08c8c08c08c08c08c08c08c08c08c08c08c08c8c08c8c8c88c88c88c88c888c888c88c888888878c88c88c888888878c8c8c8c888888888c8c88cgroupe5c80720cgroup 中读取的值与 490270720 相同。 ,并且该限制也是创建容器时由 -m 设置的内存 cgroup 限制。RES和内存cgroup的统计数据不同,RES不考虑caches,但是内存cgroup会,这就是为什么docker stats中的MEM USAGE比top中的RES多很多
用户在此处建议的内容实际上可能会帮助您查看实际内存消耗:
尝试设置
docker run --memory
?的参数,然后检查您的/sys/fs/cgroup/memory/docker/<container_id>/memory.usage_in_bytes
它应该是正确的。
--memory
或在此处-m
描述:
-m
,--memory=""
- 内存限制(格式:)<number>[<unit>]
。数字是一个正整数。单位可以是一个b
,k
,m
,或g
。最小值是4M
。
现在如何避免不必要的内存消耗。正如您发布的那样,在 PHP 中取消链接文件不需要立即删除内存缓存。相反,以特权模式(带有--privileged
标志)运行 Docker 容器,然后可以调用echo 3 > /proc/sys/vm/drop_caches
或sync && sysctl -w vm.drop_caches=3
定期清除内存页面缓存。
作为奖励,fopen('php://temp', 'w+')
在内存中临时使用和存储文件可以避免整个问题。