Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Paralleliser du code PHP

10 réponses
Avatar
Julien Arlandis
Bonjour,

Je suis dans une phase d'optimisation de mon site et je souhaite
paralléliser toutes les portions de code qui exécutent des requêtes sql
dont le résultat n'est pas nécessaire au déroulement du script
(insertion, suppression, mise à jour...).
Si une requête s'exécute en 2 ms ce sera toujours 2 ms de moins sur la
durée d'exécution totale du script php, la question c'est comment faire?

Pour l'affichage de mes vues j'utilise le moteur de template smarty et
j'ai remarqué que le simple chargement du module coute en moyenne 4 à 5
ms, ce module est appelé sur toutes les pages du site. Y aurait il un
moyen quelconque de le précharger dans php.ini d'une façon ou d'une
autre, vu que je déclare une instance de l'objet smarty y aurait peut
être un moyen de rendre cette instance persistante pour qu'elle soit
disponible à l'éxécution de chaque script?

10 réponses

Avatar
Mickael Wolff
Julien Arlandis a écrit :

Je suis dans une phase d'optimisation de mon site et je souhaite
paralléliser toutes les portions de code qui exécutent des requêtes sql
dont le résultat n'est pas nécessaire au déroulement du script
(insertion, suppression, mise à jour...).


Je ne vois pas quel est le but réel de l'opération. Si ton script est
destiné à créer une ressource, tu ne pourras différer l'appel à la base
de donnée, ça n'a pas vraiment de sens. Donnes-nous des cas plus concrets.

Si une requête s'exécute en 2 ms ce sera toujours 2 ms de moins sur la
durée d'exécution totale du script php, la question c'est comment faire?



Si pour économiser 2ms tu en dépense 2ms à chaque fois, il n'y a pas
d'intérêt.

Pour l'affichage de mes vues j'utilise le moteur de template smarty et
j'ai remarqué que le simple chargement du module coute en moyenne 4 à 5
ms, ce module est appelé sur toutes les pages du site. Y aurait il un
moyen quelconque de le précharger dans php.ini d'une façon ou d'une
autre, vu que je déclare une instance de l'objet smarty y aurait peut
être un moyen de rendre cette instance persistante pour qu'elle soit
disponible à l'éxécution de chaque script?



Le temps sera malgré tout consommé. Pas au meme moment, mais
consommé. Ce qui n'optimisera pas as ton site. Tu devrais regarder s'il
ne serait pas pertinent d'utiliser un cache (fichier, memcache, mémoire
partagée, etc) pour les vues. Mais là encore il n'y a pas de solution
miracle.

Le problème de l'optimisation est un casse-tete que tout le monde
cherche à résoudre. Les systèmes de cache aident beaucoup. Mais si
vraiment ton site est très sollicité, tu devrais essayer HipHop ou un
équivalent.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
Pascal
Julien Arlandis a écrit :
Bonjour,



Bonjour,

Je suis dans une phase d'optimisation de mon site et je souhaite
paralléliser toutes les portions de code qui exécutent des requêtes sql
dont le résultat n'est pas nécessaire au déroulement du script
(insertion, suppression, mise à jour...).



