MariaDB
 sql >> Database >  >> RDS >> MariaDB

Come confrontare le prestazioni di MySQL e MariaDB utilizzando SysBench

Cos'è SysBench? Se lavori regolarmente con MySQL, probabilmente ne avrai sentito parlare. SysBench è nell'ecosistema MySQL da molto tempo. È stato originariamente scritto da Peter Zaitsev, nel 2004. Il suo scopo era fornire uno strumento per eseguire benchmark sintetici di MySQL e dell'hardware su cui gira. È stato progettato per eseguire test di CPU, memoria e I/O. Aveva anche un'opzione per eseguire il carico di lavoro OLTP su un database MySQL. OLTP è l'acronimo di elaborazione delle transazioni online, carico di lavoro tipico per applicazioni online come e-commerce, immissione di ordini o sistemi di transazioni finanziarie.

In questo post del blog, ci concentreremo sulla funzionalità di benchmark SQL, ma tieni presente che i benchmark hardware possono anche essere molto utili per identificare i problemi sui server di database. Ad esempio, il benchmark I/O aveva lo scopo di simulare il carico di lavoro I/O di InnoDB mentre i test della CPU implicano la simulazione di un ambiente altamente simultaneo e multi-tread insieme ai test per le contese mutex, qualcosa che assomiglia anche a un tipo di carico di lavoro di database.

Storia e architettura di SysBench

Come accennato, SysBench è stato originariamente creato nel 2004 da Peter Zaitsev. Subito dopo, Alexey Kopytov ne ha assunto lo sviluppo. Ha raggiunto la versione 0.4.12 e lo sviluppo si è interrotto. Dopo una lunga pausa, Alexey ha ripreso a lavorare su SysBench nel 2016. Presto è stata rilasciata la versione 0.5 con il benchmark OLTP riscritto per utilizzare script basati su LUA. Poi, nel 2017, è stato rilasciato SysBench 1.0. Era come giorno e notte rispetto alla vecchia versione 0.4.12. Innanzitutto, invece degli script hardcoded, ora abbiamo la possibilità di personalizzare i benchmark utilizzando LUA. Ad esempio, Percona ha creato un benchmark simile a TPCC che può essere eseguito utilizzando SysBench. Diamo una rapida occhiata all'attuale architettura SysBench.

SysBench è un binario C che utilizza script LUA per eseguire benchmark. Questi script devono:

  1. Gestire l'input dai parametri della riga di comando
  2. Definisci tutte le modalità che il benchmark dovrebbe utilizzare (preparazione, esecuzione, pulizia)
  3. Prepara tutti i dati
  4. Definisci come verrà eseguito il benchmark (che aspetto avranno le query ecc.)

Gli script possono utilizzare più connessioni al database, possono anche elaborare risultati se si desidera creare benchmark complessi in cui le query dipendono dal set di risultati delle query precedenti. Con SysBench 1.0 è possibile creare istogrammi di latenza. È anche possibile che gli script LUA catturino e gestiscano gli errori tramite hook di errore. C'è il supporto per la parallelizzazione negli script LUA, più query possono essere eseguite in parallelo, rendendo, ad esempio, il provisioning molto più veloce. Ultimo ma non meno importante, ora sono supportati più formati di output. Prima che SysBench generasse solo output leggibile dall'uomo. Ora è possibile generarlo come CSV o JSON, rendendo molto più semplice eseguire la post-elaborazione e generare grafici utilizzando, ad esempio, gnuplot o inserire i dati in Prometheus, Graphite o simili datastore.

Perché SysBench?

Il motivo principale per cui SysBench è diventato popolare è il fatto che è semplice da usare. Qualcuno senza una conoscenza preliminare può iniziare a usarlo in pochi minuti. Fornisce inoltre, per impostazione predefinita, benchmark che coprono la maggior parte dei casi:carichi di lavoro OLTP, sola lettura o lettura-scrittura, ricerche di chiavi primarie e aggiornamenti di chiavi primarie. Tutto ciò ha causato la maggior parte dei problemi per MySQL, fino a MySQL 8.0. Questo è stato anche un motivo per cui SysBench era così popolare in diversi benchmark e confronti pubblicati su Internet. Questi post hanno contribuito a promuovere questo strumento e sono diventati il ​​benchmark sintetico di riferimento per MySQL.

