MariaDB
 sql >> Base de données >  >> RDS >> MariaDB

Comment évaluer les performances de MySQL et MariaDB à l'aide de SysBench

Qu'est-ce que SysBench ? Si vous travaillez régulièrement avec MySQL, vous en avez probablement entendu parler. SysBench fait partie de l'écosystème MySQL depuis longtemps. Il a été écrit à l'origine par Peter Zaitsev, en 2004. Son objectif était de fournir un outil permettant d'exécuter des benchmarks synthétiques de MySQL et du matériel sur lequel il s'exécute. Il a été conçu pour exécuter des tests de CPU, de mémoire et d'E/S. Il avait également une option pour exécuter la charge de travail OLTP sur une base de données MySQL. OLTP signifie traitement des transactions en ligne, charge de travail typique pour les applications en ligne telles que le commerce électronique, la saisie des commandes ou les systèmes de transactions financières.

Dans cet article de blog, nous nous concentrerons sur la fonctionnalité de benchmark SQL, mais gardez à l'esprit que les benchmarks matériels peuvent également être très utiles pour identifier les problèmes sur les serveurs de base de données. Par exemple, le benchmark d'E/S visait à simuler la charge de travail d'E/S d'InnoDB, tandis que les tests de CPU impliquent la simulation d'un environnement hautement simultané et multi-tread ainsi que des tests pour les conflits de mutex - quelque chose qui ressemble également à un type de charge de travail de base de données.

Histoire et architecture de SysBench

Comme mentionné, SysBench a été initialement créé en 2004 par Peter Zaitsev. Peu de temps après, Alexey Kopytov a repris son développement. Il a atteint la version 0.4.12 et le développement s'est arrêté. Après une longue pause, Alexey a recommencé à travailler sur SysBench en 2016. Bientôt, la version 0.5 a été publiée avec le benchmark OLTP réécrit pour utiliser des scripts basés sur LUA. Puis, en 2017, SysBench 1.0 est sorti. C'était comme le jour et la nuit par rapport à l'ancienne version 0.4.12. Tout d'abord, au lieu de scripts codés en dur, nous avons maintenant la possibilité de personnaliser les benchmarks à l'aide de LUA. Par exemple, Percona a créé un benchmark de type TPCC qui peut être exécuté à l'aide de SysBench. Jetons un coup d'œil à l'architecture actuelle de SysBench.

SysBench est un binaire C qui utilise des scripts LUA pour exécuter des benchmarks. Ces scripts doivent :

  1. Gérer les entrées des paramètres de ligne de commande
  2. Définir tous les modes que le benchmark est censé utiliser (préparer, exécuter, nettoyer)
  3. Préparer toutes les données
  4. Définissez comment le benchmark sera exécuté (à quoi ressembleront les requêtes, etc.)

Les scripts peuvent utiliser plusieurs connexions à la base de données, ils peuvent également traiter les résultats si vous souhaitez créer des benchmarks complexes où les requêtes dépendent de l'ensemble de résultats des requêtes précédentes. Avec SysBench 1.0, il est possible de créer des histogrammes de latence. Il est également possible pour les scripts LUA d'intercepter et de gérer les erreurs via des crochets d'erreur. La parallélisation est prise en charge dans les scripts LUA, plusieurs requêtes peuvent être exécutées en parallèle, ce qui rend, par exemple, le provisionnement beaucoup plus rapide. Enfin, plusieurs formats de sortie sont désormais pris en charge. Avant, SysBench ne générait qu'une sortie lisible par l'homme. Il est désormais possible de le générer au format CSV ou JSON, ce qui facilite grandement le post-traitement et la génération de graphiques en utilisant, par exemple, gnuplot ou en injectant les données dans Prometheus, Graphite ou un magasin de données similaire.

Pourquoi SysBench ?

