【问题标题】:PHP 5.5, under what circumstances will PHP cause very high committed memoryPHP 5.5,什么情况下PHP会导致很高的committed memory
【发布时间】: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


【解决方案1】:

关于 Committed_AS,您需要了解两件事,

  1. 这是一个估计
  2. 它暗示了在最坏的情况下您需要多少内存(加上交换)。这取决于您当时的服务器工作量。如果您的工作量较低,则 Committed_AS 将较低,反之亦然。

如果这不是框架队列的先前迭代的问题并且假设您没有将任何新的代码更改推送到生产环境,那么您将需要比较两个迭代。也许启动另一个盒子并运行一些测试。您还可以使用 xdebug 或 zend_debugger 分析应用程序,以发现代码本身可能的因果因素。另一个有用的工具是 strace。

一切顺利,您将需要它!

【讨论】:

    【解决方案2】:

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

    事实证明,设置opcache.memory_consumption = 256 会导致每个 PHP 进程保留更多的虚拟内存(可以在top 命令的 VIRT 列中看到),从而导致 Munin 估计潜在的已提交内存要高得多。

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

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

    【讨论】:

    【解决方案3】:

    Committed_AS 是内核实际承诺处理的实际大小。而queues独立运行,与PHPLaravel.无关。除了Rijndael说的,我推荐安装New Relic,可以用来排查问题。

    提示:我注意到 NginX-HHVM 组合极大地减少了服务器负载。试试看吧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-23
      • 2011-12-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多