Paralléliser avec quoi, un autre serveur HTTP qui tourne avec PHP ?
C'est la solution utilisée par les serveurs publicitaires (adservers)
qui doivent traiter rapidement plusieurs millions de requêtes par mois.
Voir un projet open source comme OpenX pour savoir comment ils font
(http://openx.org/fr).

Mais pour les requêtes SQL concernées, attention aux vues qui ne seront
pas mises à jour pendant la même phase du script.
Peut-être que la solution serait plutôt du côté des grappes de serveurs
de base de données (http://www.mysql.fr/products/database/cluster/).

Il y aussi les procédures stockées qui peuvent être efficaces.

Pour l'affichage de mes vues j'utilise le moteur de template smarty et
j'ai remarqué que le simple chargement du module coute en moyenne 4 à 5
ms, ce module est appelé sur toutes les pages du site...



Cela ne m'étonne guère. C'est la raison pour laquelle ces moteurs sont
obligés de compenser cette perte avec une gestion de cache côté serveur.
Il faut vérifier que celle-ci est bien paramétrée, et puis Smarty n'est
peut-être pas le plus rapide (voir cet article du leader de Symfony :
http://fabien.potencier.org/article/34/templating-engines-in-php).

...Y aurait il un
moyen quelconque de le précharger dans php.ini d'une façon ou d'une
autre, vu que je déclare une instance de l'objet smarty y aurait peut
être un moyen de rendre cette instance persistante pour qu'elle soit
disponible à l'éxécution de chaque script?



Là, je ne connais pas. Quelqu'un d'autre en aura peut-être une idée.

Cordialement,
Pascal
Avatar
Aurelgadjo
Julien Arlandis a écrit :
Bonjour,

Je suis dans une phase d'optimisation de mon site et je souhaite
paralléliser toutes les portions de code qui exécutent des requêtes sql
dont le résultat n'est pas nécessaire au déroulement du script
(insertion, suppression, mise à jour...).
Si une requête s'exécute en 2 ms ce sera toujours 2 ms de moins sur la
durée d'exécution totale du script php, la question c'est comment faire?




Voir les INSERT DELAYED | LOW_PRIORITY et s'il y a la meme chose pour
les update
http://dev.mysql.com/doc/refman/5.5/en/insert.html
Avatar
WebShaker
Le 27/03/2010 21:49, Mickael Wolff a écrit :
Le temps sera malgré tout consommé. Pas au meme moment, mais consommé.
Ce qui n'optimisera pas as ton site. Tu devrais regarder s'il ne serait
pas pertinent d'utiliser un cache (fichier, memcache, mémoire partagée,
etc) pour les vues. Mais là encore il n'y a pas de solution miracle.



Nan.
la question est permtinante et reviens a dire:
comment lancer un thread deuips un script PHP?

Il n'y a malheureusement guère de solution.
J'ai eu un cas ou je devais faire un calcul assez complexe et qui était
facilement parallelisable.
Ben ca n'a pas été simple.

Etienne
Avatar
Mickael Wolff
WebShaker a écrit :

Nan.
la question est permtinante et reviens a dire:
comment lancer un thread deuips un script PHP?

Il n'y a malheureusement guère de solution.
J'ai eu un cas ou je devais faire un calcul assez complexe et qui était
facilement parallelisable.
Ben ca n'a pas été simple.



PHP n'est pas un langage de programmation, mais un outil de
templating. Le but de cet outil n'est pas de permettre les processus
persistant. Il n'y a donc pas de nécessité à l'usage des threads. Si tu
en as absolument besoin, c'est qu'il y a un problème de design de ton
application.

Je rajouterai meme que, de vouloir lancer ainsi des threads et des
processus depuis un processus Apache, c'est dangereux au niveau de la
sécurité et de la disponibilité de ton application. Le modèle de
fonctionnement qui vient avec le Web, c'est justement d'avoir des
processus à courte durée de vie qui meurent rapidement après avoir
généré la requete HTTP qui va bien.

Maintenant, si tu veux parler des batches, je comprends l'intéret
d'utiliser PHP (réutilisation du code). Et là, oui, on pourrait
souhaiter que PHP dispose de threads. Mais par le design de PHP, et au
vu des derniers développements, ça m'étonnerait qu'on ne croise la route
des threads avant 10 ans (soit PHP 7).

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
John GALLET
Bonjour,

PHP n'est pas un langage de programmation, mais un outil de
templating. Le but de cet outil n'est pas de permettre les processus
persistant. Il n'y a donc pas de nécessité à l'usage des threads.



C'est quand même un peu réducteur et partiellement faux.

Si tu en as absolument besoin, c'est qu'il y a un problème de design de ton
application.



Je te donne un exemple que j'ai eu récemment: interroger par XMLRPC des
machines distantes pour collecter des informations qu'elles ne sont pas
capables de remonter seules en push d'information.

Nous sommes d'accord, on peut faire un daemon qui va le faire
régulièrement, stocker l'information, et avoir un bout de webapp qui ne
fait que lire ce résultat. Pour diverses raisons, ce n'était pas
souhaitable.

Il est évident ici que si on peut paralléliser les requêtes aux X
machines (des presses numériques en l'occurence, dont le boulot c'est
d'imprimer avant tout, et si elles ont le temps elles répondent à la
requête XML-RPC), au lieu d'avoir un temps de réponse valant
N*chaque_temps on a un temps qui vaut temps max d'une réponse.

Et là, oui, on pourrait souhaiter que PHP dispose de threads.


On peut le faire en stand-alone:
http://fr2.php.net/manual/en/intro.pcntl.php

On peut aussi faire exec("monshell.sh") avec les risques que ça comporte
et avoir dans le shell un wget monurl.php & <- noter le background

Mais clairement si on a BESOIN de ce genre de comportement, ou il faut
le faire côté client, ou changer d'architecture (typiquement, dans mon
cas, c'est le boulot d'un deamon type Nagios ou Hobbit) ou changer de
techno.

En revanche, concernant la question d'origine, il est "évident" que la
vraie question c'est de savoir où sont les "problèmes" de perf, pas de
se lancer dans des imbécilités du genre echo vs print ou " vs ' ou
lancements en paralèlle à l'aveuglette.

Concernant les requêtes SQL, mysql admet par exemple DELAYED, avec les
risques d'incohérence déjà signalés que ça comporte.

HTH
JGA
Avatar
Mickael Wolff
Le 08/05/2010 15:50, John GALLET a écrit :

C'est quand même un peu réducteur et partiellement faux.



Pourtant historiquement et techniquement, c'est un point de vu que je
considère valable. Mais je suis ouvert à la discussion :) Qu'est-ce qui
t'amène à considérer ma description comme réductrice et fausse ?

