33 votes

Cronjobs lents sur Cent OS 5

J'ai un cronjob qui s'exécute toutes les 60 minutes mais pour une raison quelconque, récemment, il est lent.

Env : centos5 + apache2 + mysql5.5 + php 5.3.3 / raid 10/10k HDD / 16gig ram / 4 xeon processor

Voici ce que fait le cronjob :

  1. analyser les données des 60 dernières minutes

    a) 1 processus analyse l'agent utilisateur et sauvegarde les données dans la base de données.

    b) 1 processus analyse les impressions/clics sur le site web et les enregistre dans la base de données

  2. à partir des données de l'étape 1

    a) créer un petit rapport et envoyer des courriels à l'administrateur/à l'entreprise

    b) enregistrer le rapport dans un tableau quotidien (disponible dans la section admin)

Je vois maintenant 8 processus (le même fichier) lorsque je lance la commande ps auxf | grep process_stats_hourly.php (j'ai trouvé cette commande dans stackoverflow)

Techniquement, je ne devrais en avoir qu'un, pas huit.

Y a-t-il un outil dans Cent OS ou quelque chose que je puisse faire pour m'assurer que mon cronjob s'exécute toutes les heures et ne chevauche pas le suivant ?

Merci

46voto

Book Of Zeus Points 38130

Votre matériel semble être assez bon pour traiter ça.

1) Vérifiez si vous avez déjà des processus suspendus. En utilisant le ps auxf (voir la réponse de tcurvelo), vérifiez si vous avez un ou plusieurs processus qui prennent trop de ressources. Peut-être n'avez-vous pas assez de ressources pour exécuter votre cronjob.

2) Vérifiez vos connexions réseau : Si vos bases de données et votre cronjob sont sur un serveur différent, vous devez vérifier le temps de réponse entre ces deux machines. Peut-être avez-vous des problèmes de réseau qui font que le cronjob attend que le réseau renvoie le paquet.

Vous pouvez utiliser : Netcat , Iperf , mtr o ttcp

3) Configuration du serveur Votre serveur est-il correctement configuré ? Votre OS, MySQL sont correctement configurés ? Je vous recommande de lire ces articles :

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) Vérifiez votre base de données : Assurez-vous que votre base de données possède les bons index et que vos requêtes sont optimisées. Lisez cet article sur le expliquer la commande

Si une requête avec quelques centaines de milliers d'enregistrements prend du temps à s'exécuter, cela affectera le reste de votre cronjob, si vous avez une requête dans une boucle, c'est encore pire.

Lisez ces articles :

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) Tracer et optimiser le code PHP ? Assurez-vous que votre code PHP s'exécute aussi rapidement que possible.

Lisez ces articles :

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

Une bonne technique pour valider votre cronjob est de tracer votre cronjob script : Sur la base du processus de votre cronjob, mettez une trace de débogage incluant combien de mémoire, combien de temps il a fallu pour exécuter le dernier processus. ex :

<?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";

En faisant cela, vous pouvez facilement trouver quel processus prend combien de mémoire et combien de temps il faut pour l'exécuter.

6) Appels de serveurs externes/services web Votre cronjob fait-il appel à des serveurs externes ou à des services web ? Si c'est le cas, assurez-vous que ceux-ci sont chargés aussi rapidement que possible. Si vous demandez des données à un serveur tiers et que ce serveur met quelques secondes à vous répondre, cela affectera la vitesse de votre cronjob, surtout si ces appels sont en boucle.

Essayez cela et faites-moi savoir ce que vous trouvez.

6voto

tcurvelo Points 1246

El ps La sortie de l'application indique également quand les processus ont démarré (voir la colonne 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]
                                                   ^^^^^^^
(...)

Ou vous pouvez personnaliser la sortie :

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

Ainsi, vous pouvez être sûr qu'ils se chevauchent.

4voto

Mike Purcell Points 12082

Vous devez utiliser un mécanisme de fichier de verrouillage dans votre script de process_stats_hourly.php. Cela n'a pas besoin d'être très complexe, vous pouvez demander à php d'écrire le PID qui a lancé le processus dans un fichier comme /var/mydir/process_stats_hourly.txt. Ainsi, si le traitement des statistiques prend plus d'une heure et que cron lance une autre instance du script process_stats_hourly.php script, il peut vérifier si le fichier de verrouillage existe déjà, sinon il ne sera pas exécuté.

Cependant, il vous reste le problème de savoir comment "remettre en file d'attente" le script horaire s'il a trouvé le fichier de verrouillage et n'a pas pu démarrer.

2voto

Basile Starynkevitch Points 67055

Vous pouvez utiliser strace -p 1234 où 1234 est un identifiant de processus pertinent, sur l'un des processus qui s'exécute trop longtemps. Vous comprendrez peut-être pourquoi il est si lent, voire bloqué.

2voto

pilcrow Points 20628

Y a-t-il un outil dans Cent OS ou quelque chose que je puisse faire pour m'assurer que mon cronjob s'exécute toutes les heures et ne chevauche pas le suivant ?

Oui. La version standard de CentOS util-linux fournit une commodité en ligne de commande pour le verrouillage du système de fichiers. Comme Digital Precision Proposition de un fichier de verrouillage est un moyen simple de synchroniser les processus.

Essayez d'invoquer votre cronjob comme suit :

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

Vous devrez modifier les chemins et ajuster $PATH en conséquence. Cette invocation tentera de verrouiller stats.lock En cas de succès, vous lancez votre script de statistiques, sinon vous abandonnez et enregistrez l'échec.

Alternativement, votre script pourrait appeler la fonction PHP flock() pour obtenir le même effet, mais le flock(1) l'utilité est déjà là pour vous.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X