mercredi 6 janvier 2016

PostgreSQL : Linux contre Windows

En septembre, j'ai été intivé par Dalibo à participer aux Postgresql Sessions à Paris.

Merci encore, cet événement à complètement changé ma vie !

Lors d'une discussion avec des employés de Dalibo, l'un d'entre eux ma fait une remarque qui a éveillé mon instinct interne de défi !
Il a dit que "PostgreSQL dans une VM Linux dans Windows était plus rapide que PostgreSQL directement dans le même Windows".

Étant nouveau dans le monde PostgreSQL/Linux, j'ai été soufflé par cette information mais quand j'ai fait mon St-Thomas et que j'ai demandé des chiffres, il n'en avait aucun.
J'ai donc compris que c'était une boutade - je comprend vite quand on m'explique longtemps - et qu'il voulait simplement dire que PostgreSQL sous Linux était plus rapide que sous Windows.


Architecture Linux vs architecture Windows.

Pour comprendre ce qui soutient son idée de vitesse, il faut comprendre une grande différence d'architecture logicielle entre Linux  et Windows.

Linux peut faire des "fork" alors que Windows ne le peut !

Mais quésaco un fork ?
En résumé, un fork est un appel système qui permet à un processus de créer un autre processus identique et que chaque processus puisse ainsi continuer à faire ce qu'il doit.
Ils peuvent tous deux partager des espaces mémoire et communiquer facilement.


C'est une technique standard de développement dans un environnement Unix/Linux mais ce n'est pas du tout standard pour Windows... vu que fork n'existe pas sous Windows.


Non seulement ça n'existe pas mais en plus, ce n'est pas une architecture standard pour des applications Windows. Lorsque vous créez une application multi-processus sous Windows, elle doit être basée sur les thread, ou mieux, sous vous la réalisez avec .Net, elle doit être construite avec async.

Mais si fork n'existe pas dans Windows et que le code de PostgreSQL est le même pour Linux et Windows mais qu'il fait un fork en Linux, il fait quoi pour Windows ?

En fait, les brillants développeurs de PostgreSQL on créé un système qui émule le fork dans le code... avec des threads!
Je ne peux que les féliciter car c'est grâce à cela que nous avons PostgreSQL sous Windows.

Mais retour sur la boutade, il est supposé que c'est à cause de ce "fork" maison que PostgreSQL sous Windows est plus lent que sous Linux.

Comme j'ai tendance à croire ce que je vois, j'étais en manque de chiffres qui peuvent prouver ce concept.
La seule étude de performance que j'ai pu trouvé a été réalisée par RedHat.
Je l'ai trouvée sur le forum developpez.net ou une remarque pertinente indique que cette étude risque de ne pas être complètement impartiale vu qu'elle a été réalisée par RedHat.

La Situation.

Le client pour lequel je travaille actuellement a un environnement Windows COMPLET et il prévoit d'utiliser de plus en plus de PostgreSQL à cause d' $ORACLE$ !