La principale raison pour laquelle SysBench est devenu populaire est le fait qu'il est simple à utiliser. Quelqu'un sans connaissances préalables peut commencer à l'utiliser en quelques minutes. Il fournit également, par défaut, des benchmarks qui couvrent la plupart des cas :charges de travail OLTP, lecture seule ou lecture-écriture, recherches de clé primaire et mises à jour de clé primaire. Tout cela a causé la plupart des problèmes pour MySQL, jusqu'à MySQL 8.0. C'était aussi une des raisons pour lesquelles SysBench était si populaire dans différents benchmarks et comparaisons publiés sur Internet. Ces messages ont aidé à promouvoir cet outil et en ont fait la référence synthétique incontournable pour MySQL.

Une autre bonne chose à propos de SysBench est que, depuis la version 0.5 et l'incorporation de LUA, n'importe qui peut préparer n'importe quel type de benchmark. Nous avons déjà mentionné une référence de type TPCC, mais n'importe qui peut créer quelque chose qui ressemblera à sa charge de travail de production. Nous ne disons pas que c'est simple, ce sera très probablement un processus qui prendra du temps, mais avoir cette capacité est bénéfique si vous avez besoin de préparer un benchmark personnalisé.

En tant que référence synthétique, SysBench n'est pas un outil que vous pouvez utiliser pour régler les configurations de vos serveurs MySQL (sauf si vous avez préparé des scripts LUA avec une charge de travail personnalisée ou si votre charge de travail est très similaire aux charges de travail de référence fournies avec SysBench). Ce qui est génial, c'est de comparer les performances de différents matériels. Vous pouvez facilement comparer les performances de, disons, différents types de nœuds proposés par votre fournisseur de cloud et le nombre maximal de QPS (requêtes par seconde) qu'ils offrent. Connaissant cette métrique et sachant ce que vous payez pour un nœud donné, vous pouvez alors calculer une métrique encore plus importante - QP $ (requêtes par dollar). Cela vous permettra d'identifier le type de nœud à utiliser lors de la création d'un environnement rentable. Bien sûr, SysBench peut également être utilisé pour le réglage initial et l'évaluation de la faisabilité d'une conception donnée. Disons que nous construisons un cluster Galera couvrant le monde entier - Amérique du Nord, UE, Asie. Combien d'insertions par seconde une telle configuration peut-elle gérer ? Quelle serait la latence de validation ? Est-il même judicieux de faire une preuve de concept ou peut-être que la latence du réseau est suffisamment élevée pour que même une simple charge de travail ne fonctionne pas comme prévu ?

Qu'en est-il des tests de résistance ? Tout le monde n'est pas passé au cloud, il y a encore des entreprises qui préfèrent construire leur propre infrastructure. Chaque nouveau serveur acquis doit passer par une période de préchauffage au cours de laquelle vous le solliciterez pour identifier les défauts matériels potentiels. Dans ce cas, SysBench peut également aider. Soit en exécutant une charge de travail OLTP qui surcharge le serveur, soit vous pouvez également utiliser des benchmarks dédiés pour le processeur, le disque et la mémoire.

Comme vous pouvez le constater, il existe de nombreux cas dans lesquels même un simple benchmark synthétique peut être très utile. Dans le paragraphe suivant, nous verrons ce que nous pouvons faire avec SysBench.

Qu'est-ce que SysBench peut faire pour vous ?

Quels tests pouvez-vous exécuter ?

