sql >> Database >  >> RDS >> Mysql

Hoe de prestaties van MySQL te benchmarken met SysBench

In dit artikel gaan we het hebben over sysbench, de eigenlijke standaard voor MySQL-benchmarking. We gaan de basisprincipes van het gebruik van sysbench bekijken en hoe we sysbench kunnen gebruiken om meer te weten te komen over MySQL en de tweede is het belangrijkste aspect voor ons. We zullen sysbench praktisch gebruiken als een tool om verkeer te genereren waar we veel over weten, omdat sysbench elke seconde wat informatie over het gegenereerde verkeer zal bevatten.

SysBench MySQL-test 

Sysbench is een multi-threaded benchmarktool gebaseerd op luaJIT. Het is de eigenlijke standaard voor MySQL-benchmarks, het moet verbinding kunnen maken met de database.

Sysbench-installatie

Eerst moeten we de sysbench installeren. Ik installeer sysbench op een andere server zodat we de daadwerkelijke impact van belasting op onze MySQL-server kunnen testen.

curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
yum -y install sysbench

Dat is ingesteld, het is heel eenvoudig om sysbench te installeren, het is beter om sysbench te laten communiceren met de MySQL-server op firewallniveau, aangezien dit een testomgeving is. Ik heb de firewall op beide hosts uitgeschakeld om problemen te voorkomen.

Klaar voor SysBench:

Voor deze test maak ik de sbtest-database en gebruiker sbtest_user en zal ik alle PRIVILEGES verlenen aan sbtest_user op de sbtest-database.

root gebruiken;

mysql> create database sbtest
mysql> create user sbtest_user identified by 'password';
mysql> grant all on sbtest.* to `sbtest_user`@`%`;
mysql> show grants for sbtest_user;
+---------------------------------------------------------+
| Grants for [email protected]%                                |
+---------------------------------------------------------+
| GRANT USAGE ON *.* TO `sbtest_user`@`%`                 |
| GRANT ALL PRIVILEGES ON `sbtest`.* TO `sbtest_user`@`%` |
+---------------------------------------------------------+

Prestaties van MySQL met SysBench

Benchmarkconfiguratie:

De voorbereidingsstap van sysbench maakt de tabellen met de gegevens die in de benchmark zullen worden gebruikt. In dit voorbeeld voeren we de opdracht prepare uit. Er zijn in het begin een paar parameters met MySQL, dat zijn de verbindingsparameters. De andere parameters zijn parameters van de oltp_read_write.lua-test en we specificeren de test zelf die oltp_read_write.lua is en dat we de opdracht prepare uitvoeren. De optie die begint met MySQL is het specificeren van de MySQL-verbinding, de hostnaam en poort waarmee verbinding moet worden gemaakt, de gebruikersnaam en het wachtwoord waarmee verbinding moet worden gemaakt en het standaardschema voor de verbinding. De tabellen en de parameters table_size zijn de eigenschappen van de oltp_read_write.lua-test.

Dit betekent dat de voorbereidingsstap 16 tabellen zal maken met elk 10.000 regels. De volgende stap is het uitvoeren van de benchmark.

Om normaal te kunnen draaien, worden alle parameters doorgegeven die zullen worden doorgegeven aan de voorbereiding en enkele extra parameters die we nu aan het beoordelen waren, deze zijn specifiek voor de daadwerkelijke uitvoering van de benchmark. De “TIJD” parameter specificeert de tijdslimiet voor het uitvoeren van de benchmark, nul betekent onbeperkte tijd, de benchmark loopt totdat we op control+c drukken. Dit is hoe we sysbench in het laboratorium zullen gebruiken en dit is hoe mensen het doorgaans gebruiken bij het leren en niet in een benchmarking-opstelling.

We willen gewoon verkeer ontketenen voor iets dat we gaan onderzoeken en we kunnen het stoppen met control+c zodra we klaar zijn met het onderzoek.

