Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Benchmarking der Leistung von MySQL mit SysBench

In diesem Artikel werden wir Sysbench besprechen, den aktuellen Standard für MySQL-Benchmarking. Wir werden einen Blick auf die Grundlagen der Sysbench-Nutzung werfen und wie wir Sysbench verwenden können, um etwas über MySQL zu lernen, und der zweite Aspekt ist für uns der wichtigste Aspekt. Wir werden sysbench praktisch als Werkzeug verwenden, um Datenverkehr zu generieren, über den wir viel wissen, da sysbench jede Sekunde einige Informationen über den generierten Datenverkehr bereithält.

SysBench MySQL-Test 

Sysbench ist ein Multithread-Benchmark-Tool, das auf LuaJIT basiert, es ist der eigentliche Standard für MySQL-Benchmarks, es muss in der Lage sein, sich mit der Datenbank zu verbinden.

Sysbench-Installation

Zuerst müssen wir die Sysbench installieren, ich installiere Sysbench auf einem anderen Server, damit wir die tatsächlichen Auswirkungen der Last auf unseren MySQL-Server testen können.

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

Damit ist es sehr einfach, sysbench zu installieren, es ist besser, sysbench zu erlauben, mit dem MySQL-Server auf Firewall-Ebene zu interagieren, da dies eine Testumgebung ist. Ich habe die Firewall auf beiden Hosts deaktiviert, um Schwierigkeiten zu vermeiden.

Bereitschaftsumgebung für SysBench:

Für diesen Test erstelle ich die sbtest-Datenbank und den Benutzer sbtest_user und werde sbtest_user alle PRIVILEGIEN für die sbtest-Datenbank gewähren.

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

Leistung von MySQL mit SysBench

Benchmark-Konfiguration:

Der Vorbereitungsschritt von sysbench erstellt die Tabellen mit den Daten, die im Benchmark verwendet werden. In diesem Beispiel führen wir den Befehl „prepare“ aus. Es gibt ein paar Parameter mit MySQL am Anfang, das werden die Verbindungsparameter sein. Die anderen Parameter sind Parameter des Tests oltp_read_write.lua, und wir geben den Test selbst an, der oltp_read_write.lua ist, und dass wir den Befehl „prepare“ ausführen. Die Optionen, die mit MySQL beginnen, geben die MySQL-Verbindung, den Hostnamen und den Port für die Verbindung, den Benutzernamen und das Kennwort für die Verbindung und das Standardschema für die Verbindung an. Die Tabellen und die Parameter table_size sind die Eigenschaften des Tests oltp_read_write.lua.

Das bedeutet, dass der Vorbereitungsschritt 16 Tabellen mit jeweils 10.000 Regeln erstellt. Der nächste Schritt besteht darin, den Benchmark auszuführen.

Für die Ausführung werden normalerweise alle Parameter übergeben, die an die vorbereiteten übergeben werden, und einige zusätzliche, die wir jetzt überprüft haben. Diese sind spezifisch für die tatsächliche Ausführung des Benchmarks. Die "ZEIT" Der Parameter gibt das Zeitlimit für die Ausführung des Benchmarks an, Null bedeutet unbegrenzte Zeit, der Benchmark wird ausgeführt, bis wir Strg + C drücken. So werden wir Sysbench im Labor verwenden, und so verwenden es die Leute normalerweise beim Lernen und nicht in einem Benchmarking-Setup.

Wir wollen nur Verkehr auf etwas loslassen, das wir untersuchen, und wir können ihn mit Strg + C stoppen, sobald wir mit der Untersuchung fertig sind.

Das "Berichtsintervall" Parameter geben an, wie oft Sysbench-Statistiken gedruckt wurden. Typischerweise wird dies wie in unserem Beispiel auf 1 gesetzt, wodurch Sysbench jede Sekunde die Zeile ausdruckt. Selbst in Benchmarking-Setups wird dieser Parameter häufig verwendet, denn stellen Sie sich vor, wir haben einen einstündigen Benchmark und am Ende nur aggregierte Statistiken, die nichts über die Verteilung der Daten aussagen, z. B. wie die Leistung auf dem Server im Laufe der Zeit war . Der "Faden" Die Option gibt die Anzahl der Client-Threads oder MySQL-Verbindungen an, die in Sysbench verwendet werden sollen. Die Anzahl der Client-Threads wirkt sich auch auf die Anzahl der Server-Threads aus, die verwendet werden können. Der "Preis" Der Parameter gibt die Ankunftsrate von Sysbench-Transaktionen an, um die durch den Benchmark verursachte Last wirklich zu bewältigen. Wenn Transaktionen fortgesetzt werden können, werden sie in die Warteschlange gestellt, was wiederum typischerweise in dieser Art von Setup verwendet wird, was wir jetzt in einem Lerntyp von Setup verwenden werden.

Vom Sysbench-Host:

Datensatz vorbereiten:

Auf der virtuellen Benchmarking-Maschine führen wir den sysbench-prepare-Befehl aus, um eine Datenbank für unsere Benchmarks zu erstellen.