Comme mentionné au début, nous nous concentrerons sur les benchmarks OLTP et pour rappel, nous répéterons que SysBench peut également être utilisé pour effectuer des tests d'E/S, de CPU et de mémoire. Jetons un coup d'œil aux benchmarks fournis avec SysBench 1.0 (nous avons supprimé certains fichiers LUA d'assistance et les scripts LUA non liés à la base de données de cette liste).

-rwxr-xr-x 1 root root 1.5K May 30 07:46 bulk_insert.lua
-rwxr-xr-x 1 root root 1.3K May 30 07:46 oltp_delete.lua
-rwxr-xr-x 1 root root 2.4K May 30 07:46 oltp_insert.lua
-rwxr-xr-x 1 root root 1.3K May 30 07:46 oltp_point_select.lua
-rwxr-xr-x 1 root root 1.7K May 30 07:46 oltp_read_only.lua
-rwxr-xr-x 1 root root 1.8K May 30 07:46 oltp_read_write.lua
-rwxr-xr-x 1 root root 1.1K May 30 07:46 oltp_update_index.lua
-rwxr-xr-x 1 root root 1.2K May 30 07:46 oltp_update_non_index.lua
-rwxr-xr-x 1 root root 1.5K May 30 07:46 oltp_write_only.lua
-rwxr-xr-x 1 root root 1.9K May 30 07:46 select_random_points.lua
-rwxr-xr-x 1 root root 2.1K May 30 07:46 select_random_ranges.lua

Examinons-les un par un.

Tout d'abord, bulk_insert.lua. Ce test peut être utilisé pour évaluer la capacité de MySQL à effectuer des insertions multi-lignes. Cela peut être très utile lors de la vérification, par exemple, des performances de la réplication ou du cluster Galera. Dans le premier cas, cela peut vous aider à répondre à une question :"à quelle vitesse puis-je insérer avant que le décalage de réplication ne se déclenche ?". Dans ce dernier cas, il vous indiquera à quelle vitesse les données peuvent être insérées dans un cluster Galera compte tenu de la latence actuelle du réseau.

Tous les scripts oltp_* partagent une structure de table commune. Les deux premiers d'entre eux (oltp_delete.lua et oltp_insert.lua) exécutent des instructions simples DELETE et INSERT. Encore une fois, cela pourrait être un test pour la réplication ou le cluster Galera - poussez-le à ses limites et voyez quelle quantité d'insertion ou de purge il peut gérer. Nous avons également d'autres benchmarks axés sur des fonctionnalités particulières - oltp_point_select, oltp_update_index et oltp_update_non_index. Ceux-ci exécuteront un sous-ensemble de requêtes - sélections basées sur la clé primaire, mises à jour basées sur l'index et mises à jour non basées sur l'index. Si vous souhaitez tester certaines de ces fonctionnalités, les tests sont là. Nous avons également des benchmarks plus complexes basés sur les charges de travail OLTP :oltp_read_only, oltp_read_write et oltp_write_only. Vous pouvez exécuter soit une charge de travail en lecture seule, qui consistera en différents types de requêtes SELECT, vous pouvez exécuter uniquement des écritures (un mélange de DELETE, INSERT et UPDATE) ou vous pouvez exécuter un mélange de ces deux. Enfin, en utilisant select_random_points et select_random_ranges, vous pouvez exécuter des SELECT aléatoires en utilisant des points aléatoires dans la liste IN() ou des plages aléatoires en utilisant BETWEEN.

Comment configurer un benchmark ?

Ce qui est également important, les benchmarks sont configurables - vous pouvez exécuter différents modèles de charge de travail en utilisant le même benchmark. Jetons un coup d'œil aux deux benchmarks les plus courants à exécuter. Nous aurons une plongée profonde dans les benchmarks OLTP read_only et OLTP read_write. Tout d'abord, SysBench a quelques options de configuration générales. Nous n'aborderons ici que les plus importants, vous pouvez tous les vérifier en exécutant :

sysbench --help

Jetons un coup d'œil à eux.

  --threads=N                     number of threads to use [1]

Vous pouvez définir le type de concurrence que vous souhaitez que SysBench génère. MySQL, comme tout logiciel, a des limites d'évolutivité et ses performances culmineront à un certain niveau de simultanéité. Ce paramètre permet de simuler différentes simultanéités pour une charge de travail donnée et de vérifier si elle a déjà dépassé le point idéal.

  --events=N                      limit for total number of events [0]
  --time=N                        limit for total execution time in seconds [10]

Ces deux paramètres régissent la durée de fonctionnement de SysBench. Il peut soit exécuter un certain nombre de requêtes, soit continuer à fonctionner pendant une durée prédéfinie.

  --warmup-time=N                 execute events for this many seconds with statistics disabled before the actual benchmark run with statistics enabled [0]

Cela va de soi. SysBench génère des résultats statistiques à partir des tests et ces résultats peuvent être affectés si MySQL est à froid. Le préchauffage permet d'identifier un débit "régulier" en exécutant un benchmark pendant une durée prédéfinie, permettant de préchauffer le cache, les pools de mémoire tampon, etc.

  --rate=N                        average transactions rate. 0 for unlimited rate [0]

Par défaut, SysBench tentera d'exécuter les requêtes aussi rapidement que possible. Pour simuler un trafic plus lent, cette option peut être utilisée. Vous pouvez définir ici combien de transactions doivent être exécutées par seconde.

  --report-interval=N             periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0]

