2 votes

L'exécution de plusieurs CLI PHP en arrière-plan provoque des erreurs MySQL

Nous utilisons un métamoteur de recherche (comparaison de prix) où chaque recherche engendre un certain nombre de recherches en temps réel sur différents sites web et présente les résultats de recherche fusionnés et triés sur notre site.

Nous utilisons PHP/MySQL/Apache sur un serveur Linux Debian dans une configuration assez simple, mais le traitement de fond de la recherche de plusieurs sites en parallèle est géré par Tomcat et un servlet Java. Cependant, en raison de certains problèmes avec cette configuration (Tomcat), je cherche de nouvelles approches pour la recherche en arrière-plan.

Une méthode qui semble prometteuse est également très simple : À partir de la page de recherche principale, chaque script de recherche individuelle est exécuté en tant que CLI PHP en utilisant exec() :

exec("nohup /usr/bin/php search.php '$params' &> /dev/null &");

L'utilisation de l'esperluette à la fin envoie le CLI PHP scripts directement en arrière-plan et la page principale peut continuer sans attendre. Il y a environ 20 scripts en cours d'exécution pour chaque recherche.

Il semble fonctionner assez bien, mais lorsque j'exécute un test de stress à l'aide d'Apache Benchmark avec des requêtes simultanées, des problèmes commencent à apparaître. Ce qui se passe, c'est que MySQL signale cette erreur :

Impossible de se connecter au serveur MySQL local via le socket '/var/run/mysqld/mysqld.sock' (11)

Il semble qu'il s'agisse d'une variante de "Too many connections" (trop de connexions), mais cela ne sert à rien d'augmenter les limites dans my.cnf. Mais ce qui me rend vraiment perplexe, c'est que ces erreurs sont présentes même si j'appelle un petit script factice qui ne fait rien, et certainement pas d'accès à MySQL. Ainsi, il semble que le simple fait d'exécuter PHP CLI charge MySQL même s'il n'est pas utilisé.

Il y a tout au plus environ 700 instances de PHP en cours d'exécution pendant mes tests, et la charge du processeur et de la mémoire est plus faible que lorsque j'utilise Tomcat pour appeler les scripts de PHP, donc de ce point de vue, cela semble faisable.

Quelqu'un a-t-il une idée du problème MySQL ? Et bien sûr, je suis ouvert à de nouvelles idées sur la façon de gérer les tâches de fond !

Regards, Martin

2voto

Scott Lundberg Points 2354

Martin,

Je ne suis certainement pas un expert en la matière, mais quelques éléments me viennent à l'esprit.

Je pense que php charge le support pour mysql que vous l'utilisiez ou non dans votre script, mais il ne devrait pas démarrer une connexion à moins que vous utilisiez Connexions persistantes Je ne pensais pas que la cli scripts hériterait de la connexion mysql de l'enfant Apache, mais apparemment c'est le cas d'après vos tests.

Vous pouvez également vous heurter à trop de fichiers limite sur mysql. Il est également fait référence au fait que le manque de RAM/ressources est une cause de l'erreur mysql. Vous avez dit qu'il montre moins de charge que votre ancienne configuration, mais pourrait-il être trop ? Lorsque ces scripts sont en cours d'exécution, est-il possible de lancer une connexion au serveur mysql en utilisant l'interface graphique (administrateur mysql) ? Si oui, vous pourriez potentiellement le voir manquer de ressources....

Il serait peut-être plus efficace, du point de vue de la base de données, que vos 20 recherches ne se trouvent que dans un seul script, plutôt que d'engendrer plusieurs script. Cela vous permettrait d'utiliser une seule connexion mysql pour les 20 recherches et devrait augmenter votre capacité de connexion en conséquence. En d'autres termes, Web script ---- spawns -----> CLI script en arrière-plan qui boucle à travers toutes vos recherches.
Ne connaissant pas votre code, ou ce que vous faites exactement, c'est juste une supposition comme solution de codage.

Bonne chance

2voto

Bill Points 1408

Je dirais que la création d'emplois est un peu trop simple, et certainement ouverte à une situation de manque de ressources.

Pour éviter cela, j'utiliserais une forme de file d'attente - soit par le biais d'une table de base de données qui liste ce qui est requis, et qui est ensuite vérifiée régulièrement, soit par un système de file d'attente de tâches, quelque chose comme Gearman ou Beanstalkd. Vous placez un message dans la file d'attente - ce que vous voulez rechercher - et une tâche d'arrière-plan, qui est déjà en cours d'exécution, qui récupère les travaux au fur et à mesure qu'ils arrivent et qui en a la capacité, effectue les tâches appropriées et renvoie les informations, soit via la base de données, soit via un système en mémoire comme Memcached. Le système frontal peut rafraîchir (ou utiliser Ajax) pour rappeler et voir si des informations ont été trouvées, et les afficher si nécessaire.

Cela sépare le front-end et le back-end, et évite d'avoir à fermer toutes les connexions que votre script a ouvertes (voir l'avertissement sur exec )

0voto

codified Points 462

Désolé pour la réponse tardive. J'ai eu la grippe.

Merci pour vos commentaires. Il y a beaucoup de choses à penser !

J'ai fait quelques expériences supplémentaires en appelant les scripts avec wget plutôt que comme CLI scripts, et de plus en ayant Lighttpd servant ces scripts de recherche spéciale sur le port 81 - pour garder la charge sur le serveur principal Apache.

Pour l'instant, cela semble prometteur, mais je poserai peut-être à nouveau la question lorsque j'aurai effectué un peu plus de tests.

Edit : Je suis le poster original, je ne sais pas pourquoi cela ressemble au post de quelqu'un d'autre. Peut-être quelque chose avec mon OpenID...

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X