Het “rapport-interval” parameters specificeren hoe vaak sysbench statistieken werden afgedrukt. Meestal is dit ingesteld op 1 zoals in ons voorbeeld, waarbij sysbench de regel voor elke seconde afdrukt. Zelfs in benchmarking-setups wordt deze parameter veel gebruikt, want stel je voor dat we een benchmark van een uur hebben en we hebben alleen geaggregeerde statistieken aan het einde, dat zegt niets over de distributie van de gegevens, zoals hoe de prestaties op de server in de loop van de tijd waren . De “thread” optie specificeert het aantal clientthreads of MySQL-verbindingen dat in sysbench moet worden gebruikt. Het aantal clientthreads heeft ook invloed op het aantal serverthreads dat kan worden gebruikt. Het “tarief” parameter specificeert de aankomstsnelheid van sysbench-transacties als een manier om echt te voldoen aan de belasting veroorzaakt door de benchmark. Als transacties kunnen doorgaan, worden ze in de wachtrij geplaatst, dit is weer iets dat typisch wordt gebruikt in dit soort instellingen wat we nu gaan gebruiken in een leertype opstelling.

Van sysbench-host:

Een dataset voorbereiden:

Op de virtuele benchmarkmachine gaan we de opdracht sysbench prepare uitvoeren om een ​​database voor onze benchmarks te maken.

Hier kunnen we zien dat we de sbtest_user gebruiken als gebruikersnaam, het wachtwoord is wachtwoord en we maken verbinding met 192.168.66.5 DB als de databaseserver.

sysbench \
--db-driver=mysql \
--mysql-user=sbtest_user \
--mysql_password=password \
--mysql-db=sbtest \
--mysql-host=192.168.66.5 \
--mysql-port=3306 \
--tables=16 \
--table-size=10000 \
/usr/share/sysbench/oltp_read_write.lua prepare

sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)

Creating table 'sbtest1'...
Inserting 10000 records into 'sbtest1'
Creating a secondary index on 'sbtest1'...
.
.
.
Creating table 'sbtest16'...
Inserting 10000 records into 'sbtest16'
Creating a secondary index on 'sbtest16'..

Je hebt hier de sbtest-database, laten we het standaardschema wijzigen in de sbtest-database, kijk welke tabellen we hebben.

We hebben gespecificeerd dat de benchmark zestien tabellen zou moeten maken en het heeft 16 tabellen gemaakt, we kunnen het hier zien

mysql> show tables;
+------------------+
| Tables_in_sbtest 
+------------------+
| sbtest1          |
| sbtest2          |
.
.
.
| sbtest16         |
+------------------+
16 rows in set (0.01 sec)

Laten we een paar records uit een tabel controleren.

mysql> select * from sbtest1 limit 6;

we gaan een benchmark uitvoeren. Deze benchmark heeft één regel uitvoer voor elke seconde omdat we rapport instellen, het interval is gelijk aan één en het heeft vier clientthreads omdat we threads instellen op vier.

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

De bovenstaande twee instellingen (gebeurtenissen en tijd) bepalen hoe lang SysBench moet blijven draaien. Het kan een aantal zoekopdrachten uitvoeren of het kan een vooraf bepaalde tijd blijven draaien.

Op sysbench-host:

sysbench \
--db-driver=mysql \
--mysql-user=sbtest_user \
--mysql_password=password \
--mysql-db=sbtest \
--mysql-host=192.168.66.5 \
--mysql-port=3306 \
--tables=16 \
--table-size=10000 \
--threads=4 \
--time=0 \
--events=0 \
--report-interval=1 \ 
/usr/share/sysbench/oltp_read_write.lua run

WARNING: Both event and time limits are disabled, running an endless test
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)
Running the test with the following options:
Number of threads: 4
Report intermediate results every 1 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!

