mercredi 8 mai 2013

async_commit=off

J'expérimente ces temps-ci avec l'option "async_commit=off" de Postgresql. Cette option indique au serveur de rendre la main au client dès que le commit est effectué en mémoire, sans attendre que les données soient effectivement écrites sur le disque. L intérêt est donc de découpler la vitesse d'écriture sur le disque dur, et donc de diminuer la latence et d'augmenter le nombre de transactions par seconde.

En contrepartie, si le serveur venait à crasher, quelques secondes de données seraient perdues. Si cette contrainte est acceptable, par exemple parce que les données sont mises à jour régulièrement, ou parce que plusieurs bases tournent derrière un pgPool, c'est un sacré coup de boost.

Voici un petit benchmark qui fait tourner en boucle 1000 transactions, chaque transaction insérant un entier dans une table faite d'une simple colonne, sans contraintes. Le test tourne en local et en distant sur une machine avec lequel j'ai un ping de 200ms, avec synchronous_commit=off et synchronous_commit=on.

L'on voit que les performances augmentent d'environ 30% en local, ce qui est tout à fait appréciable. Mais l'autre chiffre intéressant est la grosse chute de performances en distant: le gain du commit asynchrone reste à peu près identique en relatif, mais la chute est rude. Le fait d'avoir à faire l'aller-retour pour chaque transaction est très coûteux.

La conclusion, c'est que s'il est possible de relâcher ses contraintes d'intégrité, synchronous_commit=off est une manière simple d'obtenir un impressionnant gain de performances. Mais c'est aussi que dans le cas de nombreuses petites transactions, le goulot d'étranglement se trouve sur le réseau, et non sur le disque ou le processeur. Dans ce cas, peut-on imaginer de faire tourner une base en local pour les performances, qui se répliquerait de manière asynchrone sur une base distante utilisée pour le basculement lors d'un crash?

Aucun commentaire: