PHP 5.5,在什么情况下PHP会导致非常高的提交内存

时间:2014-01-25 17:25:10

标签: php ubuntu memory-management laravel munin

我试图弄清楚PHP不会消耗大量内存但会导致Committed_AS结果非常高的情况。

以此munin记忆报告为例:

munin memory

一旦我启动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升级之前没有这个问题,这里有一张图片来证明这一点。

old munin memory

也许我应该将我的问题重新解释为:Committed_AS如何精确计算以及PHP如何计算它?


更新2014.1.29:

我有一个关于这个问题的理论:因为laravel队列工作者在等待队列中的新作业时实际上使用PHP sleep()(在我的情况下是beanstalkd),它会建议高Committed_AS估计是由于相对较低的工作量和相对较高的内存消耗。

这有意义,因为我看到Committed_AS〜= avg. memory usage / avg. workload。正确地使用PHP sleep(),几乎没有使用CPU;然而它所消耗的任何记忆仍然是保留的。这导致服务器思考:嘿,即使负载最小(平均),你也会使用如此多的内存(平均而言),你应该为更高的负载做好准备(但在这种情况下,不会导致更高的负载)在更高的内存占用率)

如果有人想测试这个理论,我很乐意将赏金给予他们。

3 个答案:

答案 0 :(得分:2)

您需要了解有关Committed_AS的两件事,

  1. 这是一个估计
  2. 它暗示了在最坏的情况下你需要多少内存(加上交换)。它取决于您当时的服务器工作负载。如果您的工作负载较低,则Committed_AS将更低,反之亦然。
  3. 如果这不是框架队列的先前迭代的问题,并且假设您没有将任何新的代码更改推送到生产环境,那么您将需要比较两次迭代。也许旋转另一个盒子并运行一些测试。您还可以使用xdebug或zend_debugger对应用程序进行概要分析,以发现代码本身可能存在的因果因素。另一个有用的工具是strace。

    一切顺利,你需要它!

答案 1 :(得分:1)

我最近发现了这个高承诺内存问题的根本原因: PHP 5.5 OPcache设置

结果放opcache.memory_consumption = 256导致每个PHP进程保留更多虚拟内存(可以在top命令的VIRT列中看到),从而导致Munin估计潜在的已提交内存很多更高。

我们在后台运行的laravel队列数量只会夸大问题。

通过将opcache.memory_consumption放到recommended 128 MB(我们实际上并没有有效地使用所有这256 MB),我们将估算值减少了一半,再加上我们服务器上最近的RAM升级,估计大约为3GB,更合理且在我们的总RAM限制内

答案 2 :(得分:0)

Committed_AS是内核实际承诺进程的实际大小。 queues独立运行且与PHPLaravel.无关除了Rijndael所说的内容,我建议安装New Relic,以便找出问题所在。

提示:我注意到NginX-HHVM组合的服务器负载大幅减少。试一试。