[ 1s ] thds: 4 tps: 62.79 qps: 1320.63 (r/w/o: 933.91/257.15/129.57) lat (ms,95%): 80.03 err/s: 0.00 reconn/s: 0.00
[ 2s ] thds: 4 tps: 77.01 qps: 1530.26 (r/w/o: 1065.18/312.05/153.03) lat (ms,95%): 61.08 err/s: 0.00 reconn/s: 0.00
[ 3s ] thds: 4 tps: 74.03 qps: 1463.67 (r/w/o: 1025.47/289.13/149.07) lat (ms,95%): 70.55 err/s: 0.00 reconn/s: 0.00
[ 4s ] thds: 4 tps: 69.99 qps: 1414.84 (r/w/o: 991.89/282.97/139.98) lat (ms,95%): 65.65 err/s: 0.00 reconn/s: 0.00
[ 5s ] thds: 4 tps: 74.02 qps: 1488.34 (r/w/o: 1048.24/292.07/148.03) lat (ms,95%): 74.46 err/s: 0.00 reconn/s: 0.00
[ 6s ] thds: 4 tps: 72.99 qps: 1444.89 (r/w/o: 1003.92/294.98/145.99) lat (ms,95%): 70.55 err/s: 0.00 reconn/s: 0.00
[ 7s ] thds: 4 tps: 63.00 qps: 1271.04 (r/w/o: 890.03/255.01/126.00) lat (ms,95%): 87.56 err/s: 0.00 reconn/s: 0.00
[ 8s ] thds: 4 tps: 72.99 qps: 1439.82 (r/w/o: 1008.87/284.96/145.98) lat (ms,95%): 73.13 err/s: 0.00 reconn/s: 0.00
[ 9s ] thds: 4 tps: 74.00 qps: 1488.01 (r/w/o: 1038.01/302.00/148.00) lat (ms,95%): 73.13 err/s: 0.00 reconn/s: 0.00

dus we kunnen zien dat het ongeveer 70 80 transacties per seconde op mijn machine doet, wat zich vertaalt naar ongeveer meer dan duizend zoekopdrachten per seconde. Dit draait in VirtualBox op een laptop.

Uit deze query's kunnen we zien hoeveel ervan gelezen zijn, hoeveel ervan zijn geschreven, hoeveel ervan anders zijn, wat is de latentie van het 95e percentiel voor de transactie (r/w/o:1038.01/302.00/148.00), hoe veel fouten per seconde (err/s:0.00 ) we hebben en hoeveel verbindingen per seconde (reconn/s:0.00) we hebben. Omdat we specificeren dat tijd gelijk is aan nul, zal dit doorgaan totdat we op ctrl+c drukken.

Laten we de lijst met processen weergeven op de databasehost eens bekijken.

mysql> show processlist;
+----+-----------------+--------------------+--------+---------+-------+----------------------------+--------------------------------------+
| Id | User            | Host               | db     | Command | Time  | State                      | Info                                 |
+----+-----------------+--------------------+--------+---------+-------+----------------------------+--------------------------------------+
|  5 | event_scheduler | localhost          | NULL   | Daemon  | 23200 | Waiting on empty queue     | NULL                                 |
| 11 | root            | localhost          | NULL   | Sleep   | 18438 |                            | NULL                                 |
| 19 | root            | localhost          | sbtest | Query   |     0 | starting                   | show processlist                     |
| 23 | root            | localhost          | NULL   | Sleep   |  4098 |                            | NULL                                 |
| 30 | sbtest_user     | 192.168.66.6:37298 | sbtest | Sleep   |     0 |                            | NULL                                 |
| 31 | sbtest_user     | 192.168.66.6:37300 | sbtest | Execute |     0 | waiting for handler commit | COMMIT                               |
| 32 | sbtest_user     | 192.168.66.6:37302 | sbtest | Sleep   |     0 |                            | NULL                                 |
| 33 | sbtest_user     | 192.168.66.6:37304 | sbtest | Execute |     0 | Opening tables             | SELECT c FROM sbtest13 WHERE id=4978 |
+----+-----------------+--------------------+--------+---------+-------+----------------------------+--------------------------------------+

