Увеличение PHP memory_limit. В какой момент это становится безумным? - PullRequest
38 голосов
/ 15 сентября 2009

В системе, над которой я сейчас работаю, есть один процесс, который загружает большой массив данных в массив для сортировки / агрегирования / чего угодно. Я знаю, что этот процесс нуждается в оптимизации для использования памяти, но в краткосрочной перспективе он просто должен работать.

Учитывая объем данных, загружаемых в массив, мы продолжаем превышать лимит памяти. Он был увеличен в несколько раз, и мне интересно, есть ли момент, когда его увеличение становится вообще плохой идеей? или это только вопрос того, сколько оперативной памяти у машины?

Машина имеет 2 ГБ оперативной памяти, а memory_limit в настоящее время установлено на 1,5 ГБ. Мы можем легко добавить больше оперативной памяти к машине (и все равно).

Встречались ли другие с такой проблемой? и какие были решения?

Ответы [ 3 ]

55 голосов
/ 15 сентября 2009

Конфигурация для memory_limit PHP, работающего как модуль Apache для веб-страниц сервера, должна учитывать, сколько процессов Apache вы можете одновременно иметь на компьютере - см. Параметр конфигурации MaxClients для Apache. .

Если MaxClients равно 100, а у вас 2000 МБ или ОЗУ, очень быстрое вычисление покажет, что вам не следует использовать более 20 МБ * (потому что 20 МБ * 100 клиентов = 2 ГБ или ОЗУ, т.е. общий объем памяти вашего сервера) * для значения memory_limit.

И это без учета того, что, вероятно, на том же сервере выполняются другие вещи, такие как MySQL, сама система ... И, возможно, Apache уже использует некоторую память для себя.

Или, конечно, это также «наихудший сценарий», который учитывает, что каждая страница PHP использует максимально возможный объем памяти.


В вашем случае, если вам нужен такой большой объем памяти только для одной работы, я бы не стал увеличивать memory_limit для PḦP, работающего как модуль Apache.

Вместо этого я запускаю это задание из командной строки (или через задание cron) и указываю более высокое значение memory_limit в этом единственном случае.

Это можно сделать с помощью опции -d в php, например:

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

Учитывая, что в этом случае этот файл temp.php содержит только:

var_dump(ini_get('memory_limit'));

На мой взгляд, это намного безопаснее, чем увеличение memory_limit для модуля PHP для Apache - и это то, что я обычно делаю, когда у меня большой набор данных, или некоторые действительно тяжелые вещи, которые я не могу оптимизировать или разбить на страницы.


Если вам нужно определить несколько значений для выполнения PHP CLI, вы также можете указать ему использовать другой файл конфигурации, вместо php.ini по умолчанию, с опцией -c:

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

Таким образом, у вас есть:

  • /etc/php.ini для Apache, с низким memory_limit, низким max_execution_time, ...
  • и /etc/phpcli.ini для пакетов, запускаемых из командной строки, практически без ограничений

Это гарантирует, что ваши пакеты будут в состоянии работать - и вы по-прежнему будете иметь безопасность для вашего сайта (memory_limit и max_execution_time - меры безопасности)


Тем не менее, если у вас есть время, чтобы оптимизировать ваш скрипт, вы должны; например, в такой ситуации, когда вам приходится иметь дело с большим количеством данных, нумерация страниц обязательна; -)

2 голосов
/ 15 сентября 2009

Вы пытались разбить набор данных на более мелкие части и обрабатывать только одну часть за один раз?

Если вы извлекаете данные из файла на диске, вы можете использовать функцию fread() для загрузки более мелких фрагментов или какой-то запрос небуферизованного дБ в случае базы данных.

Я не проверял PHP с v3.something, но вы также можете использовать форму облачных вычислений. Набор данных объемом 1 ГБ кажется достаточно большим для обработки на нескольких компьютерах.

1 голос
/ 15 сентября 2009

Если вы знаете, что в вашем скрипте есть проблемы с памятью, которые необходимо исправить, и вы ищете только краткосрочные решения, то я не буду описывать способы профилирования и решения ваших проблем проблемы с памятью. Похоже, ты доберешься до этого.

Итак, я бы сказал, что вы должны иметь в виду:

  • Общая загрузка памяти в системе
  • Возможности ОС

PHP - это только один маленький компонент системы. Если вы позволите ему поглотить огромное количество оперативной памяти, пострадают другие процессы, что, в свою очередь, может повлиять на сам скрипт. В частности, если вы извлекаете много данных из базы данных, вашей СУБД может потребоваться много памяти для создания наборов результатов для ваших запросов. В качестве быстрого решения вы можете определить любые запросы, которые вы выполняете, и освободить результаты как можно скорее, чтобы освободить себе память для длительного выполнения задания.

Что касается возможностей ОС, вам следует помнить, что 32-разрядные системы, на которых вы, вероятно, работаете, могут обрабатывать до 4 ГБ ОЗУ без специальной обработки. Часто предел может быть намного меньше в зависимости от того, как он используется. Некоторые наборы микросхем и конфигурации Windows могут фактически иметь доступ к системе менее 3 ГБ, даже если физически установлено 4 ГБ или более. Вы должны проверить, сколько может адресовать ваша система.

Вы говорите, что увеличили лимит памяти в несколько раз, поэтому очевидно, что эта работа становится все больше и больше по объему. Если у вас до 1,5 ГБ, то даже установка 2 ГБ ОЗУ звучит так, как будто это будет короткая передышка.

Встречались ли другие с таким вопрос? и какие были решения?

Я думаю, вы, наверное, уже знаете, что единственное реальное решение - это сломать и потратить время на оптимизацию сценария в ближайшее время, или вы в конечном итоге получите работу, которая будет слишком большой для запуска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...