【发布时间】:2014-02-16 16:31:48
【问题描述】:
我试图找出一种情况,即 PHP 没有消耗大量内存,而是导致 Committed_AS 结果非常高。
以这个 munin 内存报告为例:
一旦我启动了我们的 Laravel 队列(10 ~ 30 个工作人员),已提交的内存就会激增。我们在这个 vps 实例上有 2G 内存 + 2G 交换,到目前为止大约有 600M 未使用的内存(大约 30% 可用)。
如果我 understand Committed_AS 正确,这意味着 99.9% 保证在当前工作负载下不会出现 out of memory 问题,这似乎表明我们需要将 vps 内存增加三倍以确保安全。
我尝试将队列数量从 30 个减少到 10 个左右,但正如您所见,绿线相当高。
至于设置:启用 PHP 5.5 opcache 的 Laravel 4.1。我们使用 spawn 实例的 upstart 脚本如下:
instance $N
exec start-stop-daemon --start --make-pidfile --pidfile /var/run/laravel_queue.$N.pid --chuid $USER --chdir $HOME --exec /usr/bin/php artisan queue:listen -- --queue=$N --timeout=60 --delay=120 --sleep=30 --memory=32 --tries=3 >> /var/log/laravel_queue.$N.log 2>&1
我看到很多情况下,高交换使用意味着内存不足,但我们的交换使用低,所以我不确定这里的故障排除步骤是合适的。
PS:在 Laravel 4.1 和我们的 vps 升级之前我们没有这个问题,这里有一张图片来证明这一点。
也许我应该将我的问题改写为:如何准确计算 Committed_AS 以及 PHP 是如何影响它的?
2014.1.29 更新:
我对这个问题有一个理论:由于 laravel 队列工作者在等待队列中的新作业时实际上使用 PHP sleep()(在我的情况下为 beanstalkd),这表明高 Committed_AS 估计是由于相对较低的工作量和相对较高的内存消耗。
在我看来 Committed_AS ~= avg. memory usage / avg. workload 是有道理的。正确地使用 PHP sleep(),几乎没有使用 CPU;但是它消耗的任何内存仍然是保留的。这导致服务器思考:嘿,即使负载最小(平均),您也使用了这么多内存(平均),您应该为更高的负载做好更好的准备(但在这种情况下,不会导致更高的负载内存占用更高)
如果有人想测试这个理论,我很乐意将赏金奖励给他们。
【问题讨论】:
-
您可能对this talk from last year's PHP UK conference 感兴趣,它解释了 PHP 中如何管理内存的某些部分。
-
@IMSoP 这是一个很棒的演讲,但它并没有真正为我指明正确的方向,因为我已经在使用一个沉重的 php 框架,并且需要弄清楚它为什么会导致高 Committed_AS 而不是内存交换时耗尽或更多 i/o。
-
是的,我只是想它可能会给你或某人一些有用的背景来解释手头的具体情况。我自己在内存管理或 Laravel 方面都不足以诊断具体情况。
-
对我来说非常有趣的问题,因为我最近遇到了非常相似的问题,但是使用 PHP 5.3 和自制框架,到目前为止没有任何解释。您的图表表明您已将 RAM 从 1GB 升级到 2GB,但是您的交换分区的大小是多少?
-
@SirDarius 2GB 交换。如果使用交换,它将在图表上显示为红色。
标签: php ubuntu memory-management laravel munin