C'est un peu un coup de gueule car depuis maintenant une année je me spécialise dans la performance de mes applications PHP autant en terme de rapidité d'éxécution qu'en consomation de RAM ou de CPU. Parfois je me demande à quoi peuvent servir tous ces efforts quand tous ceux-çi se retrouvent ruinés par un réseau trop lent.

Aujourd'hui j'en ai un exemple assez flagrant. Souvent pour ceux qui font runner leur serveur de base de données sur leur machine personnelle ou professionnelle, ou qui ont tout simplement un trafic assez fort pour causer des ralentissements sur leur machine ont peut-être déjà rencontrer cet exemple. Aujourd'hui j'ai eu donc un tranfert de table à faire entre mes serveurs MySql. Les deux tables n'étant pas constituer de la même manière et des opérations sur les enregistrements étaient nécessaire pour les rendrent conformes au nouveau format. J'ai donc requis un petit script PHP pour effectué l'export / import.

Je sais déjà que :

  • Faire un select de mes enregistrements.
  • Boucle while pour les traiter un par un.
  • Enregistrer les requêtes d'insertion pour la nouvelle table dans un fichier (comme un dump de sauvegarde).
  • Compresser ce fichier.
  • L'envoyer sur le serveur MySql hébergeant la nouvelle table.
  • Le décompresser.
  • Taper une ligne de commande pour lancer les insertions contenues dans le fichier.

Sera plus rapide que faire :

  • Un select des enregistrement.
  • Une boucle while pour les traiter un par un et les insérer directement dans la nouvelle table.

Déjà ce constat peut paraître étonnant, je décide de savoir dans qu'elle proportion va s'étendre cette différence.Voici les données de départ : 1,7 million d'enregistrements à déplacer et un serveur MySql bi-Xeon double coeur à disposition qui héberge la nouvelle table.

Maintenant les résultats tant attendu :

La première méthode à durée 12 minutes, 6 pour l'export, 5 pour la compression / décompression et le tranfert de serveur et 100 % de CPU utiliser pendant la minute de réinsertion dans la nouvelle table. La seconde méthode à pris un peu plus de deux heures en consomant durant ces deux heures 10 % de CPU sur le serveur hébergeant la nouvelle table.

Il faut savoir que la seconde méthode peut s'avérer utile si l'on souhaite faire un transfert peu important, étallé dans le temps en ne saturant pas la machine de destination pendant le transfert. Mais en ce qui me concerne et ce qui me révolte pas mal c'est que dans la première méthode faire l'abstraction du réseaux (encapsulation Mysql de la requête, enscapsulation ethernet, dialogue entre serveur etc...) montre avec évidence combien les protocoles réseaux sont consomateurs de temps. Alors avant d'hurler au fait que votre serveur Mysql distant est trop lent, de crier sur Apache qui ne serait pas assez rapide. Sachez que ces logiciels sont très performant et que ces performances ne sont que rarement observées car les protocoles réseaux les freinent en permanence.

Si certains souhaitent apporter des solutions sur les goulots d'étranglement de la seconde méthode, sachez que la connexion au serveur Mysql hébergeant la nouvelle table était permanante sinon les performances se seraient encore plus écroulées je l'imagine.

Comment remédier à tout ça je n'ai bien évidemment pas la réponse. J'espère que certains relativiseront un peu leur critique envers certain logiciel (plus précisément serveurs) s'ils ont des problèmes de déliverabilité et que ça fait aussi du bien de critiquer un peu, j'en avais envie ce soir. Alors flûte le réseau hein =)