Un altro aspetto positivo di SysBench è che, dalla versione 0.5 e dall'incorporazione di LUA, chiunque può preparare qualsiasi tipo di benchmark. Abbiamo già menzionato un benchmark simile a TPCC, ma chiunque può creare qualcosa che assomigli al suo carico di lavoro di produzione. Non stiamo dicendo che sia semplice, molto probabilmente sarà un processo che richiede tempo, ma avere questa capacità è vantaggioso se devi preparare un benchmark personalizzato.

Essendo un benchmark sintetico, SysBench non è uno strumento che puoi utilizzare per ottimizzare le configurazioni dei tuoi server MySQL (a meno che tu non abbia preparato script LUA con carico di lavoro personalizzato o il tuo carico di lavoro sia molto simile ai carichi di lavoro di benchmark con cui SysBench viene fornito). Ciò per cui è ottimo è confrontare le prestazioni di hardware diverso. Puoi facilmente confrontare le prestazioni, diciamo, di diversi tipi di nodi offerti dal tuo provider di servizi cloud e il massimo QPS (query al secondo) che offrono. Conoscendo quella metrica e sapendo quanto si paga per un determinato nodo, è quindi possibile calcolare una metrica ancora più importante:QP$ (query per dollaro). Ciò consentirà di identificare quale tipo di nodo utilizzare durante la creazione di un ambiente conveniente. Naturalmente, SysBench può essere utilizzato anche per la messa a punto iniziale e la valutazione di fattibilità di un determinato progetto. Supponiamo di costruire un cluster Galera che si estende in tutto il mondo:Nord America, UE, Asia. Quanti inserti al secondo può gestire una tale configurazione? Quale sarebbe la latenza del commit? Ha anche senso fare un proof of concept o forse la latenza di rete è abbastanza alta che anche un semplice carico di lavoro non funziona come ci si aspetterebbe.

E gli stress test? Non tutti sono passati al cloud, ci sono ancora aziende che preferiscono costruire la propria infrastruttura. Ogni nuovo server acquisito dovrebbe passare attraverso un periodo di riscaldamento durante il quale lo sottolineerai per individuare potenziali difetti hardware. In questo caso anche SysBench può aiutare. O eseguendo il carico di lavoro OLTP che sovraccarica il server, oppure puoi anche utilizzare benchmark dedicati per CPU, disco e memoria.

Come puoi vedere, ci sono molti casi in cui anche un semplice benchmark sintetico può essere molto utile. Nel prossimo paragrafo vedremo cosa possiamo fare con SysBench.

Cosa può fare SysBench per te?

Quali test puoi eseguire?

Come accennato all'inizio, ci concentreremo sui benchmark OLTP e solo come promemoria ribadiamo che SysBench può essere utilizzato anche per eseguire test di I/O, CPU e memoria. Diamo un'occhiata ai benchmark forniti da SysBench 1.0 (abbiamo rimosso alcuni file LUA helper e script LUA non di database da questo elenco).

-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

Esaminiamoli uno per uno.

Innanzitutto, bulk_insert.lua. Questo test può essere utilizzato per confrontare la capacità di MySQL di eseguire inserimenti su più righe. Questo può essere molto utile quando si controlla, ad esempio, le prestazioni della replica o del cluster Galera. Nel primo caso, può aiutarti a rispondere a una domanda:"Quanto velocemente posso inserire prima che si attivi il ritardo di replica?". Nel secondo caso, ti dirà quanto velocemente i dati possono essere inseriti in un cluster Galera data la latenza di rete corrente.

