[spip-dev] Questions configuration de serveur dédié pour spip

Bonjour,

Le site que j'administre éprouve aujourd'hui quelques difficultés niveau performances depuis que je suis passé de spip 1.9.2 à spip 2 : temps de calculs des pages longs, mais également temps anormalement élevés quand on charge des pages en cache (entre 0.5 et 1.5 secondes entre l'entrée et la sortie dans spip.php).
J'ai ajouté pas mal de fonctions et plugins à mes squelettes lors du passage à spip 2, chose qui a un cout en performances, mais là n'est pas aujourd'hui la question.

Je souhaiterais connaitre la configuration "typique" la mieux adaptée pour faire tourner un site spip 2 de ce type.
Voici les caractéristiques du site :
- 5000 + visites effectives par jour plus de la charge provoquée par les robots d'indexation parce que le site est réparti sur plusieurs domaines tous pointant sur la même machine
    => j'ai jusqu'à 5 googlebots en parallèle.
- des pages assez dynamiques car pas mal de flux éditoriaux mais pas d'interaction côté public (à part un formulaire de contact)
- une soixantaine d'auteurs actifs, généralement entre 3 et 8 auteurs connectés en permanence pour travailler à la saisie / modification de contenu
- pas mal d'images dont beaucoup sont retraitées par GD2 (création de miniatures par image_reduire pour l'essentiel)
- les caches sont configurés à 1h, 1 jour, 1 semaine ou 1 mois suivant les pages
- Il y a apparemment des pics d'activités sensibles sur le cache toutes les heures et toutes les 6 heures, j'attribue ça au cron qui le nettoie, mais peut-être me trompe-je ?

Le serveur dédié qui fait tourner tout ça est un core 2 duo 1.8 Ghz avec 2Go ram, LAMP (mandriva).

Ma question est : pour ce type de setup, quelles sont les configurations habituelles d'apache et mysql (quotas RAM, nombre de process lancés, etc.) ?

Apparemment, ni le processeur ni la mémoire de mon serveur ne sont saturés (ni la bande passante : 4 Mbits / s sur 10 dédiés disponibles), pourtant ça rame dès qu'on monte un peu en charge visiteur.
On s'oriente donc soit vers un package système défaillant ou fautif (ça on est en train de chercher, évidemment personne ici ne peut m'aider), soit vers un problème de configuration du serveur, plus particulièrement sur des engorgements possibles entre les différents processus qui tournent sur la machine ou des soucis de quota mémoire.

J'ai aussi lu des textes qui recommandaient de rester sur apache 1 pour les sites très dynamiques, qu'en pensez-vous ?

A bientôt
    Simon

Simon Camerlo a écrit :

Bonjour,

[...]
- les caches sont configurés à 1h, 1 jour, 1 semaine ou 1 mois suivant
les pages

Bonjour,

il faudrait séparer les squelettes des pages en morceaux
réutilisables, et définir les caches de ces morceaux selon les
besoins. Le pied de page par exemple n'a pas besoin d'être recalculé
souvent n'est ce pas?

[...]
J'ai aussi lu des textes qui recommandaient de rester sur apache 1 pour
les sites très dynamiques, qu'en pensez-vous ?

Plutôt étudier l'utilisation de Apache 2 mode worker, mais ça
nécessite beaucoup de changement, en particulier pour le php qui
doit être intégré différemment qu'en module.

Le mode worker d'apache est vraiment intéressant, de plus, tout ce
qui sera statique pourra être livré plus rapidement.

A bientôt
Grégoire

Hello,

Pour info, SPIP-Contrib tourne sur un dédié à peine plus gros, mais avec plutôt plus de traffic, plein de contributeurs et beaucoup de bots à la porte si on les laisse faire !

Lorsque je l'ai repris, j'ai commencé par optimiser le site lui même même afin de corriger les boucles les plus gourmande en temps de calcul, et les plugins pas optimisés qui génèrent de la charge inutile.

Ensuite, j'ai mis en place la compression/concatenation des CSS et JS dans SPIP, ce qui permet de réduire le nombre de hits sur le serveur, et en particulier de transformer les hits dynamiques (css et js en squelette) en hit statiques (fichiers statiques dans local/).

