CallJson, the extension I use for calling Rest WebServices is now available on VisualStudio Gallery :
https://visualstudiogallery.msdn.microsoft.com/43b8b9f6-cb92-4184-bf52-7208bedf82ab
SQIG
samedi 1 octobre 2016
vendredi 22 janvier 2016
PostgreSQL : Linux VS Windows - part 2
After my initial test, I had some interesting feedback my post on reddit that pushed my to do another benchmark.
And to be sure, I'll put it into words again, this is not a Linux vs Windows benchmark !
I don't care about what's the best !
I have a client with a big windows infrastructure (and no Linux) and a lot of windows expertise (and no Linux) and I want to know if I must advise him to use PostgreSQL on Linux.
Because to move to Linux, he would have to hire a Linux specialist, develop in-house expertise and adapt his budgets consequently.
Following /u/graycube's advice, I ditched my benchmark tool and used PgBench for this second round of benchmark of Windows vs Linux for PostgreSQL hosting.
Following ants_a's advice, I tested with bigger data than the memory size and with a long duration.
The m4.xlarge instances at Amazon have 16gb of data and with a scale of 2000, pgbench generated a db of +-30gb.
PgBench, for the unaware (like me) does exactly what my benchmark program did but better !
It has a lot of options and is more heavily tested than my app that's only been tested ... by me.
PGBench's not really close to what I wanted because I wanted to test it with a .NET app that uses npgsql (pgbench uses libpq), but, as the saying goes "When in Rome, do as the romans do."
For thoses tests, the architecture is the same as the previous one :
"The Client "
Windows 2012 R2 server on amazon, m4.xlarge type, with all the default settings.
The client "application" is PgBench.
"The Windows PostgreSQL Server " aka WS
Windows 2012 R2 server on amazon, m4.xlarge type, with all the default settings and a 100gb ssd.
PostgreSQL 9.4.5 installed with the wizard.
I changed the listen_addresses to * and the required changes to pg_hba.conf for the connection to work.
"The Linux PostgreSQL Server " aka LS
Amazon Linux AMI, m4.xlarge type, with all the default settings and a 100gb ssd.
PostgreSQL 9.4.5 installed with yum.
I made the same changes for postgresql.conf and pg_hba.conf as the one I made for Windows.
a.1 - init PgBench
a.2 - run locally PgBench for 240 seconds.
a.3 - run locally PgBench for 240 seconds for 42 clients.
a.4 - run locally PgBench for 240 seconds for 42 clients with 21 threads.
a.5 - Set max_connections to 300 and restart PostgreSQL
a.6 - run locally PgBench for 240 seconds for 42 clients with 21 threads.
a.7 - run from The Client for 240 seconds for 42 clients with 21 threads.
Scale of 1000
b.1 - init PgBench
b.2 - restart PostgreSQL
b.3 - run from The Client for 240 seconds for 42 clients with 21 threads.
b.4 - run from The Client for 1200 seconds for 42 clients with 21 threads.
Scale of 2000
c.1 - init PgBench
c.2 - restart PostgreSQL
c.3 - run from The Client for 2400 seconds for 250 clients with 125 threads.
My computer
50000000 of 50000000 tuples (100%) done (elapsed 118.58 s, remaining 0.00 s).
WS
50000000 of 50000000 tuples (100%) done (elapsed 59.88 s, remaining 0.00 s).
LS
50000000 of 50000000 tuples (100%) done (elapsed 48.87 s, remaining 0.00 s).
For some "fun", I tried PgBench on my computer to compare it with a 0.5$/hr machine on amazon but I stopped quickly...
As it was with the tests with my app, creation on Linux is faster.
Or is it really ?
INIT PgBench 1000
WS
100000000 of 100000000 tuples (100%) done (elapsed 115.18 s, remaining 0.00 s).
LS
100000000 of 100000000 tuples (100%) done (elapsed 120.97 s, remaining 0.00 s).
INIT PgBench 2000
WS
200000000 of 200000000 tuples (100%) done (elapsed 261.00 s, remaining 0.00 s).
LS
200000000 of 200000000 tuples (100%) done (elapsed 264.69 s, remaining 0.00 s).
Summarized init numbers :
Linux is a little bit (<5%) slower when there's a lot of data !
Here again, we should be reminded that it's the default PostgreSQL settings and default settings for both OSs.
So maybe autovacuum kicked in, maybe the Amazon's Linux VM pool is more used than the windows' one,... or whatever reason you could fit in there !
Let's see if this is the same when we run PgBench instead of just the initialization.
For the sake of sanity, I rounded some of PgBench's results but they are all available on my github.
Now I'm in the fog .
How come pushing the max_connections to 300 allowed the tps to rise ?
I guess that's because I restarted the PostgreSQL process
Please note that I haven't used the -C parameter so there should only be one connection per client. (So a max of 42)
PgBench's doc :
-C
Establish a new connection for each transaction, rather than doing it just once per client session.
Windows made 68% more TPS than Linux under heavy load for a long time.
I couldn't believe it so I waited one week and did it again.
Linux went up 10% but Windows stood almost the same for a new diff of 54%.
So on both C.3 test, we have almost 61% diff in favor of Windows.
I discussed about it with my colleagues and one of them said :
"Of course you noob, you have to tune Linux a minimum to reach the best perf !"
My answer was :
"No. That's the goal of my exercise.
I don't want a Linux specialist fiddling for 6 weeks to have a top notch server, nor do I want a Windows specialist to fiddle for 6 weeks for the same reason.
Moreover, if I'm using the cloud, there's a lot of area that I won't be able to tune. (Disk, network, ...)"
In my previous post, I said that Linux and Windows are at par when it comes to PostgreSQL performance.
After this second test I'm forced to say :
Which means, for me, they are at par.
Follow-up from the boutade from my first post, PostgreSQL in Linux in a VM in Windows is NOT faster than PostgreSQL on the same Windows, not at all !
What do you think ?
And to be sure, I'll put it into words again, this is not a Linux vs Windows benchmark !
I don't care about what's the best !
I have a client with a big windows infrastructure (and no Linux) and a lot of windows expertise (and no Linux) and I want to know if I must advise him to use PostgreSQL on Linux.
Because to move to Linux, he would have to hire a Linux specialist, develop in-house expertise and adapt his budgets consequently.
Following /u/graycube's advice, I ditched my benchmark tool and used PgBench for this second round of benchmark of Windows vs Linux for PostgreSQL hosting.
Following ants_a's advice, I tested with bigger data than the memory size and with a long duration.
The m4.xlarge instances at Amazon have 16gb of data and with a scale of 2000, pgbench generated a db of +-30gb.
PgBench, for the unaware (like me) does exactly what my benchmark program did but better !
It has a lot of options and is more heavily tested than my app that's only been tested ... by me.
PGBench's not really close to what I wanted because I wanted to test it with a .NET app that uses npgsql (pgbench uses libpq), but, as the saying goes "When in Rome, do as the romans do."
For thoses tests, the architecture is the same as the previous one :
"The Client "
Windows 2012 R2 server on amazon, m4.xlarge type, with all the default settings.
The client "application" is PgBench.
"The Windows PostgreSQL Server " aka WS
Windows 2012 R2 server on amazon, m4.xlarge type, with all the default settings and a 100gb ssd.
PostgreSQL 9.4.5 installed with the wizard.
I changed the listen_addresses to * and the required changes to pg_hba.conf for the connection to work.
"The Linux PostgreSQL Server " aka LS
Amazon Linux AMI, m4.xlarge type, with all the default settings and a 100gb ssd.
PostgreSQL 9.4.5 installed with yum.
I made the same changes for postgresql.conf and pg_hba.conf as the one I made for Windows.
The scenarios
Scale of 500a.1 - init PgBench
a.2 - run locally PgBench for 240 seconds.
a.3 - run locally PgBench for 240 seconds for 42 clients.
a.4 - run locally PgBench for 240 seconds for 42 clients with 21 threads.
a.5 - Set max_connections to 300 and restart PostgreSQL
a.6 - run locally PgBench for 240 seconds for 42 clients with 21 threads.
a.7 - run from The Client for 240 seconds for 42 clients with 21 threads.
Scale of 1000
b.1 - init PgBench
b.2 - restart PostgreSQL
b.3 - run from The Client for 240 seconds for 42 clients with 21 threads.
b.4 - run from The Client for 1200 seconds for 42 clients with 21 threads.
Scale of 2000
c.1 - init PgBench
c.2 - restart PostgreSQL
c.3 - run from The Client for 2400 seconds for 250 clients with 125 threads.
The results !
INIT PgBench 500My computer
50000000 of 50000000 tuples (100%) done (elapsed 118.58 s, remaining 0.00 s).
WS
50000000 of 50000000 tuples (100%) done (elapsed 59.88 s, remaining 0.00 s).
LS
50000000 of 50000000 tuples (100%) done (elapsed 48.87 s, remaining 0.00 s).
For some "fun", I tried PgBench on my computer to compare it with a 0.5$/hr machine on amazon but I stopped quickly...
As it was with the tests with my app, creation on Linux is faster.
Or is it really ?
INIT PgBench 1000
WS
100000000 of 100000000 tuples (100%) done (elapsed 115.18 s, remaining 0.00 s).
LS
100000000 of 100000000 tuples (100%) done (elapsed 120.97 s, remaining 0.00 s).
INIT PgBench 2000
WS
200000000 of 200000000 tuples (100%) done (elapsed 261.00 s, remaining 0.00 s).
LS
200000000 of 200000000 tuples (100%) done (elapsed 264.69 s, remaining 0.00 s).
Summarized init numbers :
Server | Scale 500 | Scale 1000 | Scale 2000 |
---|---|---|---|
WS | 59.88s | 115.18s | 261.00s |
LS | 48.87s | 120.97s | 264.96s |
Linux is a little bit (<5%) slower when there's a lot of data !
Here again, we should be reminded that it's the default PostgreSQL settings and default settings for both OSs.
So maybe autovacuum kicked in, maybe the Amazon's Linux VM pool is more used than the windows' one,... or whatever reason you could fit in there !
Let's see if this is the same when we run PgBench instead of just the initialization.
For the sake of sanity, I rounded some of PgBench's results but they are all available on my github.
Duration (sec) | TRANS WS | TRANS LS | TPS WS | TPS LS | diff tps | |
---|---|---|---|---|---|---|
a.2 | 240 | 128472 | 109535 | 535 | 456 | 17,32 |
a.3 | 240 | 328471 | 320108 | 1301 | 1333 | -2,40 |
a.4 | 240 | 382147 | 365494 | 1592 | 1522 | 4,60 |
a.6 | 240 | 421287 | 399478 | 1714 | 1663 | 3,07 |
a.7 | 240 | 468761 | 425839 | 1952 | 1774 | 10,03 |
b.3 | 240 | 291803 | 294441 | 1204 | 1226 | -1,79 |
b.4 | 1200 | 751647 | 1077216 | 626 | 896 | -30,13 |
c.3 | 2400 | 1296582 | 773482 | 540 | 321 | 68,22 |
a.6
a.6 is a.5 after restart and setting max_connections to 300.Now I'm in the fog .
How come pushing the max_connections to 300 allowed the tps to rise ?
I guess that's because I restarted the PostgreSQL process
Please note that I haven't used the -C parameter so there should only be one connection per client. (So a max of 42)
PgBench's doc :
-C
Establish a new connection for each transaction, rather than doing it just once per client session.
b.4
A scale a 1000 makes a db of +-16gb so I guess a big chunk of it can fit in the memory during the whole process and that Linux'S memory management is better than what some may think.c.3
That one made my jaw drop !Windows made 68% more TPS than Linux under heavy load for a long time.
I couldn't believe it so I waited one week and did it again.
Duration (sec) | TRANS WS | TRANS LS | TPS WS | TPS LS | diff tps | |
---|---|---|---|---|---|---|
c.3.2 | 2400 | 1303677 | 844387 | 542 | 351 | 54,42 |
Linux went up 10% but Windows stood almost the same for a new diff of 54%.
So on both C.3 test, we have almost 61% diff in favor of Windows.
Summary
Basically, windows is 5% faster with a scale of 500 , 30% slower with a scale of 1000 and 61% faster with a scale of 2000.I discussed about it with my colleagues and one of them said :
"Of course you noob, you have to tune Linux a minimum to reach the best perf !"
My answer was :
"No. That's the goal of my exercise.
I don't want a Linux specialist fiddling for 6 weeks to have a top notch server, nor do I want a Windows specialist to fiddle for 6 weeks for the same reason.
Moreover, if I'm using the cloud, there's a lot of area that I won't be able to tune. (Disk, network, ...)"
In my previous post, I said that Linux and Windows are at par when it comes to PostgreSQL performance.
After this second test I'm forced to say :
- You have Linux infrastructure and no Windows, use PostgreSQL on Linux !
- You have Windows infrastructure and no Linux, use PostgreSQL on Windows !
- You have both, well it depends... you should hire a specialist to help you !
Which means, for me, they are at par.
Follow-up from the boutade from my first post, PostgreSQL in Linux in a VM in Windows is NOT faster than PostgreSQL on the same Windows, not at all !
What do you think ?
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.
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.
Donc, avant de trop utiliser PostgreSQL sous Windows, je voulais être certain que cette solution soit la meilleure option, principalement pour les facteurs suivants :
Donc, pour chacun des points précédents, j'ai conclu que
Donc, comment trouver le chaînon manquant ??? Je vais mesurer moi-même!
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;
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.
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.
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.
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...)
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.
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.
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 :
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 :
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.
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.
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 :
- 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).
- Elle doit être solide..
- Elle doit être efficace.
Donc, pour chacun des points précédents, j'ai conclu que
- 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)
- 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.
- 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.
mardi 5 janvier 2016
PostgreSQL : Linux VS Windows
In September, I was in Paris for the Postgresql Sessions, invited there by Dalibo.
Thanks again ! It was definitely a life-changing event for me !
While discussing with some of Dalibo's employees, one of them made a remark that triggered my internal challenge instinct.
He said that postgresql in Linux in a VM in Windows is faster than PostgreSQL on the same Windows.
As I'm new in the postgresql/linux world, I was baffled by this information but when I requested numbers for it, he had none.
I understood that it's was just a boutade (I'm quick to understand when one explains it multiple times) and that he just meant that PostgreSQL on Linux was faster than on Windows.
Linux can fork while Windows can't !
But WTF is a fork ?
With a quick summary, a fork is a system call that allows a process to create child processes of itself and both new processes keep on their businesses.
They can both share their memory and communicate together.
This is a standard development technique in the Unix/Linux environment, but this is not standard at all for windows... as fork doesn't exist in windows.
It doesn't exist and you shouldn't try to do it, this is not standard architecture for windows application.
If you're building an application with this kind of architecture on windows, it should be based on thread instead, or even better, if you're building it in .NET, you should build it with async !
But if fork doesn't exist on windows but the postgresql code is the same for linux and windows, and that it forks in linux, what does it do ?
Well the brilliant PostgreSQL developer created a system for windows that emulates the fork ... with threads !
Kudos to them for that, because now we have postgresql on Windows !
But let's come back to the boutade, it is supposed that because of this custom "fork", PostgreSQL on Windows is slower than on Linux.
As with the popular "Pics or it didn't happen", I was craving for numbers to have a proof for that.
The only benchmark I could find is one from RedHat, found on the developpez.net forum.
Some may say that it's not entirely impartial due to the fact that it was made by RedHat.
So before going further with PostgreSQL on Windows for our new apps, I wanted to be sure that it was the best option because :
If we had to move to Linux, maybe the best time is at the start, not the end...
So, for each point, I came to the conclusion that :
So what can I do to find the missing link ??? Do a benchmark myself !
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;
The client "application" is composed of 3 console apps that launches 5000 tasks each, available on github https://github.com/jmguazzo/TestPostgresqlPerf.
Each task does 1 select and 1 update of a random record on the table_a.
The output of the application is composed of the following resultsApplicationId RunningTasks TaskDuration EndTime
7fef1...c1 31 9530868 03:46:01
The tasks duration value is in Ticks but I took the liberty to convert it to seconds while analyzing the results.
The console application is in C# and uses NPGSQL 3.0.3.
Postgresql 9.4.5 installed with the wizard.
I changed the max_connections to 300, listen_addresses to * and the required changes to pg_hba.conf for the connection to work.
Postgresql 9.4.5 installed with yum.(I had to google that part a little as this was quite new for me!)
I made the same changes for postgresql.conf and pg_hba.conf as the one I made for Windows.
My laptop
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.
From there, I'm baffled, Linux is definitely faster.
(And now that we know that my laptop's quite slow, I won't include it in other results...)
As explained before, the test consist of 15.000 executions of 1 SELECT and 1 UPDATE.
While running the test on LS, I had 8 "Timeout while getting a connection from pool" errors.
And to be honest, I expected to have more errors with Windows than Linux, so I guess that's another flabbergasting based on assumptions...
When an error occurs during an execution, my projects output a -1 for duration as shown hereunder :
7fef1...c1 31 541229671 03:47:09
7fef1...c1 31 -1 00:00:00
Therefore, I have to remove those 8 executions from my statistical analysis, and I will remove 8 executions from the WS results.
I was quite puzzled for deciding which one to remove so I removed them around the median value.
So what can we assume from this ?
On the Minimum duration, WS was almost 15% faster but on the Maximum, it was 10% slower than LS.
For the average duration, WS was 1% slower than LS. But as the saying goes, if my head is in the oven and my feet in the fridge, on average I'm good !
Due to the median being at the half of the results and the fact that we have 14992 valid results (15000 - 8 errors), the median is at result n° 7496.
WS is 10% faster if we look at the time only; but if we look at the full results, I had to get to the WS execution n° 8543 to have a duration of 0,93746 sec.
So more than 1000 executions on WS ran faster than the median on LS.
I find it always difficult to measure hardware precisely as, for me, analyzing it while using it is close to Schrödinger's Cat !
I was more obsessed with response time as my memory was always ringing this research from Jakob Nielsen that give the following limits for response time :
I took the hypothesis that if your DB + your Web Server must respond in less than 10 sec, I'd give half the time to the DB and therefore :
There's only a 0.001% difference between WS executions and LS.
And for both systems, more than 99% of executions took less than 5 sec.
The infrastructure I used was on Amazon and my results may have been impacted by some actions outside of my control... which, by the way, will always be the case when you're using the cloud.
Moreover, the differences aren't statistically significant IMHO, but you could always debate.
With those results, I won't say that PostgreSQL on one OS is faster than on the other.
And, to answer my own request, I won't advise my client to migrate to Linux because of PostgreSQL performance. (You could argue that there are more tools for PostgreSQL on Linux than on Windows but that was not the point here)
For me, PostgreSQL performance on Windows is not better nor worst, it's at par with Linux !
All the results are available on my github.
Thanks again ! It was definitely a life-changing event for me !
While discussing with some of Dalibo's employees, one of them made a remark that triggered my internal challenge instinct.
He said that postgresql in Linux in a VM in Windows is faster than PostgreSQL on the same Windows.
As I'm new in the postgresql/linux world, I was baffled by this information but when I requested numbers for it, he had none.
I understood that it's was just a boutade (I'm quick to understand when one explains it multiple times) and that he just meant that PostgreSQL on Linux was faster than on Windows.
Linux architecture vs Windows architecture.
To understand his speed claim, one has to understand the main difference regarding architectural design between Windows and Linux.Linux can fork while Windows can't !
But WTF is a fork ?
With a quick summary, a fork is a system call that allows a process to create child processes of itself and both new processes keep on their businesses.
They can both share their memory and communicate together.
This is a standard development technique in the Unix/Linux environment, but this is not standard at all for windows... as fork doesn't exist in windows.
It doesn't exist and you shouldn't try to do it, this is not standard architecture for windows application.
If you're building an application with this kind of architecture on windows, it should be based on thread instead, or even better, if you're building it in .NET, you should build it with async !
But if fork doesn't exist on windows but the postgresql code is the same for linux and windows, and that it forks in linux, what does it do ?
Well the brilliant PostgreSQL developer created a system for windows that emulates the fork ... with threads !
Kudos to them for that, because now we have postgresql on Windows !
But let's come back to the boutade, it is supposed that because of this custom "fork", PostgreSQL on Windows is slower than on Linux.
As with the popular "Pics or it didn't happen", I was craving for numbers to have a proof for that.
The only benchmark I could find is one from RedHat, found on the developpez.net forum.
Some may say that it's not entirely impartial due to the fact that it was made by RedHat.
The Situation.
The client I'm currently working for as a FULL Windows infrastructure and they are planning to have more and more PostgreSQL because .. $ORACLE$ !So before going further with PostgreSQL on Windows for our new apps, I wanted to be sure that it was the best option because :
- It has to withstand time ! (We are currently working with a system that was written in 1993, the year the mosaic browser and the first Pentium cpu were released !Therefore, with a little extrapolation, the new apps we're building now will still be working in 2037).
- It has to be reliable.
- It has to be efficient.
If we had to move to Linux, maybe the best time is at the start, not the end...
So, for each point, I came to the conclusion that :
- Windows and Linux where there in 1993 and are still here, so that's fine for me. (Windows NT and Slackware both started in 1993)
- PostgreSQL started in 1995 and a lot of users are using it now without issues and recently Gartner has put them in the leader quadrant, so this is also fine for me.
- That's the missing link, I don't know for sure that it's better on Linux or Windows.
So what can I do to find the missing link ??? Do a benchmark myself !
The benchmark
For this benchmark, I want :- A very simple scenario
- To isolate the benchmarked components.
- To see if PostgreSQL on Linux is faster/slower than on Windows with the same client. (Because I want to test the server !)
- To be the closest possible to a "real life" scenario.
- To be in the cloud. Why ? Because a lot of future apps will be built in the cloud... and I don't have a sufficient infrastructure at home to test it.
"The database"
Remember KISS ? (Not that 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;
"The Client "
Windows 2012 R2 server on amazon, m4.xlarge type, with all the default settings.The client "application" is composed of 3 console apps that launches 5000 tasks each, available on github https://github.com/jmguazzo/TestPostgresqlPerf.
Each task does 1 select and 1 update of a random record on the table_a.
The output of the application is composed of the following resultsApplicationId RunningTasks TaskDuration EndTime
7fef1...c1 31 9530868 03:46:01
The tasks duration value is in Ticks but I took the liberty to convert it to seconds while analyzing the results.
The console application is in C# and uses NPGSQL 3.0.3.
"The Windows Postgresql Server " aka WS
Windows 2012 R2 server on amazon, m4.xlarge type, with all the default settings.Postgresql 9.4.5 installed with the wizard.
I changed the max_connections to 300, listen_addresses to * and the required changes to pg_hba.conf for the connection to work.
"The Linux Postgresql Server " aka LS
Amazon Linux AMI, m4.xlarge type, with all the default settings.Postgresql 9.4.5 installed with yum.(I had to google that part a little as this was quite new for me!)
I made the same changes for postgresql.conf and pg_hba.conf as the one I made for Windows.
Results
For a simple "mise en bouche", here are the execution time for the creation of the tableMy laptop
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.
From there, I'm baffled, Linux is definitely faster.
(And now that we know that my laptop's quite slow, I won't include it in other results...)
Total Executions
As explained before, the test consist of 15.000 executions of 1 SELECT and 1 UPDATE.
While running the test on LS, I had 8 "Timeout while getting a connection from pool" errors.
And to be honest, I expected to have more errors with Windows than Linux, so I guess that's another flabbergasting based on assumptions...
When an error occurs during an execution, my projects output a -1 for duration as shown hereunder :
7fef1...c1 31 541229671 03:47:09
7fef1...c1 31 -1 00:00:00
Therefore, I have to remove those 8 executions from my statistical analysis, and I will remove 8 executions from the WS results.
I was quite puzzled for deciding which one to remove so I removed them around the median value.
Durations
Server | Minimum | Maximum | Average | Median |
---|---|---|---|---|
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 |
So what can we assume from this ?
On the Minimum duration, WS was almost 15% faster but on the Maximum, it was 10% slower than LS.
For the average duration, WS was 1% slower than LS. But as the saying goes, if my head is in the oven and my feet in the fridge, on average I'm good !
Due to the median being at the half of the results and the fact that we have 14992 valid results (15000 - 8 errors), the median is at result n° 7496.
WS is 10% faster if we look at the time only; but if we look at the full results, I had to get to the WS execution n° 8543 to have a duration of 0,93746 sec.
So more than 1000 executions on WS ran faster than the median on LS.
Response Time vs Throughput
I didn't want to analyze traffic/throughput because most of the time, it's useless, especially regarding the application I made and the fact that I'm using the cloud.I find it always difficult to measure hardware precisely as, for me, analyzing it while using it is close to Schrödinger's Cat !
I was more obsessed with response time as my memory was always ringing this research from Jakob Nielsen that give the following limits for response time :
- 0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.
- 1.0 second is about the limit for the user's flow of thought to stay uninterrupted, even though the user will notice the delay. Normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data.
- 10 seconds is about the limit for keeping the user's attention focused on the dialogue. For longer delays, users will want to perform other tasks while waiting for the computer to finish, so they should be given feedback indicating when the computer expects to be done. Feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect.
I took the hypothesis that if your DB + your Web Server must respond in less than 10 sec, I'd give half the time to the DB and therefore :
Server | Quantity of execution faster than 5 sec |
WS | 14913 |
LS | 14926 |
There's only a 0.001% difference between WS executions and LS.
And for both systems, more than 99% of executions took less than 5 sec.
Let's put it all together
Windows | Linux | Winner | |
Number of executions | 15.000 | 15.000 | Both ! |
Number of errors | 0 | 8 | Windows |
Minimum duration | 0,1093749 sec | 0,1249964 sec | Windows |
Maximum duration | 121,6842917 sec | 108,2615642 sec | Linux |
Average duration | 1,0363515 sec | 1,0234334 sec | Linux |
Median duration | 0,8280406 sec | 0,9374624 sec | Windows |
Quantity of execution faster than 5 sec | 14913 | 14926 | Linux |
The infrastructure I used was on Amazon and my results may have been impacted by some actions outside of my control... which, by the way, will always be the case when you're using the cloud.
Moreover, the differences aren't statistically significant IMHO, but you could always debate.
With those results, I won't say that PostgreSQL on one OS is faster than on the other.
And, to answer my own request, I won't advise my client to migrate to Linux because of PostgreSQL performance. (You could argue that there are more tools for PostgreSQL on Linux than on Windows but that was not the point here)
For me, PostgreSQL performance on Windows is not better nor worst, it's at par with Linux !
All the results are available on my github.
dimanche 15 novembre 2015
pg_empty
Empty Visual Studio 2013 project/solution for developping PostgreSQL extensions.
See https://github.com/jmguazzo/pg_empty
See https://github.com/jmguazzo/pg_empty
pg_wintools
I've released pg_wintools, a set of extension that allows easier integration of PostgreSQL in the windows ecosystem.
Because sometimes, not using Windows is not an option...
Functionnalities in this release :
- pg_read_registry : read a value from the registry.
- pg_write_event_log_entry : write an event to the eventlog.
- pg_fixed_drives_list : get the list of fixed drives and their size/free space
- pg_file_exists : check whether a file exists locally or on the network with a unc in the form \\server\share.
-
pg_hostname : return the hostname of the server.(Very useful if you're
using DNS entry for your server instead of it's name/ip)
This is a beta release as the project needs testers !
Everything is available at https://github.com/jmguazzo/ pg_wintools.
There's no install available for now, it must be build with Visual Studio 2013 (or above), the howto is documented.
It has been tested on PostgreSQL 9.4 64bits and 9.5b 32bits on 64bits Windows 10, 8, Server 2012 R2 and Server 2008 R2.
Thanks to Craig Ringer and his excellent post about compiling on Windows.
samedi 10 octobre 2015
pg_cmdshell
J'ai réalisé une extension pour PostgreSQL qui permet d'exécuter des instructions dans l'OS comme le fait xp_cmdshell dans SQL Server.
Elle est disponible sur GIT : https://github.com/jmguazzo/pg_cmdshell/
Exemple d'utilisation :
select pg_cmdshell('tasklist')
Elle est disponible sur GIT : https://github.com/jmguazzo/pg_cmdshell/
Exemple d'utilisation :
- Obtenir la liste des tâches en cours
select pg_cmdshell('tasklist')
- Obtenir des détails sur le système d'exploitation
S'abonner à :
Messages (Atom)