Mysql
 sql >> Database >  >> RDS >> Mysql

Come confrontare le prestazioni di MySQL utilizzando SysBench

In questo articolo parleremo di sysbench, lo standard attuale per il benchmarking MySQL. Daremo un'occhiata alle basi dell'utilizzo di sysbench e come possiamo utilizzare sysbench per conoscere MySQL e il secondo è l'aspetto più importante per noi. Utilizzeremo praticamente sysbench come strumento per generare traffico di cui sappiamo molto perché sysbench manterrà alcune informazioni sul traffico generato ogni secondo.

Test MySQL SysBench 

Sysbench è uno strumento di benchmark multi-thread basato su luaJIT, è lo standard attuale per i benchmark MySQL, deve essere in grado di connettersi al database.

Installazione Sysbench

Innanzitutto, dobbiamo installare sysbench, sto installando sysbench su un altro server in modo da poter testare l'impatto effettivo del carico sul nostro server MySQL.

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

Detto ciò, è molto facile installare sysbench, è meglio consentire a sysbench di interagire con il server MySQL a livello di firewall, poiché questo è un ambiente di test ho disabilitato il firewall su entrambi gli host per evitare qualsiasi difficoltà.

Ambiente pronto per SysBench:

Per questo test, sto creando il database sbtest e l'utente sbtest_user e concederò tutti i PRIVILEGI a sbtest_user sul database sbtest.