Par défaut, SysBench génère un rapport après avoir terminé son exécution et aucune progression n'est signalée pendant l'exécution du benchmark. En utilisant cette option, vous pouvez rendre SysBench plus détaillé pendant que le benchmark continue de fonctionner.

  --rand-type=STRING   random numbers distribution {uniform, gaussian, special, pareto, zipfian} to use by default [special]

SysBench vous permet de générer différents types de distribution de données. Tous peuvent avoir leurs propres objectifs. L'option par défaut, "spécial", définit plusieurs points chauds (configurables) dans les données, ce qui est assez courant dans les applications Web. Vous pouvez également utiliser d'autres distributions si vos données se comportent différemment. En faisant un choix différent ici, vous pouvez également modifier la façon dont votre base de données est sollicitée. Par exemple, la distribution uniforme, où toutes les lignes ont la même probabilité d'être consultées, est une opération beaucoup plus gourmande en mémoire. Il utilisera plus de pool de mémoire tampon pour stocker toutes les données et il sera beaucoup plus gourmand en disque si votre ensemble de données ne tient pas en mémoire. D'autre part, une distribution spéciale avec quelques points chauds mettra moins de pression sur le disque car les lignes chaudes sont plus susceptibles d'être conservées dans le pool de mémoire tampon et l'accès aux lignes stockées sur le disque est beaucoup moins probable. Pour certains des types de distribution de données, SysBench vous donne plus de réglages. Vous pouvez trouver ces informations dans la sortie "sysbench --help".

  --db-ps-mode=STRING prepared statements usage mode {auto, disable} [auto]

En utilisant ce paramètre, vous pouvez décider si SysBench doit utiliser des instructions préparées (tant qu'elles sont disponibles dans le magasin de données donné - pour MySQL, cela signifie que PS sera activé par défaut) ou non. Cela peut faire une différence lorsque vous travaillez avec des proxys tels que ProxySQL ou MaxScale - ils doivent traiter les instructions préparées d'une manière spéciale et tous doivent être acheminés vers un hôte, ce qui rend impossible le test de l'évolutivité du proxy.

En plus des options de configuration générales, chacun des tests peut avoir sa propre configuration. Vous pouvez vérifier ce qui est possible en exécutant :

[email protected]:~# sysbench ./sysbench/src/lua/oltp_read_write.lua  help
sysbench 1.1.0-2e6b7d5 (using bundled LuaJIT 2.1.0-beta3)

oltp_read_only.lua options:
  --distinct_ranges=N           Number of SELECT DISTINCT queries per transaction [1]
  --sum_ranges=N                Number of SELECT SUM() queries per transaction [1]
  --skip_trx[=on|off]           Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]
  --secondary[=on|off]          Use a secondary index in place of the PRIMARY KEY [off]
  --create_secondary[=on|off]   Create a secondary index in addition to the PRIMARY KEY [on]
  --index_updates=N             Number of UPDATE index queries per transaction [1]
  --range_size=N                Range size for range SELECT queries [100]
  --auto_inc[=on|off]           Use AUTO_INCREMENT column as Primary Key (for MySQL), or its alternatives in other DBMS. When disabled, use client-generated IDs [on]
  --delete_inserts=N            Number of DELETE/INSERT combinations per transaction [1]
  --tables=N                    Number of tables [1]
  --mysql_storage_engine=STRING Storage engine, if MySQL is used [innodb]
  --non_index_updates=N         Number of UPDATE non-index queries per transaction [1]
  --table_size=N                Number of rows per table [10000]
  --pgsql_variant=STRING        Use this PostgreSQL variant when running with the PostgreSQL driver. The only currently supported variant is 'redshift'. When enabled, create_secondary is automatically disabled, and delete_inserts is set to 0
  --simple_ranges=N             Number of simple range SELECT queries per transaction [1]
  --order_ranges=N              Number of SELECT ORDER BY queries per transaction [1]
  --range_selects[=on|off]      Enable/disable all range SELECT queries [on]
  --point_selects=N             Number of point SELECT queries per transaction [10]