Puis j'ai optimisé la configuration du serveur, dans l'ordre chronologique :
- gzip par apache (permet surtout un gain de réactivité pour les visiteurs)
- Expire sur les images, css et js (limite le nombre de hit sur le serveur)
- Xcache sur le serveur comme cache opcode (double la capacité de service des page en php)
- écran de sécurité de SPIP qui met les bot en attente lorsque le load est trop fort, et leur évite de parcourir des tonnes d'url inutiles dues aux paginations croisées sur une même page (impact important sur les pics de charge et même sur la charge moyenne)
- répertoire tmp/cache linké sur la mémoire virtuelle dev/shm

La dernière optimisation en cours de test est le plugin cache-cool. Les premiers retours ne montre pas vraiment d'impact sur la charge serveur moyenne, en revanche il procure un gain sensible de réactivité perçue par le visiteur.
Attention cependant, il n'est effectif que pour le domaine principal du site, pas sur les autres domaines en cas de multi domaine.

Tous mes serveurs sont en Apache 2, et je n'ai aucun problème avec cela.
En revanche, il est certain que le sous système disque peut être un frein car il y a beaucoup d'accès disque avec SPIP. C'est sans doute un axe de progrès sur lequel il nous faudra travailler dans l'avenir.

Cédric

D'un point de vue plus "serveur" quand ton site rame :

- que te donne un top ou un ps ? Qui est dans les choux ? Apache ou SQL ?
- côté Apache, comment sont configurées tes directives MaxClients / StartServers / MinSpareServers / MaxSpareServers / MaxRequestsPerChild ? Par défaut, suivant la distrib, l'âge de ta box tout ça (genre je sais que chez Dedibox, c'était minablissime) tu peux avoir des valeurs bien trop petites créant des files d'attentes sur le serveur, alors même que les ressources de la machine ne sont pas atteintes
- RAM pour SQL/PHP ?

Je pense qu'en règlant bien tes directives Apaches et en vérifiant la RAM SQL/PHP tu ne devrais pas avoir de soucis ! (je penche plus pour Apache et ses files d'attentes).

Bonjour,

Merci Cédric pour ces conseils, c'est un retour d'expérience précieux.