Je te donne un exemple que j'ai eu récemment: interroger par XMLRPC des
machines distantes pour collecter des informations qu'elles ne sont pas
capables de remonter seules en push d'information.

Nous sommes d'accord, on peut faire un daemon qui va le faire
régulièrement, stocker l'information, et avoir un bout de webapp qui ne
fait que lire ce résultat. Pour diverses raisons, ce n'était pas
souhaitable.



C'est ce point là qui est intéressant, et qui justifie la
parallélisation : pourquoi n'était-ce pas souhaitable ? Parce que dans
l'absolu, l'architecture dans laquelle la responsabilité de consulter
les sources XMLRPC devrait effectivement être déléguée à un script en
cron (en PHP par exemple).


> Et là, oui, on pourrait souhaiter que PHP dispose de threads.
On peut le faire en stand-alone:
http://fr2.php.net/manual/en/intro.pcntl.php

On peut aussi faire exec("monshell.sh") avec les risques que ça comporte
et avoir dans le shell un wget monurl.php & <- noter le background



Si tu savais combien de fois j'ai vu ça dans des systèmes pro :D

Mais clairement si on a BESOIN de ce genre de comportement, ou il faut
le faire côté client, ou changer d'architecture (typiquement, dans mon
cas, c'est le boulot d'un deamon type Nagios ou Hobbit) ou changer de
techno.



Personnellement je n'aurais pas confiance en PHP pour faire ça. Tant
que PHP reste simple et qu'il meurt vite, je suis ok. Mais ensuite, les
fuites mémoires et les problèmes liées aux performances me rendent nerveux.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
Bruno Desthuilliers
Mickael Wolff a écrit :
PHP n'est pas un langage de programmation, mais un outil de
templating.



Ah tiens, y a pas que moi qui trolle ici ?-)

(snip)

Le modèle de
fonctionnement qui vient avec le Web, c'est justement d'avoir des
processus à courte durée de vie qui meurent rapidement après avoir
généré la requete HTTP qui va bien.



Là je me permets d'être en total désaccord. C'est le modèle d'exécution
de PHP et hérité de CGI, certes, mais ça n'en fait pas "*le* modèle de
fonctionnement du web" pour autant. D'autres technos - pas
nécessairemenr récentes d'ailleurs - s'appuient sur des long-running
process, et ça fonctionne aussi.

Quant à la parallélisation, ça n'implique pas nécessairement les threads.
Avatar
John GALLET
Re,

Pourtant historiquement et techniquement, c'est un point de vu que je
considère valable.



Tout dépend ce qu'on met sous "historiquement". Revenons à la fin 1999
ou début 2000 en PHP 3.04 (oui, ça fait 10 ans que je fais du PHP à
haute dose, il n'y en a pas beaucoup qui peuvent en dire autant). Où en
étaient les concurrents de PHP ? Bah pas très loin. Le c# n'existait
pas, .net non plus, jsp était encore plus dans la panade qu'aujourd'hui.
Donc "historiquement", PHP avait un net avantage d'outsider dans le
monde des webapp.

Mais je suis ouvert à la discussion :) Qu'est-ce qui
t'amène à considérer ma description comme réductrice et fausse ?



C'est surtout le déni de "langage de programmation" qui me gêne. Ce
n'est pas parce que la gestion du multi-thread ou du multi-fork n'est
pas proposée aisément par le socle technique que tu peux dire "ce n'est
pas un langage de programmation".

Certes, les premières instructions en langage C qu'on m'a apprises à
l'école après les I/O c'était fork() et wait() et l'IPC, mais ce n'est
pas parce qu'on en a moins besoin **en environnement web** que c'est
primordial.

PHP peut être utilisé dans trois modes:
1) web
2) shell/daemon
3) php-gtk (stand alone comme java/awt)

Qu'il ne soit pas simple de faire du multi-thread dans le cas où il est
**l'esclave** d'un serveur web qui lui donne la becquée et à qui il
renvoit le flux de sortie ne peut pas justifier de dire que ce n'est pas
un langage de programmation et seulement un outil de templating. Je te
rejoins sur le fait que PHP **EST** un outil de templating (et il
faudrait arrêter de couiner sur les perfs de tous les smarty et autres
surcouches inutiles), mais ce n'est pas SEULEMENT un moteur de template.
La simple(*) lecture de la table de matières du manuel rappelant tout ce
qu'on peut faire avec PHP devrait aider à s'en convaincre.