usando root;

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`@`%` |
+---------------------------------------------------------+

Prestazioni di MySQL utilizzando SysBench

Configurazione benchmark:

La fase di preparazione di sysbench crea le tabelle con i dati che verranno utilizzati nel benchmark. In questo esempio stiamo eseguendo il comando prepare. Ci sono alcuni parametri con MySQL all'inizio, quelli saranno i parametri di connessione. Gli altri parametri sono parametri del test oltp_read_write.lua e stiamo specificando il test stesso che è oltp_read_write.lua e che stiamo eseguendo il comando prepare. Le opzioni che iniziano con MySQL specificano la connessione MySQL, il nome host e la porta a cui connettersi, il nome utente e la password con cui connettersi e lo schema predefinito per la connessione. Le tabelle ei parametri table_size sono le proprietà del test oltp_read_write.lua.

Ciò significa che il passaggio di preparazione creerà 16 tabelle con 10.000 regole in ciascuna di esse. Il prossimo passo è eseguire il benchmark.

Per eseguire in genere vengono passati tutti i parametri che passeranno a preparati e alcuni aggiuntivi che abbiamo esaminato ora, questi sono specifici per l'esecuzione effettiva del benchmark. Il "TEMPO" il parametro specifica il limite di tempo per l'esecuzione del benchmark, zero significa tempo illimitato, il benchmark verrà eseguito fino a quando non si preme control+c. Questo è il modo in cui useremo sysbench in laboratorio ed è così che le persone lo usano tipicamente nell'apprendimento e non in una configurazione di benchmarking.

Vogliamo solo liberare traffico su qualcosa che esamineremo e possiamo fermarlo con control+c una volta terminato l'esame.

L'"intervallo di rapporto" i parametri specificano la frequenza con cui sysbench sono state stampate le statistiche. In genere, questo è impostato su 1 come nel nostro esempio che fa stampare la riga a sysbench per ogni secondo. Anche nelle configurazioni di benchmarking questo parametro è ampiamente utilizzato perché immagina se abbiamo un benchmark di un'ora e alla fine abbiamo solo statistiche aggregate, ciò non dice nulla sulla distribuzione dei dati come le prestazioni sul server nel tempo . Il "filo" opzione specifica il numero di thread client o connessioni MySQL da utilizzare in sysbench. Il numero di thread del client avrà anche un effetto sul numero di thread del server che possono essere utilizzati. Il "tasso" Il parametro specifica la velocità di arrivo delle transazioni sysbench come un modo per soddisfare realmente il carico causato dal benchmark. Se le transazioni possono procedere, vengono messe in coda, anche questo è qualcosa che viene generalmente utilizzato in questo tipo di configurazione che utilizzeremo ora in un tipo di configurazione di apprendimento.

Da sysbench host:

Preparare un set di dati:

Sulla macchina virtuale di benchmark, eseguiremo il comando sysbench prepare per creare un database per i nostri benchmark.

Qui possiamo vedere che stiamo usando sbtest_user it come nome utente, la password è password e ci stiamo connettendo a 192.168.66.5 DB come server di database.

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'..

Hai il database sbtest proprio qui, cambiamo lo schema predefinito nel database sbtest, controlliamo quali tabelle abbiamo.

Abbiamo specificato che il benchmark dovrebbe creare sedici tabelle e ha creato 16 tabelle, possiamo vederlo qui

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

Controlliamo alcuni record da una tabella.

mysql> select * from sbtest1 limit 6;

eseguiremo un benchmark. Questo benchmark avrà una riga di output per ogni secondo perché impostiamo rapport l'intervallo è uguale a uno e ha quattro thread client perché impostiamo i thread uguali a quattro.

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

Quelle sopra le due impostazioni (eventi e ora) determinano per quanto tempo SysBench dovrebbe continuare a funzionare. Può eseguire un certo numero di query o può continuare a funzionare per un tempo predefinito.

Sull'host sysbench:

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

quindi possiamo vedere che esegue circa 70 80 transazioni al secondo sulla mia macchina, il che si traduce in circa più di mille query al secondo. Questo è in esecuzione in VirtualBox su un laptop.

Da queste query, possiamo vedere quante di esse sono lette, quante sono scritture, quante sono altre qual è la latenza del 95° percentile per la transazione (r/w/o:1038.01/302.00/148.00), come quanti errori al secondo (err/s:0.00 ) abbiamo e quante connessioni al secondo (reconn/s:0.00) abbiamo. Poiché specifichiamo che il tempo è uguale a zero, questo verrà eseguito finché non premiamo ctrl+c.

Controlliamo l'elenco dei processi di visualizzazione sull'host del database.

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 righe in serie (0,00 sec)

Il server del database era praticamente sempre occupato. Ho visto che il tempo eseguito non cambia praticamente mai da zero ed è stato molto facile catturare il server del database in azione come quando è in esecuzione "SELECT c FROM sbtest13 WHERE id=4978". E sicuramente abbiamo quattro connessioni dalla macchina di benchmarking

Per impostazione predefinita, SysBench tenterà di eseguire le query il più velocemente possibile. Per simulare il traffico più lento è possibile utilizzare questa opzione. Puoi definire qui quante transazioni devono essere eseguite al secondo.

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

Sull'host sysbench

[[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

Quindi il nuovo parametro qui è –rate è uguale a 40, il che significa che avremo due righe al secondo due righe di output e non una. Poiché impostiamo il tasso di arrivo degli eventi di benchmarking su 40 al secondo, vedremo il TPS corrente.

Non è garantito che sia 40/secondo, ma l'arrivo garantisce che in media eseguiamo all'incirca 40 transazioni al secondo e possiamo monitorare la lunghezza della coda e la concorrenza sulla seconda riga. Se eseguiamo un breve elenco di processi, è molto più facile catturare il database in uno stato in cui alcune connessioni stanno solo aspettando qui.

Mentre una sessione è occupata, puoi vedere che la transazione al secondo è zero (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)

Possiamo vedere che questo sta dormendo per alcuni secondi, era praticamente impossibile nello scenario precedente ottenere qualcosa del genere.

Traffico intenso in scrittura con rapporto finale:

Eseguiamo un carico di lavoro pesante in scrittura (ma non di sola scrittura) e, ad esempio, test delle prestazioni del sottosistema di I/O, come ho detto time=300 quindi il benchmark verrà eseguito per 300 secondi e ci fornirà un rapporto finale per analizzarlo.

[[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

ANALISI DEL RAPPORTO:

Questo è abbastanza utile per verificare che il rapporto finale ti fornirà solo le medie. I risultati intermedi consentiranno di monitorare la performance secondo per secondo. Il rapporto finale potrebbe apparire come sopra. Qui troverai informazioni sulle query eseguite, le transazioni eseguite, quanti errori si sono verificati, si è verificata qualsiasi perdita di connessione, qual è stato il throughput e il tempo totale trascorso. Puoi anche controllare le metriche di latenza e la distribuzione delle query tra i thread.