J'ai publié plusieurs benchmarks comparant différentes versions de PostgreSQL, comme par exemple le discours d'archéologie des performances (évaluant PostgreSQL 7.4 jusqu'à 9.4), et tous ces benchmarks supposant un environnement fixe (matériel, noyau, …). Ce qui est bien dans de nombreux cas (par exemple, lors de l'évaluation de l'impact d'un correctif sur les performances), mais en production, ces éléments changent avec le temps :vous obtenez des mises à niveau matérielles et de temps en temps, vous obtenez une mise à jour avec une nouvelle version du noyau.
Pour les mises à niveau matérielles (meilleur stockage, plus de RAM, des processeurs plus rapides, …), l'impact est généralement assez facile à prévoir, et de plus, les gens réalisent généralement qu'ils doivent évaluer l'impact en analysant les goulots d'étranglement sur la production et peut-être même en testant d'abord le nouveau matériel. .
Mais qu'en est-il des mises à jour du noyau ? Malheureusement, nous ne faisons généralement pas beaucoup d'analyse comparative dans ce domaine. L'hypothèse est principalement que les nouveaux noyaux sont meilleurs que les anciens (plus rapides, plus efficaces, s'adaptent à plus de cœurs de processeur). Mais est-ce vraiment vrai? Et quelle est la différence? Par exemple, que se passe-t-il si vous mettez à niveau un noyau de 3.0 à 4.7 - cela affectera-t-il les performances, et si oui, les performances s'amélioreront-elles ou non ?
De temps en temps, nous recevons des rapports sur des régressions sérieuses avec une version particulière du noyau, ou une amélioration soudaine entre les versions du noyau. Il est donc clair que les versions du noyau peuvent affecter les performances.
Je connais un seul benchmark PostgreSQL comparant différentes versions du noyau, réalisé en 2014 par Sergey Konoplev en réponse aux recommandations d'éviter les noyaux 3.0 - 3.8. Mais ce benchmark est assez ancien (la dernière version du noyau disponible il y a environ 18 mois était la 3.13, alors qu'aujourd'hui nous avons 3.19 et 4.6), j'ai donc décidé d'exécuter quelques benchmarks avec les noyaux actuels (et PostgreSQL 9.6beta1).
PostgreSQL et versions du noyau
Mais d'abord, permettez-moi de discuter de quelques différences significatives entre les politiques régissant les commits dans les deux projets. Dans PostgreSQL, nous avons le concept de versions majeures et mineures - les versions majeures (par exemple 9.5) sont publiées environ une fois par an et incluent diverses nouvelles fonctionnalités. Les versions mineures (par exemple 9.5.2) n'incluent que des corrections de bogues et sont publiées environ tous les trois mois (ou plus fréquemment, lorsqu'un bogue grave est découvert). Il ne devrait donc pas y avoir de changement majeur de performances ou de comportement entre les versions mineures, ce qui permet de déployer des versions mineures en toute sécurité sans tests approfondis.
Avec les versions du noyau, la situation est beaucoup moins claire. Le noyau Linux a également des branches (par exemple 2.6, 3.0 ou 4.7), celles-ci ne sont en aucun cas équivalentes aux "versions majeures" de PostgreSQL, car elles continuent de recevoir de nouvelles fonctionnalités et pas seulement des corrections de bogues. Je ne prétends pas que la politique de gestion des versions de PostgreSQL est en quelque sorte automatiquement supérieure, mais la conséquence est que la mise à jour entre les versions mineures du noyau peut facilement affecter de manière significative les performances ou même introduire des bogues (par exemple, 3.18.37 souffre de problèmes OOM en raison d'un tel non-bugfix valider).
Bien sûr, les distributions réalisent ces risques et verrouillent souvent la version du noyau et effectuent des tests supplémentaires pour éliminer les nouveaux bogues. Cet article utilise cependant des noyaux vanille à long terme, disponibles sur www.kernel.org.
Référence
Il existe de nombreux benchmarks que nous pourrions utiliser - cet article présente une suite de tests pgbench, c'est-à-dire un benchmark OLTP (TPC-B-like) assez simple. Je prévois de faire des tests supplémentaires avec d'autres types de benchmarks (en particulier orientés DWH/DSS), et je les présenterai sur ce blog à l'avenir.
Maintenant, revenons au pgbench - quand je dis "collection de tests", je veux dire des combinaisons de
- lecture seule ou lecture-écriture
- taille de l'ensemble de données – l'ensemble actif ne tient (pas) dans les tampons partagés/la RAM
- nombre de clients :un seul client par rapport à plusieurs clients (verrouillage/planification)
Les valeurs dépendent évidemment du matériel utilisé, voyons donc sur quel matériel cette série de benchmarks fonctionnait :
- Processeur :Intel i5-2 500 k à 3,3 GHz (turbo 3,7 GHz)
- RAM :8 Go (DDR3 à 1 333 MHz)
- stockage :6x Intel SSD DC S3700 en RAID-10 (Linux sw raid)
- système de fichiers :ext4 avec planificateur d'E/S par défaut (cfq)
C'est donc la même machine que j'ai utilisée pour un certain nombre de benchmarks précédents - une machine assez petite, pas exactement le processeur le plus récent, etc., mais je pense que c'est toujours un "petit" système raisonnable.
Les paramètres de référence sont :
- Échelles des ensembles de données :30, 300 et 1 500 (soit environ 450 Mo, 4,5 Go et 22,5 Go)
- nombre de clients :1, 4, 16 (la machine a 4 cœurs)
Pour chaque combinaison, il y avait 3 exécutions en lecture seule (15 minutes chacune) et 3 exécutions en lecture-écriture (30 minutes chacune). Le script réel qui pilote le benchmark est disponible ici (ainsi que les résultats et d'autres données utiles).
Remarque :Si vous avez un matériel très différent (par exemple, des disques rotatifs), vous pouvez voir des résultats très différents. Si vous avez un système que vous aimeriez tester, faites-le moi savoir et je vous aiderai (en supposant que je serai autorisé à publier les résultats).
Versions du noyau
Concernant les versions du noyau, j'ai testé les dernières versions dans toutes les branches à long terme depuis 2.6.x (2.6.39, 3.0.101, 3.2.81, 3.4.112, 3.10.102, 3.12.61, 3.14.73, 3.16. 36, 3.18.38, 4.1.29, 4.4.16, 4.6.5 et 4.7). Il y a encore beaucoup de systèmes fonctionnant sur des noyaux 2.6.x, il est donc utile de savoir combien de performances vous pourriez gagner (ou perdre) en mettant à niveau vers un noyau plus récent. Mais j'ai compilé tous les noyaux par moi-même (c'est-à-dire en utilisant des noyaux vanille, pas de correctifs spécifiques à la distribution), et les fichiers de configuration se trouvent dans le référentiel git.
Résultats
Comme d'habitude, toutes les données sont disponibles sur bitbucket, y compris
- fichier .config du noyau
- script de référence (run-pgbench.sh)
- Configuration PostgreSQL (avec quelques réglages de base pour le matériel)
- Journaux PostgreSQL
- divers journaux système (dmesg, sysctl, mount, …)
Les graphiques suivants montrent les tps moyens pour chaque cas de référence. Les résultats des trois exécutions sont assez cohérents, avec une différence d'environ 2 % entre le min et le max dans la plupart des cas.
lecture seule
Pour le plus petit ensemble de données, il y a une baisse nette des performances entre 3,4 et 3,10 pour tous les comptes de clients. Les résultats pour 16 clients (4 x le nombre de cœurs) sont toutefois largement récupérés dans la version 3.12.
Pour l'ensemble de données moyen (convient à la RAM mais pas aux tampons partagés), nous pouvons voir la même baisse entre 3.4 et 3.10 mais pas la reprise en 3.12.
Pour les grands ensembles de données (dépassant la RAM, donc fortement liés aux E / S), les résultats sont très différents - je ne sais pas ce qui s'est passé entre 3.10 et 3.12, mais l'amélioration des performances (en particulier pour un nombre de clients plus élevé) est assez étonnant.
lecture-écriture
Pour la charge de travail en lecture-écriture, les résultats sont assez similaires. Pour les petits et moyens ensembles de données, nous pouvons observer la même baisse d'environ 10 % entre 3.4 et 3.10, mais malheureusement aucune reprise dans 3.12.
Pour le grand ensemble de données (encore une fois, lié de manière significative aux E/S), nous pouvons constater une amélioration similaire dans la version 3.12 (pas aussi significative que pour la charge de travail en lecture seule, mais toujours significative) :
Résumé
Je n'ose pas tirer de conclusions à partir d'un seul benchmark sur une seule machine, mais je pense qu'il est prudent de dire :
- Les performances globales sont assez stables, mais nous pouvons constater des changements de performances significatifs (dans les deux sens).
- Avec des ensembles de données qui tiennent dans la mémoire (soit dans les buffers partagés, soit au moins dans la RAM), nous constatons une baisse mesurable des performances entre 3,4 et 3,10. Lors d'un test en lecture seule, cela récupère partiellement dans la version 3.12 (mais uniquement pour de nombreux clients).
- Avec des ensembles de données dépassant la mémoire, et donc principalement liés aux E/S, nous ne constatons pas de telles baisses de performances, mais plutôt une amélioration significative dans la version 3.12.
Quant aux raisons pour lesquelles ces changements soudains se produisent, je ne suis pas tout à fait sûr. Il existe de nombreux commits potentiellement pertinents entre les versions, mais je ne sais pas comment identifier le bon sans tests approfondis (et chronophages). Si vous avez d'autres idées (par exemple, si vous êtes au courant de tels commits), faites-le moi savoir.