optimisation magento

Mise-à-jour de Magento

Il est essentiel, pour se prémunir des attaques, bugs, et pour profiter des améliorations en tous genres, de tenir sa version Magento à jour. D'autant plus qu'il sera beaucoup plus difficile – voire impossible – de sauter d'une version à une autre, sans passer par toutes les versions intermédiaires qui seraient sorties entre temps.

Mettre à jour Magento peut s'avérer risqué, c'est pourquoi il faut se préparer au pire :

  • on sauvegarde la base de données :

    mysqldump -u utilisateur -p"mot_de_passe" nom_de_la_base > sauvegarde_datée.sql

  • on sauvegarde l'intégralité du dossier racine de magento.

Ensuite, on se rend dans le dossier de Magento et, en utilisateur root :

./pear mage-setup . (si la permission est rejetée : chmod 755 pear)
./pear install -f magento-core/Mage_All_Latest-stable
rm -rf racine_magento/var/cache/*
rm -rf racine_magento/var/session/*

Il faudra ensuite penser à recréer le cache à partir de l'interface d'administration et régler les éventuelles nouvelles options de configuration.

Suppression des logs de la base de données Magento

Magento sauvegarde dans sa base de données les informations relatives aux accès au site par les visiteurs.

Dans sa table de log, on trouve les champs log_url, log_url_info, log_visitor et log_visitor_info. Cette table peut grossir considérablement avec le temps, particulièrement sur un site à fort trafic, et affecter les performances du serveur hébergé. Par défaut, l'épuration de cette table n'est pas activée.

Pour l'activer et rélger les différentes options relatives au système de log, il convient de se rendre dans l'interface d'administration, menu Système -> Configuration, puis Système sur la gauche, puis dans l'onglet relatif aux logs.

Sessions Magento en base de données

Il peut être utile de stocker les sessions non plus sur le filesystem, ni même en RAM (cf ce billet), mais directement en base de données. Cela sera particulièrement utile dans le cas d'un environnement hébergé de cluster de base de données (cf ce billet) avec replication et load balancer, afin d'éviter des conflits de sessions entre les différents front offices...

Avec Magento, rien de plus simple : rendez-vous dans le fichier racine_magento/app/etc/local.xml, et changez la ligne
<session_save><![CDATA[files]]></session_save>
en
<session_save><![CDATA[db]]></session_save>

Et voilà.

Cluster de base de données Magento

Si tout se passe bien pour vous, votre commerce devrait s'étendre jusqu'aux limites du serveur hébergé que vous utilisez.

Lorsque ce moment arrive, que malgré toutes les optimisations mises en oeuvre, l'afflux de visiteurs commence à faire ralentir le site, il est temps de passer à une architecture multi-serveurs.

Tout a déjà été prévu dans Magento pour faciliter la mise en place d'une replication de base de données. Avec une base de données dédiée à la lecture, et une autre, dédiée à l'écriture, un système de réplication entre les deux pour garder les données synchronisées, on peut facilement doubler les capacités au niveau des accès aux données. Imaginez cela couplé à un load-balancing sur plusieurs front office... mais cela fera l'objet d'un autre billet.

Voici un lien expliquant la procédure de mise en place de la réplication, et ici un exemple de configuration du fichier racine_magento/app/etc/local.xml permettant de mettre en place la base de lecture et celle d'écriture :

[...]
       <resources>
            <db>
                <table_prefix><![CDATA[]]></table_prefix>
            </db>
            <default_setup>
                <connection>
                        <host><![CDATA[ip_bdd_ecriture:port]]></host>
                        <username><![CDATA[user]]></username>
                        <password><![CDATA[password]]></password>
                        <dbname><![CDATA[nom_bdd]]></dbname>
                    <active>1</active>
                </connection>
            </default_setup>
            <default_read>
                <connection>
                        <host><![CDATA[ip_bdd_lecture:port]]></host>
                        <username><![CDATA[user]]></username>
                        <password><![CDATA[password]]></password>
                        <dbname><![CDATA[nom_bdd]]></dbname>
                    <active>1</active>
                </connection>
            </default_read>
        </resources>
[...]

default_setup correspond à la base de données d'écriture.

Magento et mpm_worker

Concernant le fonctionnement d'Apache, le module mpm_prefork est le module par défaut. Il est très robuste mais aussi très consommateur de ressources. Chacun de ses processus utilise son propre espace mémoire, chaque nouveau processus réserve un nouvel espace en RAM.

Le module mpm_worker est plus récent, mieux pensé. Beaucoup plus performant, il permet de multi-threader les requêtes, le lancement d'un thread étant beaucoup plus rapide que celui d'un nouveau processus, conservant aussi le même espace mémoire. Il s'agit de l'une des meilleures optimisations possible pour la plateforme Magento hébergée.

La principale raison pour laquelle mpm_worker n'a pas encore remplacé mpm_prefork, est qu'il lui faut utiliser des extensions thread-safe, ce qui n'est pas toujours le cas, notamment avec mod_php. D'où la nécessité d'utiliser fastCGI en lieu et place de mod_php (voir ce billet). À noter que mpm_worker remplace mpm_prefork, et vice versa. Il n'est pas possible de conserver les deux.

Pour l'installer, un apt-get sur une debian ou un ubuntu suffit, sinon il convient de recompiler Apache avec l'option --with-mpm=worker lors du ./configure. Pour vérifier si l'installation a bien fonctionné, utiliser la commande " httpd -l " si tout s'est bien passé, worker apparaîtra dans la liste des modules chargés par Apache.

Magento et FastCGI

Très gourmand en ressources, en RAM notamment, un Magento mal configuré peut facilement épuiser les capacités d'un serveur très puissant.

Le php permet d'ajouter du dynamisme aux pages, mais a besoin d'être généré à la volée pour toute requête. Mod_php, le module php par défaut d'Apache, n'a qu'un défaut : il a été conçu pour fonctionner avec un processus différent pour chaque N requêtes. Ce qui signifie que sur un serveur très chargé, des dizaines de processus mod_php peuvent tourner en même temps, consommant de ce fait la RAM et forçant le serveur à swapper, engendrant d'énormes ralentissements. Ce phénomène est amplifié si le keepalive d'Apache est activé, car même non-utilisé, un processus mod_php resterait en RAM jusqu'à l'expiration du keepalive.

Afin de tirer profit de keepalive, et de sauvegarder la RAM du serveur, nous recommandons, pour votre plateforme hébergée, d'utiliser fastCGI. FastCGI ne lance qu'un nombre déterminé de processus, qui ne change pas. Ils restent en RAM et traitent toutes les demandes liées au php, au déficit de quelques millisecondes de chargement de page, tout en permettant d'utiliser keepalive.

Voir ce lien pour la procédure d'installation.

Optimisation de Magento par la configuration de MySQL

La configuration par défaut de MySQL tend à préserver la RAM à outrance. Une plateforme Magento hébergée se doit d'être rapide afin d'assurer le maximum de confort à la navigation, et l'optimisation de la configuration de MySQL y contribue pour beaucoup.

Nous proposons ici quelques rapides réglages à apporter au fichier my.cnf, section [mysqld]:

max_connections = 500
max_connect_errors = 10
key_buffer_size = 32M
max_allowed_packet = 16M
table_cache = 512
sort_buffer_size = 8M
join_buffer_size = 8M
read_buffer_size = 2M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 64M
myisam_repair_threads = 1
myisam_recover
tmp_table_size = 64M
thread_cache_size = 8
thread_concurrency = 8
wait_timeout = 300
max_heap_table_size = 32M
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = x
(ou x = 80% de la RAM sur un serveur dédié, ou 50% sur un serveur non-dédié)

Bien que ces réglages conviendront à la plupart, l'idéal serait d'adapter ces paramètres aux besoins spécifiques de la plateforme Magento en question.

Magento et cache Flat catalog

À partir de la version 1.3 de Magento, l'équipe des développeurs a rajouté une optimisation majeure : le cache Flat Catalog.

Il permet de mettre en cache une version "flat" des tables du catalog. Au final, on obtient un gain de 40% de temps de chargement des pages sur le front office du site hébergé -ainsi qu'une meilleure gestion de la mémoire-, contre un ralentissement de quelques pages sur le back office.

L'activation se fait comme suit :

  • dans l'interface d'administration, Système -> Configuration, puis dans le menu de gauche "Catalogue", onglet "Frontend", cocher Oui pour les deux options concernant le Flat Catalog.
  • toujours dans l'interface d'administration, Système -> Gestion du cache, recréer les deux caches concernant le Flat Catalog.

eAccelerator et Magento

Alternative pour la gestion du cache php, eAccelerator semble donner un gain de 10% à 20% supérieur à APC sur une plateforme Magento (voir les benchmarks).

La procédure d'installation est la suivante :

  • télécharger les sources sur le site officiel ;
  • configuration, compilation et installation avec cette série de commandes :
    phpize
    ./configure --with-eaccelerator-shared-memory --with-eaccelerator-sessions --with-eaccelerator-content-caching --with-php-config=PATH
    (pour le PATH : whereis php-config)
    make && make install
  • ajouter les lignes suivantes dans php.ini :

    [eaccelerator]
    extension="eaccelerator.so"
    eaccelerator.shm_size="128"
    eaccelerator.cache_dir="/tmp/eaccelerator" 
    (créer le dossier et chmod 777)
    eaccelerator.enable="1"
    eaccelerator.optimizer="1"
    eaccelerator.check_mtime="1"
    eaccelerator.debug="0"
    eaccelerator.filter=""
    eaccelerator.shm_max="0"
    eaccelerator.shm_ttl="0"
    eaccelerator.shm_prune_period="0"
    eaccelerator.shm_only="0"
    eaccelerator.compress="1"
    eaccelerator.compress_level="9"

Puis redémarrer Apache.

Ensuite, éditer/ajouter les lignes suivantes dans racine_magento/app/etc/local.xml :

<cache>
    <backend>eaccelerator</backend>
    <prefix>alphanumeric</prefix>
</cache>

Il faudra penser à rafraichir le cache depuis l'interface d'administration du site hébergé.

Compilation intermédiaire du code PHP de Magento

Sans optimisation de ce côté, le serveur doit repasser par toutes les phases de compilation / interprétation du langage PHP pour chacune des pages du site.

Il existe des gestionnaires de cache de compilation intermédiaire du code PHP, tel que APC, qui soulagent la charge processeur du serveur en mettant en cache le code PHP dans un format de code binaire intermédiaire, ce qui épargne à l'interpréteur de recompiler l'intégralité du code PHP à chaque requête. Il s'agit de l'une des meilleurs optimisations possible pour Magento, du fait de l'importance du PHP dans son code.

La première chose à faire est d'installer APC :
par exemple sous Debian : apt-get install php-apc

Puis, dans php.ini, d'ajouter les lignes suivantes :

[apc]
apc.enabled="1"
apc.ttl="7200"
apc.user_ttl="7200"
apc.shm_segments="3"
apc.shm_size="128"

Et enfin, de redémarrer Apache.

Bien que nous recommandons – pour des raisons d'optimisations – d'utiliser le système de fichier tmpfs pour cela (voir ce billet), il est possible d'utiliser APC comme cache du dossier racine_magento/var/cache. Pour se faire, il convient de se rendre dans le fichier racine_magento/app/etc/local.xml et d'y ajouter les lignes suivantes, juste en dessous de <global> :

<cache>
    <backend>apc</backend>
    <prefix>alphanumeric</prefix>
</cache>

(dans le cas ou plusieurs Magento/sites web tourneraient sur le serveur d'hébergement, il faut remplacer alphanumeric par un préfixe unique, cela permet de différencier les caches d'APC afin de ne pas mélanger les données entre les sites).