Hier können wir sehen, dass wir sbtest_user als Benutzernamen verwenden, das Passwort password ist und wir uns mit 192.168.66.5 DB als Datenbankserver verbinden.

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

Sie haben die sbtest-Datenbank genau hier, ändern wir das Standardschema in die sbtest-Datenbank, überprüfen Sie, welche Tabellen wir haben.

Wir haben angegeben, dass der Benchmark sechzehn Tabellen erstellen sollte, und es wurden 16 Tabellen erstellt, wir können es hier sehen

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

Lassen Sie uns ein paar Datensätze aus einer Tabelle überprüfen.

mysql> select * from sbtest1 limit 6;

Wir werden einen Benchmark durchführen. Dieser Benchmark hat eine Ausgabezeile für jede Sekunde, weil wir das Intervall von Rapport auf eins gesetzt haben, und er hat vier Client-Threads, weil wir Threads auf vier gesetzt haben.

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

Die beiden obigen Einstellungen (Ereignisse und Zeit) bestimmen, wie lange SysBench ausgeführt werden soll. Es kann entweder eine bestimmte Anzahl von Abfragen ausführen oder für eine vordefinierte Zeit weiterlaufen.

Auf 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

Wir können also sehen, dass auf meinem Computer ungefähr 70 bis 80 Transaktionen pro Sekunde durchgeführt werden, was ungefähr mehr als tausend Abfragen pro Sekunde entspricht. Dies läuft in VirtualBox auf einem Laptop.

Aus diesen Abfragen können wir sehen, wie viele davon Lesevorgänge sind, wie viele davon Schreibvorgänge sind, wie viele davon andere sind, was die 95. Perzentil-Latenzzeit für die Transaktion ist (r/w/o:1038.01/302.00/148.00), wie wie viele Fehler pro Sekunde (err/s:0.00 ) wir haben und wie viele Verbindungen pro Sekunde (reconn/s:0.00) wir haben. Da wir die Zeit gleich Null angeben, wird dies ausgeführt, bis wir Strg+C drücken.

Sehen wir uns die Show-Prozessliste auf dem Datenbankhost an.

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 Zeilen im Satz (0,00 Sek.)

Der Datenbankserver war praktisch immer ausgelastet. Ich habe gesehen, dass sich die ausgeführte Zeit praktisch nie von Null ändert, und es war sehr einfach, den Datenbankserver in Aktion zu fangen, wie wenn er „SELECT c FROM sbtest13 WHERE id=4978“ ausführt. Und definitiv haben wir vier Verbindungen von der Benchmarking-Maschine

Standardmäßig versucht SysBench, Abfragen so schnell wie möglich auszuführen. Um langsameren Verkehr zu simulieren, kann diese Option verwendet werden. Hier können Sie festlegen, wie viele Transaktionen pro Sekunde ausgeführt werden sollen.

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

Auf dem 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

Der neue Parameter hier ist also –rate gleich 40, was bedeutet, dass wir zwei Zeilen pro Sekunde zwei Ausgabezeilen haben und nicht eine. Da wir die Ankunftsrate der Benchmarking-Ereignisse auf 40 pro Sekunde festgelegt haben, sehen wir die aktuelle TPS.

Dies ist nicht garantiert 40/Sekunde, aber die Ankunft garantiert, dass wir im Durchschnitt ungefähr 40 Transaktionen pro Sekunde durchführen und wir die Warteschlangenlänge und die Parallelität auf der zweiten Leitung überwachen können. Wenn wir eine kurze Prozessliste erstellen, ist es viel einfacher, die Datenbank in einem Zustand zu erwischen, in dem einige Verbindungen hier nur warten.

Während eine Sitzung ausgelastet ist, können Sie sehen, dass die Transaktion pro Sekunde null ist (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)

Wir können sehen, dass dies für ein paar Sekunden schläft, das war im vorherigen Szenario so gut wie unmöglich, so etwas zu bekommen.

Viel Schreibverkehr mit Endbericht:

Lassen Sie uns eine schreiblastige (aber nicht nur schreibbare) Arbeitslast ausführen und beispielsweise die Leistung des Test-I/O-Subsystems, wie ich erwähnt habe, time=300 dann läuft der Benchmark 300 Sekunden lang und gibt uns einen Endbericht zur Analyse.

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

BERICHTSANALYSE:

Dies ist sehr nützlich, um zu überprüfen, ob der Abschlussbericht nur Durchschnittswerte enthält. Zwischenergebnisse ermöglichen es, die Leistung sekundengenau zu verfolgen. Der Abschlussbericht kann wie oben aussehen. Hier finden Sie Informationen über ausgeführte Abfragen, ausgeführte Transaktionen, wie viele Fehler aufgetreten sind, Verbindungsabbrüche aufgetreten sind, wie hoch der Durchsatz und die insgesamt verstrichene Zeit war. Sie können auch Latenzmetriken und die Abfrageverteilung über Threads hinweg überprüfen.