Je suis passé à peu près par les mêmes phases d'optimisation des squelettes (il ne me reste qu'à trouver comment optimiser les boucles générées par polyhiérarchie qui n'utilisent pas les index, mais l il va falloir que je mette les mains dans le cambouis et je n'ai pas encore eu le temps), avec en plus une grosse réflexion sur le découpage, les inclusions statiques/dyn, et les caches.
A ce jour mon var_profile est assez stable et satisfaisant, les pages les plus gourmandes ne dépassent pas les 2 secondes de calcul SQL et leur cache est assez long (je descendrai certainement en dessous de la seconde une fois la polyhiérarchie optimisée car je suis malheureusement obligé de faire appel assez intensivement à branche_complete en raison de contraintes éditoriales complexes).
Par contre, si le var_profile est assez stable, les valeurs temporelles renvoyées par var_mode=debug pour la compilation des squelettes sont assez aléatoires (elles oscillent, pour un même squelette, entre quelques millisecondes et quelques dizaines de secondes sans raison apparente quand on le teste plusieurs fois d'affilée).

Pour la compression CSS / JS, elle est en place bien que le couteau suisse (impossible de me passer de certaines lames) la supporte mal : certains media type à corriger pour "all" (j'y travaille), et le fait que les url vers ses js / css sont en absolu en utilisant URL_SITE_SPIP, à cause de leur utilisation à la fois dans le public et le privé (là c'est un peu plus compliqué, je ne sais pas vraiment comment corriger ça sans tout péter).

Sur le front de la config serveur :
- gzip est activé sur tout le serveur et testé (il a fallu rajouter un mime-type "application/javascript" car la config par défaut ne gérait que "text/javascript", vu la taille de jquery ça faisait mal côté BP !)
- l'écran de sécurité est up, je n'ai pas vu de différence flagrante
Je vais de ce pas me pencher sur expire, Xcache et la mémoire virtuelle.

Je pense quand-même que j'ai un souci soit au niveau de php, soit au niveau des MaxClients / StartServers / MinSpareServers / MaxSpareServers / MaxRequestsPerChild comme le disait XDjuj, parce que les temps de réaction du serveur pour l'utilisateur sont vraiment longs (un audit de connectivité a donné un temps moyen de plus de 3s avant de recevoir le premier octet) alors que la courbe de charge processeur est plate (< 5%) et la ram n'est pas saturée (aucune utilisation du scratch).
Tout ceci semble confirmé par le test qu'on est en train de conduire : on a déplacé le serveur SQL sur un serveur alternatif (même baie) avec quasiment aucune amélioration sur le temps de réactivité client.
Je vais demander à l'administrateur de la machine de me transmettre les valeurs de config du serveur (je ne suis que webmestre / développeur, mes connaissances en admin serveur sont théoriques et limitées), histoire de voir si elles ne sont pas aberrantes.

Côté plugins spip, je pense tester assez vite cache-cool (j'attends que vous le stabilisiez encore un tout petit peu, il est jeune, mais chapeau pour la vitesse de mise au point ! :slight_smile: et fastcache également pour mes pages les plus sollicitées, mais comme les lenteurs frappent aussi les pages lues depuis le cache...

En tout cas merci beaucoup pour ces pistes de recherche, si je trouve enfin la source du problème, je ferai un petit retour pour l'expérience collective :wink:

A bientôt
    Simon

cedric.morin@yterium.com a écrit :

Bonjour,

Pour la compression CSS / JS, elle est en place bien que le couteau suisse (impossible de me passer de certaines lames)

Lesquelles sans indiscrétions?

la supporte mal : certains media type à corriger pour « all » (j’y travaille), et le fait que les url vers ses js / css sont en absolu en utilisant URL_SITE_SPIP, à cause de leur utilisation à la fois dans le public et le privé (là c’est un peu plus compliqué, je ne sais pas vraiment comment corriger ça sans tout péter).

hmmm pas fun ca … pour différencier le privé public … on peut utiliser la constante _DIR_RACINE en php et donc #EVAL{_DIR_RACINE} en squelettes peut être?.. mais #CHEMIN ne marche pas?

kent1

Bonjour,

Merci Cédric pour ces conseils, c'est un retour d'expérience précieux.

Je suis passé à peu près par les mêmes phases d'optimisation des squelettes (il ne me reste qu'à trouver comment optimiser les boucles générées par polyhiérarchie qui n'utilisent pas les index, mais l il va falloir que je mette les mains dans le cambouis et je n'ai pas encore eu le temps), avec en plus une grosse réflexion sur le découpage, les inclusions statiques/dyn, et les caches.
A ce jour mon var_profile est assez stable et satisfaisant, les pages les plus gourmandes ne dépassent pas les 2 secondes de calcul SQL

ouch, c'est vraiment beaucoup.
J'essaye toujours de ne pas dépasser le quart de seconde.
Au delà, il faut chercher le problème, car dans la pratique cela laisse largement le temps de récupérer toutes les informations nécessaires à construire une page.

et leur cache est assez long (je descendrai certainement en dessous de la seconde une fois la polyhiérarchie optimisée car je suis malheureusement obligé de faire appel assez intensivement à branche_complete en raison de contraintes éditoriales complexes).

Je suis d'accord que polyhierarchie a un cout, et pour le moment je n'ai pas trouvé d'optimisation simple.
Mais même avec, sur un site comme cuisine-libre, je reste dans la cible du quart de seconde, et dans tous les cas largement sous la demi-seconde.

Au delà, on peut faire tout ce qu'on veut, 2 secondes de calcul c'est vraiment long (en plus cela ne concerne que le sql, il faut ajouter l'execution du php).
Le cache a plein de vertus, et permet de lisser la charge, et de répondre à des pics de visites, mais in fine, lorsqu'une page doit être mise à jour, ce temps de calcul viendra toujours charger le serveur.

Par contre, si le var_profile est assez stable, les valeurs temporelles renvoyées par var_mode=debug pour la compilation des squelettes sont assez aléatoires (elles oscillent, pour un même squelette, entre quelques millisecondes et quelques dizaines de secondes sans raison apparente quand on le teste plusieurs fois d'affilée).

Pour la compression CSS / JS, elle est en place bien que le couteau suisse (impossible de me passer de certaines lames)

c'est un choix. Impossible sûrement pas. Si tu as fais un comparatif avec et sans le couteau et que tu n'as pas vu d'impact sur la perf de ton site et la charge de ton serveur, ça va. Sinon, tu sais ou gratter.

la supporte mal : certains media type à corriger pour "all" (j'y travaille), et le fait que les url vers ses js / css sont en absolu en utilisant URL_SITE_SPIP, à cause de leur utilisation à la fois dans le public et le privé (là c'est un peu plus compliqué, je ne sais pas vraiment comment corriger ça sans tout péter).

Sur le front de la config serveur :
- gzip est activé sur tout le serveur et testé (il a fallu rajouter un mime-type "application/javascript" car la config par défaut ne gérait que "text/javascript", vu la taille de jquery ça faisait mal côté BP !)
- l'écran de sécurité est up, je n'ai pas vu de différence flagrante
Je vais de ce pas me pencher sur expire, Xcache et la mémoire virtuelle.

Je pense quand-même que j'ai un souci soit au niveau de php, soit au niveau des MaxClients / StartServers / MinSpareServers / MaxSpareServers / MaxRequestsPerChild comme le disait XDjuj, parce que les temps de réaction du serveur pour l'utilisateur sont vraiment longs (un audit de connectivité a donné un temps moyen de plus de 3s avant de recevoir le premier octet) alors que la courbe de charge processeur est plate (< 5%) et la ram n'est pas saturée (aucune utilisation du scratch).

Ben oui, mais si il faut 2s de SQL + le calcul du php + le transit, c'est pas très étonnant.
Il faut regarder le ping pour la connectivité pure.
Ensuite tu peux faire un test sur un fichier statique (img, js, css) pour voir apache tout seul, aussi bien en terme de temps de réponse initial+capacité.
Enfin seulement il faut regarder ce que donne un hit php, puis un hit SPIP. Cela te permet de voir quelle couche rame.

Par ailleurs, il y a un réglage par défaut très mauvais dans apache, qui est le
KeepAlive On
KeepAliveTimeout 15

Si tu as cela, en première approche il vaut mieux le passer à Off. Ensuite, pour affiner le temps de réponse vu du client on peut le garder à On, mais avec un timeout de l'ordre d'1s à 2s maxi, ce qui se traduit dans tous les cas par une augmentation de la charge serveur (du fait des process qui restent ouverts en attendant une éventuelle suite).

Tout ceci semble confirmé par le test qu'on est en train de conduire : on a déplacé le serveur SQL sur un serveur alternatif (même baie) avec quasiment aucune amélioration sur le temps de réactivité client.

Ah, plutôt mauvais choix je pense. Avoir le SQL sur le même serveur qu'apache est toujours plus rapide.

Je vais demander à l'administrateur de la machine de me transmettre les valeurs de config du serveur (je ne suis que webmestre / développeur, mes connaissances en admin serveur sont théoriques et limitées), histoire de voir si elles ne sont pas aberrantes.

Côté plugins spip, je pense tester assez vite cache-cool (j'attends que vous le stabilisiez encore un tout petit peu, il est jeune, mais chapeau pour la vitesse de mise au point ! :slight_smile: et fastcache également pour mes pages les plus sollicitées, mais comme les lenteurs frappent aussi les pages lues depuis le cache...

Oui, ces plugins sont bien "en plus" quand on a optimisé tout le reste et qu'on est bien afuté. Ils permettent alors de gagner encore un peu (voire beaucoup). Mais si à la base il y a des gros freins, ils ne feront pas de miracle.

Cédric

Quentin Drouet a écrit :

Bonjour,

Pour la compression CSS / JS, elle est en place bien que le couteau suisse (impossible de me passer de certaines lames)

Lesquelles sans indiscrétions?

  • Trousse à balise → pour #NOW qui permet de faire des requêtes avec des critères articles.date<#NOW et qui génèrent des requêtes de toute façon moins tordues que le critère age
  • Liens en clair → pour les versions imprimables
  • balises #TITRE_PARENT / OBJET
  • supprime le numéro (systématique pour ne pas avoir à me retaper tous les squelettes passés et futurs)
  • Spip et ses raccourcis → redéfinition de certains raccourcis
  • ancres douces
  • découpe en pages et onglets
  • blocs dépliables
  • sommaire automatique
  • belles puces
  • belles urls
  • quelques broutilles dispensables mais sans trop d’impact

la supporte mal : certains media type à corriger pour « all » (j’y travaille), et le fait que les url vers ses js / css sont en absolu en utilisant URL_SITE_SPIP, à cause de leur utilisation à la fois dans le public et le privé (là c’est un peu plus compliqué, je ne sais pas vraiment comment corriger ça sans tout péter).

hmmm pas fun ca … pour différencier le privé public … on peut utiliser la constante _DIR_RACINE en php et donc #EVAL{_DIR_RACINE} en squelettes peut être?.. mais #CHEMIN ne marche pas?

Je t’avouerai que je n’ai pas eu le temps de me plonger dans le code du couteau suisse et de ses outils.
Avec le processus de précompilation des outils,etc., j’ai trop peur de tout casser et n’ai pas le temps de bloquer une journée ou deux là-dessus
=> pour le moment je me contente d’une version non optimale.

A bientôt
Simon

a écrit : Oui, je sais que c’est beaucoup, c’est dû à une architecture de rubriques assez “acrobatique” en raison de multiples contraintes que je ne maîtrise pas forcément (triple contrainte thématique + workflow + type de contenus) que j’ai géré comme j’ai pu sans nuire à l’expérience utilisateur (auteur), un vrai casse-tête, le tout au prix d’un peu de performances. Polyhiérarchie m’a bien aidé, mais il ne peut pas tout faire. L’une des contraintes : les contenus postés par les utilisateurs ne doivent se trouver que dans une seule rubrique, le multi-rubriquage doit être géré uniquement par les admins aux niveaux inférieurs et de manière ponctuelle (pas le temps de remapper en permanence les rubriques) => création d’une “infrastructure” de rubriques aux trois premiers niveaux pour “ventiler” les contenus sans opération supplémentaire ni pour les admins, ni pour les auteurs. Si on ajoute à ça un bilinguisme basé sur une structure de rubriques unique nommées avec des tags qui oblige à faire des tests récursifs de présence d’article dans la langue cible pour vérifier si on doit afficher la rubrique ou pas (car la traduction n’est pas systématique), ça a un coût… L’autre solution (langues sur les secteurs) n’était pas viable vu les autres contraintes, et elle oblige de toute manière les contributeurs à penser à déplacer la version traduite d’un article dans la bonne rubrique, ce qui est inenvisageable vu les contributeurs que je dois gérer (problématique numéro 1 : réduire autant que possible le nombre d’opérations que les contributeurs ont à faire pour publier un article, le tout en leur cédant des drotis d’admin restreint pour qu’ils publient eux-même sans trop faire de bêtise…). Pour en revenir à la charge serveur, le problème est que les courbes CPU, mémoire, et autres indicateurs système sont plates. Et en plus de ça les délais de réaction sont aussi extrêmement longs quand on lit une page dans le cache, alors que la charge serveur est nulle ou presque (vérifié en live par un top lancé sur le serveur au moment des requêtes) => même si les squelettes sont loin d’être optimaux, 3 s de réaction pour lire une page dans le cache me paraissent quand-même exagérées quand la charge serveur est <5%… Oui, tout à fait d’accord. Le problème n’est pas exactement là, c.f. ci-dessus. J’ai essayé avec et sans, le gain est imperceptible, alors autant le garder. D’autant que pour le virer, il me faudrait revoir pas mal de squelettes. (cf autre message). Par contre c’est clair qu’on peut gagner facilement au niveau compactage des headers générés par le CS en s’y penchant un peu. Encore une fois, là n’est pas le problème, le délai concerne tous les hits, pas les seuls qui calculent les pages. Elle est ok, testé en profondeur Ca paraît bon sur le statique, le problème semble venir de la partie dynamique, apache ou php en tête, je creuse dans cette direction. Ca rame au niveau de spip car phpmyadmin est plus réactif même quand spip rame, mais je ne sais pas encore quelle partie : lecture du cache, exécution, réécriture d’url ? Je cherche. Là encore ce ne sont pas seulement les calculs, les lectures dans le cache semblent impactées dans les mêmes proportions. L’admin du serveur vient de m’envoyer les réglages actuels : Voila les parametres apache C’est juste le temps d’un test : pour voir quel côté est en cause. Ca nous a permis de voir au passage que la BP apache → mysql est d’environ 3 Mbits/s en permanence, et mysql → apache de 220 Kbits/s en moyenne Voilà pourquoi je garde ça pour la fin. Merci pour l’aide ! Simon

Non, met le a off, ou à la rigueur 1 ou 2s
au delà c'est délirant comme réglage, complètement aberrant.

Cédric

Moi j'augmenterai simplement Min/MaxSpareServers à genre Min 32 et Max 64 et du coup le start à 32 aussi.

Je tenterais de mettre à 0 le MaxRequestPerChild en vérifiant que la mémoire en prend pas un coup (mais pour l'instant, tu as dit encéphalogramme plat alors autant le tenter).

je sais pas si c'est le meme cas, mais j'ai un probleme sur le calcul
aussi avec un serveur avec le safe_mode mal configuree, dont apache
peut creer un repertoire mais pas ecrire de dans.

Sur l'envoye d'une page en cache c'est nickel, mais pas quand on fait un calcul.

J'ai un timeout sur flock.php, ligne 329

Bonjour,

Un petit retour sur les travaux en cours.

Tout d'abord merci à tous pour vos conseils qui ont été d'une aide précieuse, le serveur est devenu beaucoup plus réactif grâce aux changements qu'on a faits depuis.

Les axes qu'on a retenus sont :
- le maintien du nombre de process apache entre 20 et 40
- le keepalive à 1s
- une augmentation de la mémoire allouée à chaque process à 15 Mo (pas mal de traitements d'images automatisés sur mon site, la différence se sent immédiatement)
- les autres modifs dont j'ai déjà parlé dans un précédent message.

Les temps de réaction ont du coup été divisés par plus de 2, voire par 10 en pleine charge.

Pour améliorer encore, on est en cours d'upgrade de mysql (anciennement v5.0.45 à passer en 5.1.40), et on va également ajouter un frontend Varnish pour les contenus statiques ou faiblement dynamiques.

Ca c'est pour le serveur, du côté du site, l'ajout fe Fastcache et Cache-cool devrait permettre de lisser encore un peu plus la charge.

Plus d'infos bientôt si on arrive à des résultats intéressants.

A bientôt
    Simon

cedric.morin@yterium.com a écrit :

Bonjour,

je suis tombé sur un bon cas de test, aussi :

Le site est à 7000 visiteurs/jours, et tourne sur une base MySQL de
200Mo, et Apache s'effondre au moindre calcul.
Il est super mal optimisé -- voir buggué -- (*), mais je suis en train
de regarder l'impact des configurations du serveur (Apache et MySQL)
sur les perfs.
(et côté temps de calcul, ça monte à plus de 15s pour compiler le cache !)

J'ai cloné le site sur un dédié (en créant une machine virtuelle),
donc y'a de quoi s'amuser..

Je vous fais des retours si je trouve des pistes intéressantes.

.Gilles
(*) Ne me demandez pas pourquoi, mais les pages principales des
rubriques font environ 6000 SELECT !

samuel a écrit :

hello,

Juste pour info, tu peux donner les directives apaches concernées stp ?
> - le maintien du nombre de process apache entre 20 et 40
ca a qqchose a voir avec
    StartServers 5
    MinSpareServers 5
    MaxSpareServers 10
    MaxClients 150
    MaxRequestsPerChild 0
?

C'est ça.
Attention : ces valeurs dépendent vraiment de ta machine, de la charge de ton serveur et des squelettes / plugins / code custom de ton site.
Mes réglages n'ont rien d'absolu, ils correspondent à un cas particulier.
Par contre le MaxRequestsPerChild 0 est une mauvaise idée : ça veut dire que tes processus fils apache ne meurent jamais et ne sont jamais relancés.
Le problème c'est qu'ils libèrent très mal (voire pas) la mémoire, donc avec l'entropie, ils vont saturer ton système.
Dans mon cas on l'a mis à 100 (le process fils meurt après avoir traité 100 requêtes http, le process père en lance alors un nouveau si nécessaire).
Au passage, il me semble aussi qu'on a mis le MaxClients à 100, mais je ne suis plus sûr.
Sinon c'est StartServers 20
                    MinSpareServers 20
                    MaxSpareServers 40
Mais il faut d'abord s'assurer que ton serveur l'encaisse.

> - le keepalive à 1s

KeepAliveTimeout ?

Oui, ça règle la persistance des connexions http.

> - une augmentation de la mémoire allouée à chaque process à 15 Mo (pas
> mal de traitements d'images automatisés sur mon site, la différence se
> sent immédiatement)

hum. Ca, je vois pas trop ou c'est

J'ai oublié de préciser : c'est la mémoire allouée à php.
Je ne connais pas la directive, c'est peut-être dans php.ini.

> - les autres modifs dont j'ai déjà parlé dans un précédent message.

Je vais essayer de retrouver

Posté dans le même fil, tu n'as qu'à le remonter

A bientôt
    Simon

Bonjour,

un petit retour sur une optimisation qui a été effectuée pour booster
un site SPIP mal codé (sous 1.9.2).

- Pas vraiment d'optimisation Apache - il faut dire que ce n'est qu'un
site de test, pas en live..

- utilisation de la version "worker" d'Apache, qui gère très bien le
multi-threading

- Du coup, on n'utilise plus mod_php5 qui ne supporte par le
multi-threading, mais PHP5 est en mode fast-cgi.
  Pour le coup je ne sais pas si c'est un réel gain de perf ou pas..

- le répertoire tmp/cache est linké en mémoire vive (merci Cédric pour l'idée)

mount -t tmpfs -o noexec,nosuid tmpfs /tmp/
mkdir /tmp/www_cache
chown www-data /tmp/www_cache/
ln -s /var/www/tmp/cache /tmp/www_cache

- J'ai repris la config de l'hébergeur Infomaniak.ch, pour MySQL :

interactive_timeout = 30
join_buffer_size = 4194304
key_buffer_size = 67108864
myisam_sort_buffer_size = 67108864
range_alloc_block_size = 4096
read_buffer_size = 2097152
read_rnd_buffer_size = 8388608
sort_buffer_size = 4194304
wait_timeout = 30

- PHP est un peu gonflé en mémoire : il faut dire que le calcul du
cache consomme bcp

- Ajout de xcache

- Et enfin, côté SPIP : plugin FASTCACHE + memoization

Le serveur est une Debian, en virtualisé sous openvz, hébergement OVH MG Max.

Pour info, la base MySQL fait plus de 230Mo, les pages des rubriques
principales parcourent l'ensemble des articles (un bug sans aucun
doute, mais au moins ça donne un intérêt aux tests) : soit 6000 SELECT
lors du calcul du cache. ^^
Là on est dans la situation d'un hébergeur vraiment emmerdé..
(Le problème, c'est que si l'hébergement est mutualisé, ça bouffe du
CPU sur les copain)

Le gain est énorme (entre 5 et 10), et je n'ai certainement pas poussé
jusqu'au bout.

Sinon, comment est-ce qu'on peut augmenter la mémoire allouée à chaque process ?

.Gilles

Bonjour,

un petit retour sur une optimisation qui a été effectuée pour booster
un site SPIP mal codé (sous 1.9.2).

- Pas vraiment d'optimisation Apache - il faut dire que ce n'est qu'un
site de test, pas en live..

- utilisation de la version "worker" d'Apache, qui gère très bien le
multi-threading

- Du coup, on n'utilise plus mod_php5 qui ne supporte par le
multi-threading, mais PHP5 est en mode fast-cgi.
Pour le coup je ne sais pas si c'est un réel gain de perf ou pas..

Je ne suis pas sur...
Mon expérience en la matière est liée à suPHP, qui requiert php en mode cgi.
Difficile de dire quelle était la part de suPHP et du mode cgi, mais
c'etait sensiblement plus lent.
Mais surtout, le mode cgi interdit toute utilisation d'opcode cache
comme Xcache, et là c'est crucial.
Pour fixer les ordres de grandeur j'ai observé les gains suivants :
cgi + suPHP -> mod_php : x 2
mod_php -> mod_php+xCache : x 2

Donc au total un gain x4, mesuré avec ab

- le répertoire tmp/cache est linké en mémoire vive (merci Cédric pour l'idée)

mount -t tmpfs -o noexec,nosuid tmpfs /tmp/
mkdir /tmp/www_cache
chown www-data /tmp/www_cache/
ln -s /var/www/tmp/cache /tmp/www_cache

Moi je préfère faire dans confir/mes_options
if (is_dir("/dev/shm/cache-truc")
  define('_DIR_CACHE', "/dev/shm/cache-truc/");

ce qui permet au site de fonctionner dans tous les cas, y compris
après un reboot si le répertoire cache dans n'est pas recréé dans
dev/shm/

- J'ai repris la config de l'hébergeur Infomaniak.ch, pour MySQL :

interactive_timeout = 30
join_buffer_size = 4194304
key_buffer_size = 67108864
myisam_sort_buffer_size = 67108864
range_alloc_block_size = 4096
read_buffer_size = 2097152
read_rnd_buffer_size = 8388608
sort_buffer_size = 4194304
wait_timeout = 30

J'avoue que j'ai très peu touché à mysql jusqu'ici, et je n'ai jamais
vu grand impact.
Mais il faut dire que je ne passe à l'optimisation serveur que quand
j'ai déjà résolu les problèmes applicatifs, donc dans les squelettes
car sinon c'est comme mettre un sparadrap sur une jambe de bois

- PHP est un peu gonflé en mémoire : il faut dire que le calcul du
cache consomme bcp

- Ajout de xcache

Ça marche marche en cgi ?

- Et enfin, côté SPIP : plugin FASTCACHE + memoization

Attention, ce genre de plugin (en particulier FASTCACHE) est utile en
production pour limiter les ressources serveur et optimiser la qualité
de service, mais sur un environnement de test, il a toutes les chances
de compliquer la vie pour les correctifs, avec des temps de réponse
variables et peu comparables d'un cas sur l'autre.
Perso, je pense que les caches statiques comme FASTCACHE ou Expresso
n'ont d'intérêt qu'en cas de stress ponctuel sur le serveur en
production, car sinon ils amènent de la complexité.

Cédric

- utilisation de la version "worker" d'Apache, qui gère très bien le
multi-threading

- Du coup, on n'utilise plus mod_php5 qui ne supporte par le
multi-threading, mais PHP5 est en mode fast-cgi.
Pour le coup je ne sais pas si c'est un réel gain de perf ou pas..

Je ne suis pas sur...
Mon expérience en la matière est liée à suPHP, qui requiert php en mode cgi.
Difficile de dire quelle était la part de suPHP et du mode cgi, mais
c'etait sensiblement plus lent.
Mais surtout, le mode cgi interdit toute utilisation d'opcode cache
comme Xcache, et là c'est crucial.
Pour fixer les ordres de grandeur j'ai observé les gains suivants :
cgi + suPHP -> mod_php : x 2
mod_php -> mod_php+xCache : x 2

Donc au total un gain x4, mesuré avec ab

Il faut peut-être aussi tenir du fait de passer du mode prefork au
mode worker d'Apache2 :
Si ça n'apporte aucun avantage sur les gros serveurs (d'après ce bench
: http://www.thrull.com/corner/webserver/prefork-vs-worker/), il
semble que c'est intéressant sur les serveurs plus petits (cf. ce
bench : http://www.camelrichard.org/apache-prefork-vs-worker)

Je vais vérifier cette histoire d'opcode car en effet on perd une
grande partie de l'intérêt d'xCache.

- le répertoire tmp/cache est linké en mémoire vive (merci Cédric pour l'idée)

if (is_dir("/dev/shm/cache-truc")
define('_DIR_CACHE', "/dev/shm/cache-truc/");

Nettement plus simple que ce que j'avais proposé, en effet.

- Ajout de xcache

Ça marche marche en cgi ?

xcache fonctionne, au moins en partie, en mode cgi :
le tableau d'admin de xcache m'indique bien que des éléments sont mis en cache.
Maintenant, quel est le rapport avec l'opcode, ça je ne sais pas trop.

Je vais faire des tests complémentaires avec autobech / httperf, pour
voir, dans les 2 configs.
(j'ai vu une assez bonne doc ici :
The Linux HTTP Benchmarking HOWTO)

.Gilles

Cédric Morin a écrit :

cgi + suPHP -> mod_php : x 2
  

Oui !
Je confirme le GROS gain de réactivité sur le serveur en désactivant mod_cgi et fastcgi.

Bon, il me reste encore du boulot, mais là ça commence à ressembler à quelque-chose.
Merci beaucoup du tuyau, c'est en effet assez contre-intuitif comme paramétrage.
C'est certainement lié au fait que spip génère beaucoup de code php à "faible" durée de vie, la phase de compilation cgi ne faisant que rajouter une charge inutile.

A bientôt et merci encore, je continue à creuser
    Simon