增加 PHP memory_limit.什么时候会变得疯狂?

2021-12-21 00:00:00 memory php scalability

在我目前正在研究的系统中,有一个进程将大量数据加载到数组中以进行排序/聚合/任何操作.我知道这个过程需要优化内存使用,但在短期内它只需要工作.

In a system I am currently working on, there is one process that loads large amount of data into an array for sorting/aggregating/whatever. I know this process needs optimising for memory usage, but in the short term it just needs to work.

鉴于加载到数组中的数据量,我们不断达到内存限制.它已经增加了好几倍,我想知道是否有一点增加它通常会变成一个坏主意?还是仅是机器有多少内存的问题?

Given the amount of data loaded into the array, we keep hitting the memory limit. It has been increased several times, and I am wondering is there a point where increasing it becomes generally a bad idea? or is it only a matter of how much RAM the machine has?

机器有 2GB 的 RAM,memory_limit 目前设置为 1.5GB.我们可以轻松地为机器添加更多 RAM(无论如何都会这样做).

The machine has 2GB of RAM and the memory_limit is currently set at 1.5GB. We can easily add more RAM to the machine (and will anyway).

其他人遇到过这种问题吗?以及解决方案是什么?

Have others encountered this kind of issue? and what were the solutions?

推荐答案

PHP 作为 Apache 模块运行到服务器网页的 memory_limit 配置必须考虑到您可以有多少 Apache 进程同时在机器上 - 请参阅 Apache 的 MaxClients 配置选项.

The configuration for the memory_limit of PHP running as an Apache module to server webpages has to take into consideration how many Apache process you can have at the same time on the machine -- see the MaxClients configuration option for Apache.

如果 MaxClients 是 100 并且您有 2,000 MB 的 RAM,一个非常快速的计算将表明您不应使用超过 20 MB *(因为 20 MB * 100 个客户端 = 2 GB 或 RAM,即您的服务器拥有的总内存量)* 用于 memory_limit 值.

If MaxClients is 100 and you have 2,000 MB of RAM, a very quick calculation will show that you should not use more than 20 MB *(because 20 MB * 100 clients = 2 GB or RAM, ie the total amount of memory your server has)* for the memory_limit value.

这还没有考虑到可能在同一台服务器上运行其他东西,比如 MySQL、系统本身,......而且 Apache 可能已经在为自己使用一些内存.

And this is without considering that there are probably other things running on the same server, like MySQL, the system itself, ... And that Apache is probably already using some memory for itself.

当然,这也是一个最坏情况",即考虑到每个 PHP 页面都在使用它可以使用的最大内存量.

Or course, this is also a "worst case scenario", that considers that each PHP page is using the maximum amount of memory it can.


在您的情况下,如果您只需要为一项工作提供如此大的内存,我不会为作为 Apache 模块运行的 PḦP 增加 memory_limit.

相反,我会从命令行(或通过 cron 作业) 启动该作业,并在这种且唯一的情况下指定更高的 memory_limit.

Instead, I would launch that job from command-line (or via a cron job), and specify a higher memory_limit specificaly in this one and only case.

这可以通过 php 的 -d 选项来完成,例如:

This can be done with the -d option of php, like :

$ php -d memory_limit=1GB temp.php
string(3) "1GB"

考虑到在这种情况下,temp.php 仅包含:

Considering, in this case, that temp.php only contains :

var_dump(ini_get('memory_limit'));

在我看来,这比为 Apache 增加 PHP 模块的 memory_limit 更安全 -- 当我有一个大型数据集或一些我无法优化或分页的非常重的东西时,我通常会这样做.

In my opinion, this is way safer than increasing the memory_limit for the PHP module for Apache -- and it's what I usually do when I have a large dataset, or some really heavy stuff I cannot optimize or paginate.


如果您需要为 PHP CLI 执行定义多个值,您还可以通过 -c 选项告诉它使用另一个配置文件,而不是默认的 php.ini:


If you need to define several values for the PHP CLI execution, you can also tell it to use another configuration file, instead of the default php.ini, with the -c option :

php -c /etc/phpcli.ini temp.php

那样,你有:

  • /etc/php.ini for Apache,低memory_limit,低max_execution_time,...
  • /etc/phpcli.ini 用于从命令行运行的批处理,几乎没有限制
  • /etc/php.ini for Apache, with low memory_limit, low max_execution_time, ...
  • and /etc/phpcli.ini for batches run from command-line, with virtually no limit

这可确保您的批处理能够运行——并且您的网站仍然具有安全性(memory_limitmax_execution_time 是安全措施)

This ensures your batches will be able to run -- and you'll still have security for your website (memory_limit and max_execution_time being security measures)


尽管如此,如果您有时间优化您的脚本,您应该:例如,在您必须处理大量数据的情况下,分页是必不可少的 ;-)


Still, if you have the time to optimize your script, you should ; for instance, in that kind of situation where you have to deal with lots of data, pagination is a must-have ;-)

相关文章