Encore une fois, nous discuterons des options les plus importantes à partir d'ici. Tout d'abord, vous contrôlez à quoi ressemblera exactement une transaction. D'une manière générale, il se compose de différents types de requêtes - INSERT, DELETE, différents types de SELECT (recherche de point, plage, agrégation) et UPDATE (indexé, non indexé). Utiliser des variables comme :

  --distinct_ranges=N           Number of SELECT DISTINCT queries per transaction [1]
  --sum_ranges=N                Number of SELECT SUM() queries per transaction [1]
  --index_updates=N             Number of UPDATE index queries per transaction [1]
  --delete_inserts=N            Number of DELETE/INSERT combinations per transaction [1]
  --non_index_updates=N         Number of UPDATE non-index queries per transaction [1]
  --simple_ranges=N             Number of simple range SELECT queries per transaction [1]
  --order_ranges=N              Number of SELECT ORDER BY queries per transaction [1]
  --point_selects=N             Number of point SELECT queries per transaction [10]
  --range_selects[=on|off]      Enable/disable all range SELECT queries [on]

Vous pouvez définir à quoi devrait ressembler une transaction. Comme vous pouvez le voir en regardant les valeurs par défaut, la majorité des requêtes sont des SELECT - principalement des sélections ponctuelles mais également différents types de SELECT de plage (vous pouvez tous les désactiver en définissant range_selects sur off). Vous pouvez ajuster la charge de travail vers une charge de travail plus lourde en écriture en augmentant le nombre de mises à jour ou de requêtes INSERT/DELETE. Il est également possible de modifier les paramètres liés aux index secondaires, à l'incrémentation automatique mais aussi à la taille de l'ensemble de données (nombre de tables et combien de lignes chacune d'entre elles doit contenir). Cela vous permet de personnaliser assez bien votre charge de travail.

  --skip_trx[=on|off]           Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]

Il s'agit d'un autre paramètre, très important lorsque vous travaillez avec des proxys. Par défaut, SysBench tentera d'exécuter des requêtes en transaction explicite. De cette façon, l'ensemble de données restera cohérent et non affecté :SysBench exécutera, par exemple, INSERT et DELETE sur la même ligne, en s'assurant que l'ensemble de données ne grandira pas (ce qui affectera votre capacité à reproduire les résultats). Cependant, les proxys traiteront les transactions explicites différemment - toutes les requêtes exécutées dans une transaction doivent être exécutées sur le même hôte, supprimant ainsi la possibilité de faire évoluer la charge de travail. Veuillez garder à l'esprit que la désactivation des transactions entraînera un ensemble de données divergent du point initial. Cela peut également déclencher des problèmes tels que des erreurs de clé en double ou autres. Pour pouvoir désactiver les transactions, vous pouvez également consulter :

  --mysql-ignore-errors=[LIST,...] list of errors to ignore, or "all" [1213,1020,1205]

Ce paramètre vous permet de spécifier les codes d'erreur de MySQL que SysBench doit ignorer (et ne pas couper la connexion). Par exemple, pour ignorer des erreurs telles que :erreur 1062 (Entrée en double '6' pour la clé 'PRIMARY'), vous devez transmettre ce code d'erreur :--mysql-ignore-errors=1062

Ce qui est également important, chaque benchmark doit présenter un moyen de provisionner un ensemble de données pour les tests, de les exécuter, puis de le nettoyer une fois les tests terminés. Cela se fait à l'aide des commandes 'prepare', 'run' et 'cleanup'. Nous montrerons comment cela se fait dans la section suivante.