Donc, avant de trop utiliser PostgreSQL sous Windows, je voulais être certain que cette solution soit la meilleure option, principalement pour les facteurs suivants :

  1. Elle doit être pérenne! (Un des systèmes sur lequel nous travaillons a été écrit en 1993, l'année où le navigateur Mosaic et le premier Pentium sont sortis et donc, avec une simple extrapolation, ce que nous construisons actuellement sera encore utilisé en 2037).
  2. Elle doit être solide..
  3. Elle doit être efficace.
Si jamais nous devons passer à Linux, le meilleur moment est probablement au début, pas à la fin.
Donc, pour chacun des points précédents, j'ai conclu que
  1. Windows et Linux étaient déjà là en 1993 et sont toujours là, donc c'est bon pour moi. (Windows NT et Slackware sont tous les deux apparus en 1993)
  2. PostgreSQL a débuté en 1995 et beaucoup de monde l'utilise maintenant sans problème. D'ailleurs, récemment Gartner l'a repris dans son leader quadrant, ça aussi c'est bon pour moi.
  3. C'est le chaînon manquant, je ne sais pas si c'est mieux sous Linux ou Windows. 


Donc, comment trouver le chaînon manquant ???  Je vais mesurer moi-même!

L'étude

Pour cette étude de performance, je veux:

  • Un scénario simple,
  • Isoler les éléments étudiés,
  • Voir si PostgreSQL sous Linux est plus ou moins rapide que sous Windows avec le même client, (Parce que je veux tester le serveur !)
  • Être le plus près possible d'un scénario de la vie de tous les jours,
  • Être hébergé dans le nuage. Pourquoi ? Parce que beaucoup d'applications futures seront hébergées dans le nuage... et que je n'ai pas l'infrastructure suffisante chez moi.

"La base de données"

Vous connaissez KISS  ? (Pas ce KISS ! )

create table table_a( thread_id int, a_value int);
create index on table_a(thread_id);

insert into table_a(thread_id,a_value)
select * from generate_series(1,10) as thread_id ,generate_series(1,100000) as a_value;


"Le Client "

Windows 2012 R2 Server sur une instance de type m4.xlarge chez amazon, avec tous les paramètres par défaut.
L'application cliente est composée de 3 exécutables console qui exécutent chacun 5000 tâches.
Elle est disponible sur github https://github.com/jmguazzo/TestPostgresqlPerf.
Chaque tâche fait 1 select et 1 update d'un enregistrement aléatoire de la table_a.
L'application génère la sortie suivante
ApplicationId RunningTasks   TaskDuration   EndTime
7fef1...c1    31             9530868        03:46:01
La durée d'une tâche est en Ticks mais je me suis permis de la convertir en seconde lors de mon analyse des résultats.
L'application est en C# et utilise NPGSQL 3.0.3.

"Le serveur Windows Postgresql " alias WS

Windows 2012 R2 Server sur une instance de type m4.xlarge, avec tous les paramètres par défaut.
PostgreSQL 9.4.5 installé avec l'assistant.J'ai modifié les paramètres max_connections = 300, listen_addresses = * et j'ai effectué les changements minimum dans le fichier pg_hba.conf.

"le serveur Linux Postgresql " alias LS

Amazon Linux AMI sur une instance de type m4.xlarge, avec tous les paramètres par défaut.
PostgreSQL 9.4.5 installé avec yum. (Google a été mon ami pour ce bout-là car j'allais de nouveauté en nouveauté !)
J'ai effectué les mêmes changement au fichier postgresql.conf et pg_hba.conf que ceux que j'ai fait pour Windows.



Résultats

Comme introduction, voici le temps d'exécution pour la création de la table :

Mon portable
Query returned successfully: 1000000 rows affected, 14624 ms execution time.

WS
Query returned successfully: 1000000 rows affected, 9374 ms execution time.

LS
Query returned successfully: 1000000 rows affected, 3859 ms execution time.

Ça y est, je suis soufflé, Linux déchire !
(Et maintenant que c'est clairement prouvé que mon portable est pourri, je ne vais plus l'inclure dans les autres résultats...)

Analyse des exécutions


Comme expliqué ci-dessus, chaque test est composé de 15.000 exécutions de 1 SELECT et 1 UPDATE.

En exécutant les tests sur LS, il y a eu 8 erreurs "Timeout while getting a connection from pool".
Et honnêtement, je pensais avoir plus d'erreurs avec Windows qu'avec Linux; je m'étonne encore de mes propres suppositions...

Lorsqu'une erreur survient dans une exécution, l'application retourne un -1 pour la durée comme repris ci-dessous :
7fef1...c1    31    541229671    03:47:09
7fef1...c1    31    -1    00:00:00

Donc, j'ai dû retirer ces 8 exécution de mon analyse statistique et j'ai dû en retirer aussi 8 des résultats sous WS.
Ne sachant pas trop lesquelles retirer sans troubler les résultats, je les ai retirées aux alentours de la médiane.



Durées

Serveur Minimum Maximum Moyenne Médiane
WS 0,1093749 sec 121,6842917 sec 1,0363515 sec 0,8280406 sec
LS 0,1249964 sec 108,2615642 sec 1,0234334 sec 0,9374624 sec

Que pouvons-nous déterminer avec ça ?
Pour la durée minimum, WS est 15% plus rapide que LS.
Par contre, pour la maximum WS est 10% plus lent que LS.

Pour la moyenne, WS est 1% plus lent que LS.
Mais comme le dit l'adage, si ma tête est dans le four et mes pieds dans le congélateur, en moyenne je suis bien !

Vu que la médiane se détermine en prenant le résultat au milieu de l'ensemble et que nous avons 14992 résultats (15000 - 8 erreurs), la médiane se trouve au résultat numéro 7496.

WS est 10% plus rapide sur base du chiffre mais lorsque nous plongeons dans les résultats, il faut se rendre à l'exécution 8543 pour avoir une durée de 0,93746 secondes.
Donc, plus de 1000 exécutions sous WS ont été plus rapides que la médiane de LS.

Temps de réponse OU débit

Je n'ai pas voulu analyser le traffic/débit car, pour moi, je trouve cette information peu utile, particulièrement avec l'application que j'ai réalisé et avec l'hébergement dans le nuage.
J'ai quand même toujours trouvé difficile d'apprécier des mesures précises du matériel, surtout lorsque le dit matériel est utilisé pour prendre ces mesures; on est proche du chat de Schrödinger's !

Je suis plus obnubilé par le temps de réponse car ma mémoire ne cesse de se rappeler à moi avec les résultats de cette recherche effectuée par Jakob Nielsen qui reprend les limites suivantes pour le temps de réponse :
  • 0.1 seconde est +- la limite pour que l'utilisateur ait le sentiment que le système réagit de manière instantanée, et donc qu'aucun mécanisme ou indicateur n'est requis, si ce n'est l'affichage des résultats.
  • 1.0 seconde est +- la limite pour que le flux de pensée de l'utilisateur ne soit pas interrompu bien qu'il en remarque le délai. Normalement, aucun indicateur n'est nécessaire pour des délais entre 0.1 et 1.0 seconde mais l'utilisateur aura l'impression qu'il n'est pas directement lié aux données.
  • 10 secondes est la limite pour garder l'attention de l'utilisateur. Si les délais sont plus long, l'utilisateur va vouloir effectuer d'autres tâches en attendant que l'ordinateur termine. Il faut donc leur donner des indications de la progression ou de quand la tâche sera terminée.

J'ai donc pris comme hypothèse que si votre BD+WebServeur doit répondre en moins de 10 secondes, j'en donne 5 à la BD.
Donc :

Serveur Nombre d'exécutions de moins de 5 sec
WS 14913
LS 14926

Il y a donc une différence de seulement 0.001% entre WS et LS.
Et pour chaque système, plus de 99% des exécutions ont pris moins de 5 secondes.

Conclusion



Windows Linux Gagnant
Nombre d'exécutions 15.000 15.000 Les 2!
Nombre d'erreurs 0 8 Windows
Durée minimum 0,1093749 sec 0,1249964 sec Windows
Durée maximum 121,6842917 sec 108,2615642 sec Linux
Durée moyenne 1,0363515 sec 1,0234334 sec Linux
Durée médiane 0,8280406 sec 0,9374624 sec Windows
Nombre d'exécutions de moins de 5 sec 14913 14926 Linux

L'infrastructure que j'ai utilisée était hébergée sur Amazon et certains de mes résultats ont pu être troublés par des actions en dehors de mon contrôle ... ce qui sera toujours le cas quand vous êtes dans le nuage

De plus, j'estime que certaines différences ne sont pas statistiquement significatives, mais on pourrait en débattre.

Avec ces résultats, je ne peut dire que PostgreSQL est plus rapide sur un système d'exploitation que sur l'autre.

Et donc, pour répondre à ma propre requête, je ne vais pas conseiller à mon client de prendre les performances de PostgreSQL comme raison pour migrer à Linux.
On pourrait tergiverser en disant qu'il y a plus d'outils PostgreSQL sous Linux que sous Windows mais ce n'était pas le point de cet article.

Pour moi, la performance de PostgreSQL sous Windows n'est ni meilleure ni pire que sous Linux,elle est similaire !

Les résultats complets sont disponibles sur github.


Aucun commentaire:

Publier un commentaire

Ce commentaire sera validé par notre modérateur.