Forum Clubic

Php/mysql asynchrone

Salut à tous,

Depuis quelques jours je cherche un moyen simple de paralléliser des requêtes mysql, mais sans succès.
Je n’ai qu’une vague connaissance du fonctionnement exact de Mysql, et encore moins des protocoles tcp-ip ou autres…

J’aimerais déjà savoir s’il est techniquement possible d’effectuer en asynchrone des requêtes sur la même connexion sql.
Ensuite si la parallélisation des requêtes peut dans certains cas s’avérer plus lente qu’un regroupement en 1 seule requête.

Le but étant d’accélérer les traitement pouvant être faits uniquement sur une partie (ou une partition) d’une table.
(je n’ai pas d’exemple précis, c’est juste de la prospection)

(pour l’instant je n’ai trouvé que des témoignages de gros geek ayant modifé les drivers mysql pour faire de l’asynchrone :paf:)

ps: si vous avez d’autres méthodes pour optimiser les gros traitements (excepté les trucs qui se trouvent dans la doc mysql) je suis preneur :slight_smile:

Non, ca changerais quelque chose si tu avais plusieurs base de données sur les quelles repartir les requetes. Au niveau du serveur MySQL, il doit savoir géré ces multiples core si il en a sur une seule requete de toutes facon (je pense). Enfin si ca peut avancer à quelque chose les requete en // c’est uniquement dans le cas d’un multi-core, sinon ca sert à rien.
Edité le 19/08/2009 à 17:55

oui je voulais parler de multi-threading.
Et je ne pense pas qu’une unique requête soit “multi-threadée” car il n’y aurait pas assez de thread pour gérer simultanément des dixaines de requêtes (je pense).
Et dans tous les cas, il y aurait un avantage à // les requêtes : dès qu’un résultat est connu, on peut le traiter (sans attendre la totalité du résultat). Ca évite aussi que Mysql perde les pédales comme ça lui arrive quand y’a trop de données à gérer.
Edité le 20/08/2009 à 00:37

Toutes les exécutions de requetes SQL sont synchrones et mono thread (ce qui ne veut pas dire qu’il tourne sur un seul coeur d’un cpu multi coeur !!). Par contre, rien n’empeche d’exécuter plusieurs requetes en meme temps, notamment par le biais d’une pool de connexions PHP ouvertes sur MySql.

Ce que tu cherches, c’est plutot un batch multi thread. Si effectivement, ton traitement peut etre parallélisé (exemple : “pour chaque item, faire une mise à jour” devient alors “distribuer tous les items sur n thread, chacun fait une mise à jour”).

Pour la mise en oeuvre, je te déconseille fortement de recourrir à PHP pour faire ton batch : problèmes de timeout du serveur web et/ou d’appli, occupation des ressources du front end.
Edité le 20/08/2009 à 10:06

okay!

Oui ce serait surtout pour du batch (que je fait effectivement en php. C’est le problème d’avoir été formé sur le tas : je reprend les mauvaises habitudes de mes collègues :frowning: )
Donc déjà merci, je vais chercher dans ce sens.

Mais ce n’est pas uniquement pour du batch : j’ai déjà fait des modules de stats/CRM assez complexes qui auraient bien eu besoin d’une ptite parallélisation (ça m’aurai évité un algo toru^^)

Donc en php la seule solution est une “pool de connexions”?
Par contre je ne suis pas sûr de piger : la “pool” de connexions est gérée par mysql non? Comment je fait pour que mon script aie droit à plusieurs connexions? (car si j’ai bien compris, ce que tu propose c’est d’avoir plusieurs connexions?)

(en tt cas merci, tu m’as déjà donné de nouvelles pistes :slight_smile: )

Euh … ben là désolé je ne pourrai pas t’aider davantage sur le PHP :slight_smile:

Un pool de connexion, c’est un principe théorique selon lequel client (serveur php) et fournisseur (serveur mysql) se dédient mutuellement un ensemble de connexions ouvertes. Lorsque le client veut un service du fournisseur, il “emprunte” une connexion de la pool.