Exemples

Dans cette section, nous allons passer en revue quelques exemples de ce à quoi SysBench peut être utilisé. Comme mentionné précédemment, nous nous concentrerons sur les deux benchmarks les plus populaires - OLTP en lecture seule et OLTP en lecture/écriture. Parfois, il peut être judicieux d'utiliser d'autres points de repère, mais au moins nous serons en mesure de vous montrer comment ces deux peuvent être personnalisés.

Recherches de clé primaire

Tout d'abord, nous devons décider quel benchmark nous allons exécuter, en lecture seule ou en lecture-écriture. Techniquement parlant, cela ne fait aucune différence car nous pouvons supprimer les écritures du benchmark R/W. Concentrons-nous sur celui en lecture seule.

Dans un premier temps, nous devons préparer un ensemble de données. Nous devons décider de sa taille. Pour ce benchmark particulier, en utilisant les paramètres par défaut (ainsi, des index secondaires sont créés), 1 million de lignes se traduiront par environ 240 Mo de données. Dix tables, 1 000 000 lignes chacune équivaut à 2,4 Go :

[email protected]:~# du -sh /var/lib/mysql/sbtest/
2.4G    /var/lib/mysql/sbtest/
[email protected]:~# ls -alh /var/lib/mysql/sbtest/
total 2.4G
drwxr-x--- 2 mysql mysql 4.0K Jun  1 12:12 .
drwxr-xr-x 6 mysql mysql 4.0K Jun  1 12:10 ..
-rw-r----- 1 mysql mysql   65 Jun  1 12:08 db.opt
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:12 sbtest10.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:12 sbtest10.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:10 sbtest1.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:10 sbtest1.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:10 sbtest2.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:10 sbtest2.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:10 sbtest3.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:10 sbtest3.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:10 sbtest4.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:10 sbtest4.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:11 sbtest5.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:11 sbtest5.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:11 sbtest6.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:11 sbtest6.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:11 sbtest7.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:11 sbtest7.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:11 sbtest8.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:11 sbtest8.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:12 sbtest9.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:12 sbtest9.ibd

Cela devrait vous donner une idée du nombre de tables que vous voulez et de leur taille. Disons que nous voulons tester la charge de travail en mémoire afin de créer des tables qui s'intégreront dans le pool de mémoire tampon InnoDB. D'autre part, nous voulons également nous assurer qu'il y a suffisamment de tables pour ne pas devenir un goulot d'étranglement (ou que le nombre de tables correspond à ce que vous attendez dans votre configuration de production). Préparons notre jeu de données. Veuillez garder à l'esprit que, par défaut, SysBench recherche le schéma 'sbtest' qui doit exister avant de préparer l'ensemble de données. Vous devrez peut-être le créer manuellement.

[email protected]:~# sysbench /root/sysbench/src/lua/oltp_read_only.lua --threads=4 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=10 --table-size=1000000 prepare
sysbench 1.1.0-2e6b7d5 (using bundled LuaJIT 2.1.0-beta3)

Initializing worker threads...

Creating table 'sbtest2'...
Creating table 'sbtest3'...
Creating table 'sbtest4'...
Creating table 'sbtest1'...
Inserting 1000000 records into 'sbtest2'
Inserting 1000000 records into 'sbtest4'
Inserting 1000000 records into 'sbtest3'
Inserting 1000000 records into 'sbtest1'
Creating a secondary index on 'sbtest2'...
Creating a secondary index on 'sbtest3'...
Creating a secondary index on 'sbtest1'...
Creating a secondary index on 'sbtest4'...
Creating table 'sbtest6'...
Inserting 1000000 records into 'sbtest6'
Creating table 'sbtest7'...
Inserting 1000000 records into 'sbtest7'
Creating table 'sbtest5'...
Inserting 1000000 records into 'sbtest5'
Creating table 'sbtest8'...
Inserting 1000000 records into 'sbtest8'
Creating a secondary index on 'sbtest6'...
Creating a secondary index on 'sbtest7'...
Creating a secondary index on 'sbtest5'...
Creating a secondary index on 'sbtest8'...
Creating table 'sbtest10'...
Inserting 1000000 records into 'sbtest10'
Creating table 'sbtest9'...
Inserting 1000000 records into 'sbtest9'
Creating a secondary index on 'sbtest10'...
Creating a secondary index on 'sbtest9'...

