У меня есть запланированная задача, которая запускает скрипт на регулярной основе (каждый час). Этот скрипт выполняет некоторое интенсивное взаимодействие с базой данных и файловой системой и регулярно занимает несколько минут. Проблема заключается в том, что при использовании сценария в процессоре процессор работает и замедляет нормальные операции. Есть ли способ дросселировать этот процесс, чтобы он занимал больше времени, но не потребляет столько ресурсов?
Я просмотрел разные параметры конфигурации для PHP, но, похоже, не все, что соответствует моим потребностям.
Установка memory_limit в php.ini на что-то меньшее приводит к тому, что объекты данных переполняются довольно легко.
Я видел похожие сообщения, в которых люди предлагали использовать sleep () в определенных точках скрипта, но это не мешает скрипту отрываться от сервера.
Оптимальным решением было бы каким-то образом рассказать стеклам Lamp (в данном случае Wamp) использовать только 10% максимального использования процессора. Я вообще не беспокоюсь о времени выполнения и предпочел бы, чтобы это заняло больше времени, если это означает экономию циклов процессора в секунду. Моим альтернативным решением было бы настроить другой сервер с репликацией базы данных, чтобы cron мог отправиться в город, не замедляя все остальное.
Окружающая среда: Windows Server 2k3, Apache 2.2.11, PHP 5.2.9, MySQL 5.1
Я ценю любое понимание этой ситуации.
EDIT: Я ценю все ответы, даже те, которые являются * nix-specific. В моей ситуации еще довольно рано менять среду хостинга. Надеюсь, этот вопрос поможет другим, независимо от ОС.
Это сложная проблема. Если вы используете PHP-скрипт через командную строку, вы можете установить приоритет планирования процесса на низкий ( start /low php.exe myscript.php
я считаю). Если ваш скрипт PHP фактически выполняет большую часть обработки, которая потребляет ваш процессор, это может сработать. Тем не менее, вы сказали, что выполняете очень сложное взаимодействие с базой данных и файловой системой, что не поможет этому решению. Похоже, есть подсказка MySQL «LOW_PRIORITY» для запросов INSERT и UPDATE, которые могут вам помочь, но я не пробовал их.
Вы можете настроить процессы в Windows на более низкий приоритет. Я не уверен, как этот процесс запускается, но если вы настроите процесс на низкий приоритет, все, что захочет, ресурсы ЦП получат их, если вы установите приоритет на действительно низкий уровень.
В UNIX (LAMP) мне удалось решить проблему, проверив загрузку сервера, прежде чем продолжить цикл
function get_server_load($windows = 0) { $os = strtolower(PHP_OS); if(strpos($os, "win") === false) { if(file_exists("/proc/loadavg")) { $load = file_get_contents("/proc/loadavg"); $load = explode(' ', $load); return $load; } elseif(function_exists("shell_exec")) { $load = explode(' ', `uptime`); return $load; } else { return ""; } } } for(... ... ...){ $data = get_server_load(); if($data[0] < 0.2){ // continue }else{ sleep(1); } }
Эта функция должна работать и на окнах, но я не могу этого гарантировать. В linux он возвращает вам массив с нагрузкой последней минуты, 5 минут и 15 минут
Кроме того, рассмотрите возможность запуска ваших сценариев (если с помощью CLI) с более низким приоритетом (в Linux используйте «nice»)
Вы также можете использовать другие значения перед продолжением цикла, например, количество активных процессов Apache (вы можете проанализировать страницу 127.0.0.1/server_status?auto, если вы включили mod_status в httpd.conf), а также ситуацию в MySQL (активные соединения ?)
Можете ли вы изменить свою запись cron, чтобы запустить скрипт с помощью nice ?
Не рекомендуется использовать сервер для обслуживания клиентов и анализа данных.
Поэтому, если вы ищете окончательное решение, сделайте несколько редизайнов своего приложения и выгрузите анализ данных из интерфейсов и живой базы данных в другую систему, предназначенную для этой задачи.
Даже если вы можете успешно сжать анализатор, он будет использовать драгоценные ресурсы, иначе они будут доступны для обслуживания пользователей.
Это может быть трудное изменение, но может стоить рефакторинга ваших структур данных в итераторах. Кроме того, если у вас есть циклические ссылки в вашем коде, укажите метод clearReferences (), который отключает эти объекты. Это проблема, которая решается в PHP 5.3.
Поэтому, если у вас есть:
class Row { protected $_table; public function __construct($table) { $this->_table = $table; } } class Table { protected $_row; public function __construct() { $this->_row = new Row($this); } }
Добавьте метод clearReferences () в класс Row:
class Row { public function clearReferences() { $this->_table = null; } }
Это все, что я могу придумать на данный момент.
У меня есть куча скриптов, которые я запускаю из cron аналогичным образом, используя nice:
0 * * * * nice -n19 php myscript.php
Это не поможет использованию ОЗУ (только изменение способа написания сценария может сделать это), но он использует только процессор, который в противном случае был бы бездействующим.
EDIT: не видел, что вопрос связан с средой Windows, извините … оставив это для любых пользователей * nix, имеющих такую же проблему.
Возможно, ваш сценарий просто пытается сделать слишком много всего сразу. Будет ли это делать меньше, если он будет работать три раза в час?
Другим решением может быть установка дополнительного сервера только для запуска такой обработки «бэкэнд». Это было бы особенно эффективно, если бы оно не помещало чрезмерную нагрузку в базу данных, а именно на веб-сервер.
Еще один подход к рассмотрению заключается в том, можно ли разделить работу на другое направление. В подобных сценариях часто есть несколько больших операторов SQL, которые генерируют результаты, используемые для создания множества небольших операторов SQL. Если последний можно отложить где-то, их можно запустить с базой данных в качестве более позднего шага. Такой подход может также позволить вам использовать небуферизованный запрос для извлечения данных предварительной обработки, которые могут значительно сократить потребление памяти кодом PHP.
Если у вас есть (Apache), работающий как служба, вы можете изменить настройки приоритета в центре управления Win / services. В любом случае ваше использование ЦП будет шипами, но другие программы будут предпочтительнее планировщика. Также попробуйте поставить базу данных / сервер на другой hd, чем ваши Приложения.