Concretement, sur les serveurs d’application Java J2EE, on n’associe en général une seule connexion à un thread.

Mais si on reprend ton exemple, le module de “stats / crm”. Comment qu’il marche du point de vue utilisateur ? En synchrone, en asynchrone ?

Une solution théorique pour faire un batch en PHP (ca vaut ce que ca vaut hein, j’ai pas fait de PHP depuis des lustres) :

  • quand tu cliques sur le bouton, ca va mettre à jour une valeur d’une table quelconque (ou autre si tu n’utilises pas de base de données)
  • de l’autre côté, tu as un programme qui va tourner en continu (un démon) et qui scrutera la valeur de cette table
  • de telle manière à pouvoir exécuter tes traitements en asynchrone et sans utiliser les resources de ton appli web, en multi thread, et tout et tout
    Via www.manuelphp.com…

Sur le principe, oui. Plusieurs threads pour plusieurs connexions.
Edité le 20/08/2009 à 14:27

c’est pas mal ton truc :slight_smile:

Le module stats/crm c’est un exemple à oublier. En fait je prospecte des solutions d’optimisations de structure de code que je pourrais appliquer dans l’avenir.

Plus précisément, je cherche à décharger apache en chargeant mysql, mais sans que mysql perde les pédales ou mette des plombes…
(et en restant dans une architecture facilement maintenable)

Du coup, tant que je te tiens : vue qu’on peut exécuter du shell en php, je pourrais appeler mon programme de batch (qui du coup n’en est plus vraiment un^^) dans un script php non? (comme ça c’est qd même du php qui “lance” le traitement. Je trouve ça plus simple pour la maintenance)

(ouai je suis en mode “flême de chercher des heure sur le web pour avoir la réponse”"^^)

Entre flemmards, jcomprends :slight_smile:

Si on peut exécuter du shell en PHP, ca ne veut pas dire que c’est une bonne pratique. Ceci dit, c’est effectivement une manière simple pour mettre en oeuvre un batch : il suffit que le shell fasse quelque chose comme :

. $WORKING_DIR/mon_super_shell.sh &

Et ca va exécuter le batch sans en attendre sa fin d’exécution. Et ca reste un batch.

Par contre, comment tu surveilles l’exécution du processus ? Par un autre batch ? :slight_smile:
C’est une solution qui n’est -à mon avis- pas industrialisable car elle engendrerait un cout d’exploitation / maintenance élevé (rien que le temps passé à savoir si le processus est dans les choux, et celui pour nettoyer les connexions laissées ouvertes etc).

Autre solution : ca existe en PHP un framework de planification de tâches ? Un peu comme Quartz en Java
www.opensymphony.com…

Edité le 20/08/2009 à 16:28

Mois je surveille po! je suis le roi du tombage de serveur :fou:
(d’ailleurs ça fait trop longtemps que j’ai pas fait le coup à un client… faudra que je programme ça :whistle: )

ouai bon, je vais revoir ma copie^^


des tâches genre CRON? Moi la dernière fois que j'ai voulu programmer CRON avec du PHP l'hébergeur m'a fusillé sur place^^ (de vagues raisons de sécurité qu'il parait :fou:) Edité le 20/08/2009 à 16:38

Euh … voui, sauf que CRON, c’est du genre tous les soirs à 23h. Là ca serait à la demande.

Mais bon, jsais pas si PHP propose ce genre de dispositif …

Si je devais imaginer une solution avec les moyens du bord, je dirais :

  • un démon composé d’un script shell qui va lancer deux programmes PHP : un qui vérifie si un traitement est demandé, un qui les exécutent dans un batch multi thread
  • un frontal qui ne fait que provoquer le déclenchement du démon

L’autre solution, c’est un contournement : chercher à réduire le temps d’exécution du bordel et laisser le fonctionnement en l’état.