Медленная работа на Cent OS 5 - PullRequest
33 голосов
/ 25 октября 2011

У меня есть 1 cronjob, который запускается каждые 60 минут, но по какой-то причине в последнее время он работает медленно.

Env: centos5 + apache2 + mysql5.5 + php 5.3.3 / raid 10 / 10k HDD/ 16gig ram / 4 xeon процессор

Вот что делает cronjob:

  1. анализ данных за последние 60 минут

    a) 1 пользовательский агент анализа процессаи сохранить данные в базе данных

    б) 1 процесс, проанализировать показы / клики на сайте и сохранить их в базе данных

  2. из данных на шаге 1

    а) создать небольшой отчет и отправить электронное письмо администратору / бизнесу

    б) сохранить отчет в ежедневной таблице (доступно в разделе администратора)

Теперь я вижу 8 процессов (тот же файл), когда я запускаю команду ps auxf | grep process_stats_hourly.php (обнаружил эту команду в stackoverflow)

Технически у меня должен быть только 1, а не 8.

Есть лилюбой инструмент в Cent OS или что-то, что я могу сделать, чтобы мой cronjob работал каждый час и не перекрывался.он следующий?

Спасибо

Ответы [ 7 ]

46 голосов
/ 29 октября 2011

Похоже, ваше оборудование достаточно для его обработки.

1) Проверьте, есть ли у вас процессы зависания. Используя ps auxf (см. Ответ tcurvelo), проверьте, есть ли у вас один или несколько процессов, которые занимают слишком много ресурсов. Может быть, у вас недостаточно ресурсов для запуска cronjob.

2) Проверьте сетевые подключения: Если ваши базы данных и ваш cronjob находятся на разных серверах, вы должны проверить, каково время отклика между этими двумя машинами. Возможно, у вас есть проблемы с сетью, из-за которых cronjob ждет, пока сеть отправит пакет обратно.

Вы можете использовать: Netcat , Iperf , mtr или ttcp

3) Конфигурация сервера Ваш сервер настроен правильно? Ваша ОС, MySQL настроены правильно? Я бы порекомендовал прочитать эти статьи:

http://www3.wiredgorilla.com/content/view/220/53/

http://www.vr.org/knowledgebase/1002/Optimize-and-disable-default-CentOS-services.html

http://dev.mysql.com/doc/refman/5.1/en/starting-server.html

http://www.linux -mag.com / ID / 7473 /

4) Проверьте свою базу данных: Убедитесь, что ваша база данных имеет правильные индексы и убедитесь, что ваши запросы оптимизированы. Прочтите эту статью о объясните команду

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

Прочитайте эти статьи:

http://dev.mysql.com/doc/refman/5.0/en/optimization.html

http://20bits.com/articles/10-tips-for-optimizing-mysql-queries-that-dont-suck/

http://blog.fedecarg.com/2008/06/12/10-great-articles-for-optimizing-mysql-queries/

5) Трассировка и оптимизированный код PHP? Убедитесь, что ваш PHP-код работает как можно быстрее.

Прочитайте эти статьи:

http://phplens.com/lens/php-book/optimizing-debugging-php.php

http://code.google.com/speed/articles/optimizing-php.html

http://ilia.ws/archives/12-PHP-Optimization-Tricks.html

Хорошая техника для проверки вашего cronjob - это отслеживать ваш скрипт cronjob: Основываясь на вашем процессе cronjob, поместите некоторую трассировку отладки, включая количество памяти, сколько времени потребовалось для выполнения последнего процесса. например:

<?php

echo "\n-------------- DEBUG --------------\n";
echo "memory (start): " . memory_get_usage(TRUE) . "\n";

$startTime = microtime(TRUE);
// some process
$end = microtime(TRUE);

echo "\n-------------- DEBUG --------------\n";
echo "memory after some process: " . memory_get_usage(TRUE) . "\n";
echo "executed time: " . ($end-$start) . "\n";

Таким образом вы можете легко определить, какой процесс занимает сколько памяти и сколько времени требуется для его выполнения.

6) Внешние серверы / вызовы веб-сервисов Ваш cronjob вызывает внешние серверы или веб-сервис? если это так, убедитесь, что они загружены как можно быстрее. Если вы запрашиваете данные со стороннего сервера, и этот сервер занимает несколько секунд, чтобы вернуть ответ, который повлияет на скорость вашего cronjob, особенно если эти вызовы зациклены.

Попробуйте и дайте мне знать, что вы найдете.

6 голосов
/ 29 октября 2011

Вывод ps также показывает, когда процесс запущен (см. Столбец STARTED).

$ ps auxf
USER    PID  %CPU %MEM     VSZ    RSS   TTY  STAT  STARTED    TIME   COMMAND
root      2   0.0  0.0       0      0   ?    S     18:55      0:00   [ktrheadd]
                                                   ^^^^^^^
(...)

Или вы можете настроить вывод:

$ ps axfo start,command
STARTED   COMMAND
18:55     [ktrheadd]
(...)

Таким образом, вы можете быть уверены, что они перекрываются.

4 голосов
/ 29 октября 2011

Вы должны использовать механизм lockfile в вашем скрипте process_stats_hourly.php.Не должно быть ничего слишком сложного, вы можете заставить php записать PID, который запустил процесс, в файл типа /var/mydir/process_stats_hourly.txt.Поэтому, если обработка статистики занимает больше часа, а cron запускает другой экземпляр сценария process_stats_hourly.php, он может проверить, существует ли уже файл блокировки, если он не запустится.

Однако у вас остается проблема с тем, как «поставить в очередь» почасовой скрипт, если он действительно обнаружил файл блокировки и не смог запуститься.

2 голосов
/ 29 октября 2011

Есть ли какой-нибудь инструмент в Cent OS или что-то, что я могу сделать, чтобы мой cronjob работал каждый час и не перекрывал следующий?

Да. Стандартный пакет CentOS util-linux обеспечивает удобство командной строки для блокировки файловой системы. Как рекомендует Digital Precision , файл блокировки - это простой способ синхронизации процессов.

Попробуйте вызвать ваш cronjob следующим образом:

flock -n /var/tmp/stats.lock process_stats_hourly.php || logger -p cron.err 'Unable to lock stats.lock'

Вам нужно будет отредактировать пути и настроить для $ PATH в зависимости от ситуации. Этот вызов будет пытаться заблокировать stats.lock, вызывая ваш скрипт статистики в случае успеха, в противном случае отказываясь и регистрируя ошибку.

В качестве альтернативы ваш сценарий может вызвать сам PHP flock () для достижения того же эффекта, но утилита flock(1) уже готова для вас.

2 голосов
/ 29 октября 2011

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

0 голосов
/ 29 октября 2011

Как часто вращается этот файл журнала?

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

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

0 голосов
/ 27 октября 2011

Вы можете добавить шаг в cronjob, чтобы проверить вывод вышеприведенной команды:

ps auxf | grep process_stats_hourly.php

Продолжайте цикл до тех пор, пока команда ничего не вернет, указывая, что процесс невыполняется, затем разрешите выполнение оставшегося кода.

...