(*) ouais, enfin depuis leur réorganisation de m***e, même moi je n'y
retrouve plus mes petits, j'ai passé plusieurs minutes hier à chercher
la liste de toutes les fonctions sur les tableaux.

Nous sommes d'accord, on peut faire un daemon qui va le faire
régulièrement, stocker l'information, et avoir un bout de webapp qui ne
fait que lire ce résultat. Pour diverses raisons, ce n'était pas
souhaitable.



C'est ce point là qui est intéressant, et qui justifie la
parallélisation : pourquoi n'était-ce pas souhaitable ?



Déjà parce que ce sont des ressources qu'il faut solliciter le moins
possible (presses industrielles). Donc avoir un cron qui fait du polling
actif pour des prunes, bof. Et aussi parce que quand on déboule me voir
en disant "ça merde", j'ai besoin d'une vision instantanée, pas de ce
qui s'est passé il y a 10 minutes.

Ensuite parce qu'il faut le stocker quelque part. Et non, je n'avais pas
sous la main une base de données que je pouvais utiliser pour ça et pas
du tout envie et encore moins le temps de faire un stockage fichier
propre en RRD ou autre. Après parce qu'il faut avoir justement un accès
à une machine qui va avoir la crontab qui va bien, qui va avoir de quoi
faire la demande (php en CLI). En gros, pour faire l'architecture
propre, il me fallait un projet, un budget temps, l'équipe sysadmin sans
laquelle je n'ai pas le droit d'aller pisser etc. Alors qu'en faisant la
requête directement, en 40 minutes de pause déjeuner c'était torché et
ça répondait au besoin.

Parce que dans l'absolu, l'architecture dans laquelle la responsabilité de consulter
les sources XMLRPC devrait effectivement être déléguée à un script en
cron (en PHP par exemple).



Souvent oui. S'il n'y en a qu'une ou que tu veux absolument une
information synchrone, non.

On peut aussi faire exec("monshell.sh") avec les risques que ça comporte
et avoir dans le shell un wget monurl.php & <- noter le background



Si tu savais combien de fois j'ai vu ça dans des systèmes pro :D



Sur le fond ça ne me gêne pas tellement si on comprend ce qu'on fait.

Mais il est vrai que dans ce cas spécifique là, je l'ai fait en java en
lançant un thread sur chaque machine et ça a réduit drastiquement le
temps de réponse car je passais de sérialisation à parallélisation.

Personnellement je n'aurais pas confiance en PHP pour faire ça. Tant
que PHP reste simple et qu'il meurt vite, je suis ok. Mais ensuite, les
fuites mémoires et les problèmes liées aux performances me rendent nerveux.



J'ai de facto moins de problèmes de perfs et de consommation avec des
daemon en PHP qu'en java... Et j'ai 10 fois plus de JVM de serveur
d'appli qui explosent en vol que d'apache/php qui sont à la peine.

Si je peux je préfère rester en C/C++ ou shell, et bien que ne sachant
que le lire, je constate d'excellents résultats avec python.

Ne pas oublier non plus que toute config de prod apache peut tirer
profit du MaxRequestPerChild et que de toutes façons, il n'est jamais
mauvais de faire un restart des serveurs web/d'appli tous les jours.

HTH
JGA
Avatar
WebShaker
Le 27/03/2010 15:15, Julien Arlandis a écrit :
Bonjour,

Je suis dans une phase d'optimisation de mon site et je souhaite
paralléliser toutes les portions de code qui exécutent des requêtes sql
dont le résultat n'est pas nécessaire au déroulement du script
(insertion, suppression, mise à jour...).
Si une requête s'exécute en 2 ms ce sera toujours 2 ms de moins sur la
durée d'exécution totale du script php, la question c'est comment faire?

Pour l'affichage de mes vues j'utilise le moteur de template smarty et
j'ai remarqué que le simple chargement du module coute en moyenne 4 à 5
ms, ce module est appelé sur toutes les pages du site. Y aurait il un
moyen quelconque de le précharger dans php.ini d'une façon ou d'une
autre, vu que je déclare une instance de l'objet smarty y aurait peut
être un moyen de rendre cette instance persistante pour qu'elle soit
disponible à l'éxécution de chaque script?



il existe plusieurs solutions qui ne sont pas forcément aussi
performante que la gestion des threads, mais qui permettent de faire pas
mal de truc

c'est expliqué ici
http://www.chrogeek.com/2008/08/multithread-en-php-le-point-sur-les-differentes-techniques/

Etienne