Une fois que nous avons nos données, préparons une commande pour exécuter le test. Nous voulons tester les recherches de clé primaire, nous allons donc désactiver tous les autres types de SELECT. Nous désactiverons également les instructions préparées car nous voulons tester les requêtes régulières. Nous allons tester la faible concurrence, disons 16 threads. Notre commande peut ressembler à ceci :

sysbench /root/sysbench/src/lua/oltp_read_only.lua --threads=16 --events=0 --time=300 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=10 --table-size=1000000 --range_selects=off --db-ps-mode=disable --report-interval=1 run

Qu'avons-nous fait ici ? Nous avons fixé le nombre de threads à 16. Nous avons décidé que nous voulions que notre benchmark s'exécute pendant 300 secondes, sans limite de requêtes exécutées. Nous avons défini la connectivité à la base de données, le nombre de tables et leur taille. Nous avons également désactivé tous les SELECT de plage, nous avons également désactivé les instructions préparées. Enfin, nous avons défini l'intervalle de rapport sur une seconde. Voici à quoi peut ressembler un exemple de sortie :

[ 297s ] thds: 16 tps: 97.21 qps: 1127.43 (r/w/o: 935.01/0.00/192.41) lat (ms,95%): 253.35 err/s: 0.00 reconn/s: 0.00
[ 298s ] thds: 16 tps: 195.32 qps: 2378.77 (r/w/o: 1985.13/0.00/393.64) lat (ms,95%): 189.93 err/s: 0.00 reconn/s: 0.00
[ 299s ] thds: 16 tps: 178.02 qps: 2115.22 (r/w/o: 1762.18/0.00/353.04) lat (ms,95%): 155.80 err/s: 0.00 reconn/s: 0.00
[ 300s ] thds: 16 tps: 217.82 qps: 2640.92 (r/w/o: 2202.27/0.00/438.65) lat (ms,95%): 125.52 err/s: 0.00 reconn/s: 0.00

Chaque seconde, nous voyons un instantané des statistiques de charge de travail. Ceci est très utile pour suivre et tracer - le rapport final ne vous donnera que des moyennes. Des résultats intermédiaires permettront de suivre la performance seconde par seconde. Le rapport final peut ressembler à ceci :

SQL statistics:
    queries performed:
        read:                            614660
        write:                           0
        other:                           122932
        total:                           737592
    transactions:                        61466  (204.84 per sec.)
    queries:                             737592 (2458.08 per sec.)
    ignored errors:                      0      (0.00 per sec.)
    reconnects:                          0      (0.00 per sec.)

Throughput:
    events/s (eps):                      204.8403
    time elapsed:                        300.0679s
    total number of events:              61466

Latency (ms):
         min:                                   24.91
         avg:                                   78.10
         max:                                  331.91
         95th percentile:                      137.35
         sum:                              4800234.60

Threads fairness:
    events (avg/stddev):           3841.6250/20.87
    execution time (avg/stddev):   300.0147/0.02

Vous trouverez ici des informations sur les requêtes exécutées et d'autres instructions (BEGIN/COMMIT). Vous saurez combien de transactions ont été exécutées, combien d'erreurs se sont produites, quel était le débit et le temps total écoulé. Vous pouvez également vérifier les métriques de latence et la distribution des requêtes sur les threads.

Si nous étions intéressés par la distribution de la latence, nous pourrions également passer l'argument '--histogram' à SysBench. Cela se traduit par une sortie supplémentaire comme ci-dessous :