8 rijen in set (0,00 sec)

De databaseserver was vrijwel altijd bezet. Ik zag dat de uitgevoerde tijd praktisch nooit van nul verandert, en het was heel gemakkelijk om de databaseserver in actie te zien, zoals wanneer deze draait "SELECT c FROM sbtest13 WHERE id=4978". En zeker, we hebben vier verbindingen van de benchmarkmachine

SysBench probeert standaard query's zo snel mogelijk uit te voeren. Om langzamer verkeer te simuleren kan deze optie worden gebruikt. U kunt hier definiëren hoeveel transacties er per seconde moeten worden uitgevoerd.

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

Op sysbench-host

[[email protected] ~]# sysbench \
--db-driver=mysql \
--mysql-user=sbtest_user \
--mysql_password=password \
--mysql-db=sbtest \
--mysql-host=192.168.66.5 \
--mysql-port=3306 \
--tables=16 \
--table-size=10000 \
--threads=4 \
--time=0 \
--events=0 \
--report-interval=1 \
--rate=40 \
/usr/share/sysbench/oltp_read_write.lua run

WARNING: Both event and time limits are disabled, running an endless test
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)
Running the test with following options:
Number of threads: 4
Target transaction rate: 40/sec
Report intermediate results every 1 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!

[ 1s ] thds: 4 tps: 42.87 qps: 858.43 (r/w/o: 600.20/171.49/86.74) lat (ms,95%): 73.13 err/s: 0.00 reconn/s: 0.00
[ 1s ] queue length: 0, concurrency: 1
[ 2s ] thds: 4 tps: 41.01 qps: 857.25 (r/w/o: 609.17/164.05/84.02) lat (ms,95%): 101.13 err/s: 0.00 reconn/s: 0.00
[ 2s ] queue length: 0, concurrency: 3
[ 3s ] thds: 4 tps: 57.01 qps: 1119.29 (r/w/o: 778.20/228.06/113.03) lat (ms,95%): 73.13 err/s: 0.00 reconn/s: 0.00
[ 3s ] queue length: 0, concurrency: 2
.
.
.
[ 15s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
[ 15s ] queue length: 145, concurrency: 4
[ 16s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
[ 16s ] queue length: 179, concurrency: 4

Dus de nieuwe parameter hier is –rate is gelijk aan 40, wat betekent dat we twee regels per seconde twee uitvoerregels hebben en niet één. Omdat we de aankomstsnelheid van de benchmarking-evenementen hebben ingesteld op 40 per seconde, zien we de huidige TPS.

Dit is niet gegarandeerd 40/seconde, maar de aankomst garandeert dat we gemiddeld ongeveer 40 transacties per seconde doen en we de wachtrijlengte en de gelijktijdigheid op de tweede regel kunnen volgen. Als we een korte proceslijst maken, is het veel gemakkelijker om de database te vangen in een staat waarin sommige verbindingen hier gewoon wachten.

Terwijl een sessie bezet is, kun je zien dat de transactie per seconde nul is (tps:0.00 ).

mysql> show processlist;
+----+-----------------+--------------------+--------+---------+-------+------------------------+------------------------------------------------------------------------------------------------------+
| Id | User            | Host               | db     | Command | Time  | State                  | Info                                                                                                 |
+----+-----------------+--------------------+--------+---------+-------+------------------------+------------------------------------------------------------------------------------------------------+
|  5 | event_scheduler | localhost          | NULL   | Daemon  | 19162 | Waiting on empty queue | NULL                                                                                                 |
|  8 | root            | localhost          | NULL   | Query   |     0 | starting               | show processlist                                                                                     |                                                                                                |
| 21 | sbtest_user     | 192.168.66.6:49060 | sbtest | Execute |    33 | updating               | UPDATE sbtest8 SET k=k+1 WHERE id=5005                                                               |
| 22 | sbtest_user     | 192.168.66.6:49062 | sbtest | Execute |    22 | updating               | UPDATE sbtest14 SET c='54592761471-89397085016-24424731626-29460127219-18466786462-73074657089-48925 
| 23 | sbtest_user     | 192.168.66.6:49064 | sbtest | Execute |    21 | updating               | UPDATE sbtest10 SET c='68520795048-46094139936-88850487689-12482054639-29231339380-71050139550-93403 |
| 24 | sbtest_user     | 192.168.66.6:49066 | sbtest | Execute |    31 | updating               | DELETE FROM sbtest14 WHERE id=4994                                                                   |
+----+-----------------+--------------------+--------+---------+-------+------------------------+------------------------------------------------------------------------------------------------------+
10 rows in set (0.00 sec)

We kunnen zien dat dit een paar seconden slaapt, dit was vrijwel onmogelijk in het vorige scenario om zoiets te krijgen.

Schriftelijk verkeer met eindrapport:

Laten we een schrijfzware (maar niet alleen-schrijven) werklast uitvoeren en bijvoorbeeld de prestaties van het I/O-testsubsysteem, zoals ik al zei time=300 dan zal de benchmark 300 seconden lopen en het zal ons een eindrapport geven om het te analyseren.

[[email protected] ~]#   
sysbench \
--db-driver=mysql \
--mysql-user=sbtest_user \
--mysql_password=password \
--mysql-db=sbtest \
--mysql-host=192.168.66.5 \
--mysql-port=3306 \
--tables=16 \
--table-size=10000 \
--threads=8 \
--time=300 \
--events=0 \
--report-interval=1 \
--rate=40 \
/usr/share/sysbench/oltp_read_write.lua run
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)

Running the test with following options:
Number of threads: 8
Target transaction rate: 40/sec
Report intermediate results every 1 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!

[ 1s ] thds: 8 tps: 39.87 qps: 810.27 (r/w/o: 570.08/159.46/80.73) lat (ms,95%): 82.96 err/s: 0.00 reconn/s: 0.00
[ 1s ] queue length: 0, concurrency: 1
[ 2s ] thds: 8 tps: 43.02 qps: 847.39 (r/w/o: 590.27/172.08/85.04) lat (ms,95%): 125.52 err/s: 0.00 reconn/s: 0.00
[ 2s ] queue length: 0, concurrency: 0
.
.
.
[ 350s ] thds: 8 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
[ 350s ] queue length: 6545, concurrency: 1
SQL statistics:
    queries performed:
        read:                            78624
        write:                           22385
        other:                           11205
        total:                           112214
    transactions:                        5589   (15.94 per sec.)
    queries:                             112214 (320.02 per sec.)
    ignored errors:                      27     (0.08 per sec.)
    reconnects:                          0      (0.00 per sec.)

General statistics:
    total time:                          350.6412s
    total number of events:              5589

Latency (ms):
         min:                                   12.45
         avg:                                74639.59
         max:                               213244.02
         95th percentile:                   100000.00
         sum:                            417160677.24

Threads fairness:
    events (avg/stddev):           698.6250/196.36
    execution time (avg/stddev):   52145.0847/15557.93

RAPPORTANALYSE:

Dit is erg handig om te controleren of het eindrapport alleen gemiddelden geeft. Tussenresultaten zullen het mogelijk maken om de prestaties van seconde tot seconde te volgen. Het eindrapport kan er als volgt uitzien. U vindt hier informatie over uitgevoerde zoekopdrachten, transacties die zijn uitgevoerd, hoeveel fouten er zijn opgetreden, eventuele verbroken verbindingen, wat de doorvoer was en de totale verstreken tijd. U kunt ook latentiestatistieken en de vraagverdeling over threads controleren.


  1. snelle willekeurige rijselectie in Postgres

  2. Oracle pivot-operator

  3. Verbinding maken met host PostgreSQL vanaf een zwervende virtualbox-machine

  4. Slaapstandprobleem met Oracle Trigger voor het genereren van id uit een reeks