Tutti gli script oltp_* condividono una struttura di tabella comune. I primi due (oltp_delete.lua e oltp_insert.lua) eseguono singole istruzioni DELETE e INSERT. Anche in questo caso, questo potrebbe essere un test per la replica o per il cluster Galera:spingerlo al limite e vedere quale quantità di inserimento o eliminazione può gestire. Abbiamo anche altri benchmark focalizzati su funzionalità particolari:oltp_point_select, oltp_update_index e oltp_update_non_index. Questi eseguiranno un sottoinsieme di query:selezioni basate su chiave primaria, aggiornamenti basati su indici e aggiornamenti non basati su indici. Se vuoi testare alcune di queste funzionalità, i test ci sono. Abbiamo anche benchmark più complessi basati su carichi di lavoro OLTP:oltp_read_only, oltp_read_write e oltp_write_only. Puoi eseguire un carico di lavoro di sola lettura, che consisterà in diversi tipi di query SELECT, puoi eseguire solo scritture (un mix di DELETE, INSERT e UPDATE) oppure puoi eseguire un mix di questi due. Infine, usando select_random_points e select_random_ranges puoi eseguire alcuni SELECT casuali usando punti casuali nell'elenco IN() o intervalli casuali usando BETWEEN.

Come puoi configurare un benchmark?

Ciò che è anche importante, i benchmark sono configurabili:puoi eseguire diversi modelli di carico di lavoro utilizzando lo stesso benchmark. Diamo un'occhiata ai due benchmark più comuni da eseguire. Approfondiremo i benchmark OLTP read_only e OLTP read_write. Prima di tutto, SysBench ha alcune opzioni di configurazione generali. Discuteremo qui solo i più importanti, puoi controllarli tutti eseguendo:

sysbench --help

Diamo un'occhiata a loro.

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

Puoi definire il tipo di concorrenza che desideri che SysBench generi. MySQL, come ogni software, ha alcuni limiti di scalabilità e le sue prestazioni raggiungeranno il picco a un certo livello di concorrenza. Questa impostazione consente di simulare diverse simultaneità per un determinato carico di lavoro e verificare se ha già superato il punto debole.

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

Queste due impostazioni 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.

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

Questo è autoesplicativo. SysBench genera risultati statistici dai test e tali risultati potrebbero essere influenzati se MySQL è in uno stato freddo. Il riscaldamento aiuta a identificare il throughput "regolare" eseguendo il benchmark per un tempo predefinito, consentendo di riscaldare la cache, i pool di buffer ecc.

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

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.

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

Per impostazione predefinita SysBench genera un report dopo aver completato la sua esecuzione e non viene segnalato alcun progresso mentre il benchmark è in esecuzione. Usando questa opzione puoi rendere SysBench più dettagliato mentre il benchmark è ancora in esecuzione.

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

SysBench ti dà la possibilità di generare diversi tipi di distribuzione dei dati. Tutti possono avere i propri scopi. L'opzione predefinita, "speciale", definisce diversi hot-spot (è configurabile) nei dati, cosa abbastanza comune nelle applicazioni web. Puoi anche utilizzare altre distribuzioni se i tuoi dati si comportano in modo diverso. Facendo una scelta diversa qui puoi anche cambiare il modo in cui il tuo database è stressato. Ad esempio, la distribuzione uniforme, in cui tutte le righe hanno la stessa probabilità di accesso, è un'operazione che richiede molta più memoria. Utilizzerà più pool di buffer per archiviare tutti i dati e sarà molto più intensivo del disco se il set di dati non si adatta alla memoria. D'altra parte, una distribuzione speciale con un paio di punti caldi sottoporrà il disco a meno stress poiché è più probabile che le righe calde vengano mantenute nel pool di buffer e l'accesso alle righe archiviate sul disco è molto meno probabile. Per alcuni dei tipi di distribuzione dei dati, SysBench offre più modifiche. Puoi trovare queste informazioni nell'output di 'sysbench --help'.

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

Usando questa impostazione puoi decidere se SysBench deve usare le istruzioni preparate (purché siano disponibili nel datastore fornito - per MySQL significa che PS sarà abilitato per impostazione predefinita) o meno. Questo può fare la differenza mentre si lavora con proxy come ProxySQL o MaxScale:dovrebbero trattare le istruzioni preparate in un modo speciale e tutte dovrebbero essere indirizzate a un host, rendendo impossibile testare la scalabilità del proxy.