Latency histogram (values are in milliseconds)
       value  ------------- distribution ------------- count
      29.194 |******                                   1
      30.815 |******                                   1
      31.945 |***********                              2
      33.718 |******                                   1
      34.954 |***********                              2
      35.589 |******                                   1
      37.565 |***********************                  4
      38.247 |******                                   1
      38.942 |******                                   1
      39.650 |***********                              2
      40.370 |***********                              2
      41.104 |*****************                        3
      41.851 |*****************************            5
      42.611 |*****************                        3
      43.385 |*****************                        3
      44.173 |***********                              2
      44.976 |**************************************** 7
      45.793 |***********************                  4
      46.625 |***********                              2
      47.472 |*****************************            5
      48.335 |**************************************** 7
      49.213 |***********                              2
      50.107 |**********************************       6
      51.018 |***********************                  4
      51.945 |**************************************** 7
      52.889 |*****************                        3
      53.850 |*****************                        3
      54.828 |***********************                  4
      55.824 |***********                              2
      57.871 |***********                              2
      58.923 |***********                              2
      59.993 |******                                   1
      61.083 |******                                   1
      63.323 |***********                              2
      66.838 |******                                   1
      71.830 |******                                   1

Une fois que nous sommes bons avec nos résultats, nous pouvons nettoyer les données :

sysbench /root/sysbench/src/lua/oltp_read_only.lua --threads=16 --events=0 --time=300 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=10 --table-size=1000000 --range_selects=off --db-ps-mode=disable --report-interval=1 cleanup

Trafic intense en écriture

Imaginons ici que nous voulons exécuter une charge de travail lourde en écriture (mais pas en écriture seule) et, par exemple, tester les performances du sous-système d'E/S. Tout d'abord, nous devons décider de la taille du jeu de données. Nous supposerons ~ 48 Go de données (20 tables, 10 000 000 lignes chacune). Nous devons le préparer. Cette fois, nous utiliserons le benchmark de lecture-écriture.

[email protected]:~# sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=20 --table-size=10000000 prepare

Une fois cela fait, nous pouvons modifier les valeurs par défaut pour forcer davantage d'écritures dans le mélange de requête :

[email protected]:~# sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=16 --events=0 --time=300 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=20 --delete_inserts=10 --index_updates=10 --non_index_updates=10 --table-size=10000000 --db-ps-mode=disable --report-interval=1 run

Comme vous pouvez le voir dans les résultats intermédiaires, les transactions sont désormais lourdes en écriture :

[ 5s ] thds: 16 tps: 16.99 qps: 946.31 (r/w/o: 231.83/680.50/33.98) lat (ms,95%): 1258.08 err/s: 0.00 reconn/s: 0.00
[ 6s ] thds: 16 tps: 17.01 qps: 955.81 (r/w/o: 223.19/698.59/34.03) lat (ms,95%): 1032.01 err/s: 0.00 reconn/s: 0.00
[ 7s ] thds: 16 tps: 12.00 qps: 698.91 (r/w/o: 191.97/482.93/24.00) lat (ms,95%): 1235.62 err/s: 0.00 reconn/s: 0.00
[ 8s ] thds: 16 tps: 14.01 qps: 683.43 (r/w/o: 195.12/460.29/28.02) lat (ms,95%): 1533.66 err/s: 0.00 reconn/s: 0.00

Comprendre les résultats

Comme nous l'avons montré ci-dessus, SysBench est un excellent outil qui peut aider à identifier certains des problèmes de performances de MySQL ou MariaDB. Il peut également être utilisé pour le réglage initial de la configuration de votre base de données. Bien sûr, vous devez garder à l'esprit que, pour tirer le meilleur parti de vos repères, vous devez comprendre pourquoi les résultats ressemblent à ce qu'ils sont. Cela nécessiterait des informations sur les métriques internes de MySQL à l'aide d'outils de surveillance, par exemple, ClusterControl. Il est très important de s'en souvenir - si vous ne comprenez pas pourquoi les performances étaient telles qu'elles étaient, vous pouvez tirer des conclusions incorrectes à partir des références. Il y a toujours un goulot d'étranglement, et SysBench peut vous aider à résoudre les problèmes de performances, que vous devez ensuite identifier.