Oltre alle opzioni di configurazione generali, ciascuno dei test può avere una propria configurazione. Puoi verificare cosa è possibile eseguendo:

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

Ancora una volta, discuteremo le opzioni più importanti da qui. Prima di tutto, hai il controllo di come apparirà esattamente una transazione. In generale, consiste in diversi tipi di query:INSERT, DELETE, diversi tipi di SELECT (ricerca punto, intervallo, aggregazione) e UPDATE (indicizzato, non indicizzato). Utilizzando variabili come:

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

Puoi definire come dovrebbe essere una transazione. Come puoi vedere osservando i valori predefiniti, la maggior parte delle query sono SELECT - principalmente selezioni di punti ma anche diversi tipi di SELECT di intervallo (puoi disabilitarle tutte impostando range_selects su off). È possibile modificare il carico di lavoro verso un carico di lavoro più pesante in scrittura aumentando il numero di aggiornamenti o le query INSERT/DELETE. È anche possibile modificare le impostazioni relative agli indici secondari, all'incremento automatico ma anche alle dimensioni del set di dati (numero di tabelle e quante righe ciascuna di esse dovrebbe contenere). Ciò ti consente di personalizzare il tuo carico di lavoro abbastanza bene.

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

Questa è un'altra impostazione, molto importante quando si lavora con i proxy. Per impostazione predefinita, SysBench tenterà di eseguire query in una transazione esplicita. In questo modo il set di dati rimarrà coerente e non verrà influenzato:SysBench, ad esempio, eseguirà INSERT e DELETE sulla stessa riga, assicurandosi che il set di dati non cresca (influendo sulla tua capacità di riprodurre i risultati). Tuttavia, i proxy tratteranno le transazioni esplicite in modo diverso:tutte le query eseguite all'interno di una transazione devono essere eseguite sullo stesso host, eliminando così la possibilità di ridimensionare il carico di lavoro. Tieni presente che la disabilitazione delle transazioni comporterà una divergenza del set di dati dal punto iniziale. Potrebbe anche innescare alcuni problemi come errori di chiave duplicati o simili. Per poter disabilitare le transazioni potresti anche voler esaminare:

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

Questa impostazione consente di specificare codici di errore da MySQL che SysBench dovrebbe ignorare (e non interrompere la connessione). Ad esempio, per ignorare errori come:errore 1062 (voce duplicata '6' per la chiave 'PRIMARIA') dovresti passare questo codice di errore:--mysql-ignore-errors=1062

Ciò che è anche importante, ogni benchmark dovrebbe presentare un modo per fornire un set di dati per i test, eseguirli e quindi ripulirlo al termine dei test. Questo viene fatto usando i comandi "prepara", "esegui" e "pulisci". Mostreremo come farlo nella prossima sezione.

Esempi

In questa sezione analizzeremo alcuni esempi di ciò per cui SysBench può essere utilizzato. Come accennato in precedenza, ci concentreremo sui due benchmark più popolari:OLTP di sola lettura e OLTP di lettura/scrittura. A volte può avere senso utilizzare altri benchmark, ma almeno saremo in grado di mostrarti come è possibile personalizzare questi due.

Ricerche chiave primaria

Prima di tutto, dobbiamo decidere quale benchmark eseguiremo, di sola lettura o di lettura-scrittura. Tecnicamente parlando non fa differenza in quanto possiamo rimuovere le scritture dal benchmark R/W. Concentriamoci su quella di sola lettura.

Come primo passo, dobbiamo preparare un set di dati. Dobbiamo decidere quanto dovrebbe essere grande. Per questo particolare benchmark, utilizzando le impostazioni predefinite (quindi vengono creati indici secondari), 1 milione di righe risulteranno in circa 240 MB di dati. Dieci tabelle, 1000 000 righe ciascuna equivalgono a 2,4 GB:

[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

Questo dovrebbe darti un'idea di quanti tavoli vuoi e quanto dovrebbero essere grandi. Diciamo che vogliamo testare il carico di lavoro in memoria, quindi vogliamo creare tabelle che rientrino nel pool di buffer InnoDB. D'altra parte, vogliamo anche assicurarci che ci siano abbastanza tabelle per non diventare un collo di bottiglia (o che la quantità di tabelle corrisponda a quella che ti aspetteresti nella tua configurazione di produzione). Prepariamo il nostro set di dati. Tieni presente che, per impostazione predefinita, SysBench cerca lo schema "sbtest" che deve esistere prima di preparare il set di dati. Potrebbe essere necessario crearlo manualmente.

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

Una volta che abbiamo i nostri dati, prepariamo un comando per eseguire il test. Vogliamo testare le ricerche della chiave primaria, quindi disabiliteremo tutti gli altri tipi di SELECT. Disabiliteremo anche le istruzioni preparate poiché vogliamo testare le query regolari. Verificheremo una bassa concorrenza, diciamo 16 thread. Il nostro comando potrebbe essere simile al seguente:

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

Cosa abbiamo fatto qui? Abbiamo impostato il numero di thread su 16. Abbiamo deciso che vogliamo che il nostro benchmark venga eseguito per 300 secondi, senza un limite di query eseguite. Abbiamo definito la connettività al database, il numero di tabelle e la loro dimensione. Abbiamo anche disabilitato tutti i SELECT di intervallo, abbiamo anche disabilitato le istruzioni preparate. Infine, impostiamo l'intervallo del rapporto su un secondo. Ecco come potrebbe apparire un output di esempio:

[ 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

Ogni secondo vediamo un'istantanea delle statistiche del carico di lavoro. Questo è abbastanza utile per tracciare e tracciare:il rapporto finale ti darà solo le medie. I risultati intermedi consentiranno di monitorare la performance secondo per secondo. Il rapporto finale potrebbe essere simile al seguente:

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

Qui troverai informazioni sulle query eseguite e altre istruzioni (BEGIN/COMMIT). Imparerai quante transazioni sono state eseguite, quanti errori si sono verificati, qual è stato il throughput e il tempo totale trascorso. Puoi anche controllare le metriche di latenza e la distribuzione delle query tra i thread.

Se fossimo interessati alla distribuzione della latenza, potremmo anche passare l'argomento "--istogramma" a SysBench. Ciò si traduce in un output aggiuntivo come di seguito:

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

Una volta che siamo a posto con i nostri risultati, possiamo ripulire i dati:

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

Traffico intenso in scrittura

Immaginiamo qui di voler eseguire un carico di lavoro pesante in scrittura (ma non di sola scrittura) e, ad esempio, testare le prestazioni del sottosistema di I/O. Prima di tutto, dobbiamo decidere quanto dovrebbe essere grande il set di dati. Assumiamo circa 48 GB di dati (20 tabelle, 10.000.000 righe ciascuna). Dobbiamo prepararlo. Questa volta useremo il benchmark di lettura-scrittura.

[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

Fatto ciò, possiamo modificare le impostazioni predefinite per forzare più scritture nel mix di query:

[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

Come puoi vedere dai risultati intermedi, le transazioni sono ora in una fase di scrittura pesante:

[ 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

Capire i risultati

Come mostrato sopra, SysBench è un ottimo strumento che può aiutare a individuare alcuni dei problemi di prestazioni di MySQL o MariaDB. Può essere utilizzato anche per la messa a punto iniziale della configurazione del database. Ovviamente, devi tenere a mente che, per ottenere il meglio dai tuoi benchmark, devi capire perché i risultati sembrano come loro. Ciò richiederebbe informazioni dettagliate sulle metriche interne di MySQL utilizzando strumenti di monitoraggio, ad esempio ClusterControl. Questo è abbastanza importante da ricordare:se non capisci perché le prestazioni erano come erano, potresti trarre conclusioni errate dai benchmark. C'è sempre un collo di bottiglia e SysBench può aiutare a sollevare i problemi di prestazioni, che devi quindi identificare.