Was ist SysBench? Wenn Sie regelmäßig mit MySQL arbeiten, haben Sie höchstwahrscheinlich schon davon gehört. SysBench ist seit langem Teil des MySQL-Ökosystems. Es wurde ursprünglich von Peter Zaitsev im Jahr 2004 geschrieben. Sein Zweck war es, ein Tool bereitzustellen, um synthetische Benchmarks von MySQL und der Hardware, auf der es läuft, auszuführen. Es wurde entwickelt, um CPU-, Speicher- und I/O-Tests auszuführen. Es hatte auch die Möglichkeit, OLTP-Workloads auf einer MySQL-Datenbank auszuführen. OLTP steht für Online Transaction Processing, typische Workload für Online-Anwendungen wie E-Commerce, Auftragserfassung oder Finanztransaktionssysteme.
In diesem Blogbeitrag werden wir uns auf die SQL-Benchmark-Funktion konzentrieren, aber denken Sie daran, dass Hardware-Benchmarks auch sehr nützlich sein können, um Probleme auf Datenbankservern zu identifizieren. Beispielsweise sollte der E/A-Benchmark die InnoDB-E/A-Arbeitslast simulieren, während CPU-Tests die Simulation einer hochgradig gleichzeitigen, mehrfach durchlaufenen Umgebung zusammen mit Tests auf Mutex-Konflikte beinhalten – etwas, das auch einer Datenbank-Arbeitslast ähnelt.
Geschichte und Architektur von SysBench
Wie bereits erwähnt, wurde SysBench ursprünglich 2004 von Peter Zaitsev erstellt. Bald darauf übernahm Alexey Kopytov die Entwicklung. Es erreichte die Version 0.4.12 und die Entwicklung wurde eingestellt. Nach einer langen Pause begann Alexey 2016 wieder mit der Arbeit an SysBench. Bald wurde Version 0.5 mit OLTP-Benchmark veröffentlicht, der umgeschrieben wurde, um LUA-basierte Skripte zu verwenden. Dann, im Jahr 2017, wurde SysBench 1.0 veröffentlicht. Das war wie Tag und Nacht im Vergleich zur alten Version 0.4.12. In erster Linie haben wir jetzt anstelle von fest codierten Skripten die Möglichkeit, Benchmarks mit LUA anzupassen. Beispielsweise hat Percona einen TPCC-ähnlichen Benchmark erstellt, der mit SysBench ausgeführt werden kann. Werfen wir einen kurzen Blick auf die aktuelle SysBench-Architektur.
SysBench ist eine C-Binärdatei, die LUA-Skripte verwendet, um Benchmarks auszuführen. Diese Skripte müssen:
- Eingabe von Befehlszeilenparametern verarbeiten
- Definieren Sie alle Modi, die der Benchmark verwenden soll (prepare, run, cleanup)
- Bereiten Sie alle Daten vor
- Definieren Sie, wie der Benchmark ausgeführt wird (wie Abfragen aussehen werden usw.)
Skripte können mehrere Verbindungen zur Datenbank verwenden, sie können auch Ergebnisse verarbeiten, wenn Sie komplexe Benchmarks erstellen möchten, bei denen Abfragen von der Ergebnismenge vorheriger Abfragen abhängen. Mit SysBench 1.0 ist es möglich, Latenzhistogramme zu erstellen. Es ist auch möglich, dass die LUA-Skripte Fehler durch Fehler-Hooks abfangen und behandeln. Es gibt Unterstützung für Parallelisierung in den LUA-Skripten, mehrere Abfragen können parallel ausgeführt werden, was beispielsweise die Bereitstellung viel schneller macht. Nicht zuletzt werden jetzt mehrere Ausgabeformate unterstützt. Bevor SysBench nur menschenlesbare Ausgaben generierte. Jetzt ist es möglich, sie als CSV oder JSON zu generieren, was die Nachbearbeitung und das Generieren von Diagrammen beispielsweise mit gnuplot erheblich erleichtert oder die Daten in Prometheus, Graphite oder einen ähnlichen Datenspeicher einspeist.
Warum SysBench?
Der Hauptgrund, warum SysBench populär wurde, ist die Tatsache, dass es einfach zu bedienen ist. Jemand ohne Vorkenntnisse kann es innerhalb von Minuten verwenden. Es bietet außerdem standardmäßig Benchmarks, die die meisten Fälle abdecken – OLTP-Workloads, Read-Only oder Read-Write, Primärschlüssel-Lookups und Primärschlüssel-Updates. All dies verursachte die meisten Probleme für MySQL bis MySQL 8.0. Dies war auch ein Grund, warum SysBench in verschiedenen im Internet veröffentlichten Benchmarks und Vergleichen so beliebt war. Diese Beiträge trugen dazu bei, dieses Tool bekannter zu machen, und machten es zum führenden synthetischen Benchmark für MySQL.
Eine weitere gute Sache an SysBench ist, dass seit Version 0.5 und der Einbindung von LUA jeder jede Art von Benchmark erstellen kann. Wir haben bereits TPCC-ähnliche Benchmarks erwähnt, aber jeder kann etwas herstellen, das seiner Arbeitsbelastung in der Produktion ähnelt. Wir sagen nicht, dass es einfach ist, es wird höchstwahrscheinlich ein zeitaufwändiger Prozess sein, aber diese Fähigkeit ist von Vorteil, wenn Sie einen benutzerdefinierten Benchmark erstellen müssen.
Als synthetischer Benchmark ist SysBench kein Tool, mit dem Sie die Konfigurationen Ihrer MySQL-Server optimieren können (es sei denn, Sie haben LUA-Skripte mit benutzerdefinierter Arbeitslast erstellt oder Ihre Arbeitslast ist den Benchmark-Arbeitslasten sehr ähnlich, mit denen SysBench geliefert wird). Was es großartig macht, ist, die Leistung verschiedener Hardware zu vergleichen. Sie können die Leistung von beispielsweise verschiedenen Arten von Knoten, die von Ihrem Cloud-Anbieter angeboten werden, und die von ihnen angebotenen maximalen QPS (Abfragen pro Sekunde) leicht vergleichen. Wenn Sie diese Metrik kennen und wissen, was Sie für einen bestimmten Knoten bezahlen, können Sie dann eine noch wichtigere Metrik berechnen – QP$ (Abfragen pro Dollar). Auf diese Weise können Sie ermitteln, welcher Knotentyp beim Aufbau einer kosteneffizienten Umgebung verwendet werden soll. Natürlich kann SysBench auch zur anfänglichen Abstimmung und Bewertung der Machbarkeit eines bestimmten Designs verwendet werden. Nehmen wir an, wir bauen einen Galera-Cluster auf, der sich über die ganze Welt erstreckt – Nordamerika, EU, Asien. Wie viele Inserts pro Sekunde kann ein solches Setup verarbeiten? Was wäre die Commit-Latenz? Macht es überhaupt Sinn, einen Machbarkeitsnachweis zu führen, oder ist die Netzwerklatenz vielleicht hoch genug, dass selbst eine einfache Arbeitslast nicht so funktioniert, wie Sie es erwarten würden.
Was ist mit Stresstests? Nicht alle sind in die Cloud umgestiegen, es gibt immer noch Unternehmen, die es vorziehen, ihre eigene Infrastruktur aufzubauen. Jeder neu erworbene Server sollte eine Aufwärmphase durchlaufen, in der Sie ihn belasten, um potenzielle Hardwaredefekte zu lokalisieren. Auch in diesem Fall kann SysBench helfen. Entweder durch Ausführen von OLTP-Workloads, die den Server überlasten, oder Sie können auch dedizierte Benchmarks für CPU, Festplatte und Speicher verwenden.
Wie Sie sehen können, gibt es viele Fälle, in denen sogar ein einfacher, synthetischer Benchmark sehr nützlich sein kann. Im nächsten Abschnitt sehen wir uns an, was wir mit SysBench machen können.
Was kann SysBench für Sie tun?
Welche Tests können Sie durchführen?
Wie eingangs erwähnt, werden wir uns auf OLTP-Benchmarks konzentrieren und nur zur Erinnerung wiederholen, dass SysBench auch verwendet werden kann, um I/O-, CPU- und Speichertests durchzuführen. Werfen wir einen Blick auf die Benchmarks, mit denen SysBench 1.0 geliefert wird (wir haben einige Hilfs-LUA-Dateien und Nicht-Datenbank-LUA-Skripte aus dieser Liste entfernt).
-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
Gehen wir sie nacheinander durch.
Zuerst bulk_insert.lua. Dieser Test kann verwendet werden, um die Fähigkeit von MySQL zu bewerten, mehrzeilige Einfügungen durchzuführen. Dies kann sehr nützlich sein, wenn Sie beispielsweise die Leistung der Replikation oder des Galera-Clusters überprüfen. Im ersten Fall kann es Ihnen helfen, eine Frage zu beantworten:„Wie schnell kann ich einfügen, bevor die Replikationsverzögerung eintritt?“. Im letzteren Fall erfahren Sie, wie schnell Daten bei der aktuellen Netzwerklatenz in einen Galera-Cluster eingefügt werden können.
Alle oltp_*-Skripte haben eine gemeinsame Tabellenstruktur. Die ersten beiden (oltp_delete.lua und oltp_insert.lua) führen einzelne DELETE- und INSERT-Anweisungen aus. Auch dies könnte ein Test für die Replikation oder den Galera-Cluster sein – treiben Sie es an die Grenzen und sehen Sie, wie viel Einfügen oder Löschen es bewältigen kann. Wir haben auch andere Benchmarks, die sich auf bestimmte Funktionen konzentrieren – oltp_point_select, oltp_update_index und oltp_update_non_index. Diese führen eine Teilmenge von Abfragen aus – primärschlüsselbasierte Auswahlen, indexbasierte Aktualisierungen und nicht indexbasierte Aktualisierungen. Wenn Sie einige dieser Funktionalitäten testen möchten, sind die Tests da. Wir haben auch komplexere Benchmarks, die auf OLTP-Workloads basieren:oltp_read_only, oltp_read_write und oltp_write_only. Sie können entweder eine schreibgeschützte Workload ausführen, die aus verschiedenen Arten von SELECT-Abfragen besteht, Sie können nur Schreibvorgänge ausführen (eine Mischung aus DELETE, INSERT und UPDATE) oder Sie können eine Mischung aus diesen beiden ausführen. Schließlich können Sie mit select_random_points und select_random_ranges ein zufälliges SELECT ausführen, entweder mit zufälligen Punkten in der IN()-Liste oder mit zufälligen Bereichen unter Verwendung von BETWEEN.
Wie kann man einen Benchmark konfigurieren?
Wichtig ist auch, dass Benchmarks konfigurierbar sind – Sie können verschiedene Workload-Muster mit demselben Benchmark ausführen. Werfen wir einen Blick auf die beiden am häufigsten auszuführenden Benchmarks. Wir werden einen tiefen Einblick in die OLTP-Read_only- und OLTP-Read_Write-Benchmarks geben. Zunächst einmal hat SysBench einige allgemeine Konfigurationsoptionen. Wir werden hier nur die wichtigsten besprechen, Sie können sie alle überprüfen, indem Sie Folgendes ausführen:
sysbench --help
Werfen wir einen Blick darauf.
--threads=N number of threads to use [1]
Sie können definieren, welche Art von Parallelität SysBench generieren soll. MySQL hat, wie jede Software, einige Skalierbarkeitsbeschränkungen und seine Leistung wird bei einem gewissen Grad an Parallelität ihren Höhepunkt erreichen. Diese Einstellung hilft dabei, verschiedene Gleichzeitigkeiten für eine bestimmte Arbeitslast zu simulieren und zu prüfen, ob der Sweet Spot bereits überschritten ist.
--events=N limit for total number of events [0]
--time=N limit for total execution time in seconds [10]
Diese beiden Einstellungen 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.
--warmup-time=N execute events for this many seconds with statistics disabled before the actual benchmark run with statistics enabled [0]
Dies ist selbsterklärend. SysBench generiert statistische Ergebnisse aus den Tests und diese Ergebnisse können beeinträchtigt werden, wenn sich MySQL in einem kalten Zustand befindet. Warmup hilft, den „normalen“ Durchsatz zu identifizieren, indem Benchmarks für eine vordefinierte Zeit ausgeführt werden, wodurch Cache, Pufferpools usw. aufgewärmt werden können.
--rate=N average transactions rate. 0 for unlimited rate [0]
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.
--report-interval=N periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0]
Standardmäßig generiert SysBench einen Bericht, nachdem es seine Ausführung abgeschlossen hat, und es wird kein Fortschritt gemeldet, während der Benchmark ausgeführt wird. Mit dieser Option können Sie SysBench ausführlicher machen, während der Benchmark noch läuft.
--rand-type=STRING random numbers distribution {uniform, gaussian, special, pareto, zipfian} to use by default [special]
SysBench gibt Ihnen die Möglichkeit, verschiedene Arten der Datenverteilung zu generieren. Alle von ihnen können ihre eigenen Zwecke haben. Die Standardoption „special“ definiert mehrere (konfigurierbare) Hotspots in den Daten, was in Webanwendungen recht häufig vorkommt. Sie können auch andere Distributionen verwenden, wenn sich Ihre Daten anders verhalten. Indem Sie hier eine andere Auswahl treffen, können Sie auch die Belastung Ihrer Datenbank ändern. Beispielsweise ist eine gleichmäßige Verteilung, bei der alle Zeilen die gleiche Wahrscheinlichkeit haben, dass auf sie zugegriffen wird, eine viel speicherintensivere Operation. Es wird mehr Pufferpool verwendet, um alle Daten zu speichern, und es wird viel plattenintensiver, wenn Ihr Datensatz nicht in den Speicher passt. Andererseits belastet eine spezielle Verteilung mit einigen Hot-Spots die Festplatte weniger, da heiße Zeilen eher im Pufferpool verbleiben und der Zugriff auf auf der Festplatte gespeicherte Zeilen viel unwahrscheinlicher ist. Für einige der Datenverteilungstypen bietet Ihnen SysBench weitere Optimierungen. Sie finden diese Informationen in der Ausgabe von „sysbench --help“.
--db-ps-mode=STRING prepared statements usage mode {auto, disable} [auto]
Mit dieser Einstellung können Sie entscheiden, ob SysBench vorbereitete Anweisungen verwenden soll (solange sie im angegebenen Datenspeicher verfügbar sind - für MySQL bedeutet dies, dass PS standardmäßig aktiviert ist) oder nicht. Dies kann bei der Arbeit mit Proxys wie ProxySQL oder MaxScale einen Unterschied machen - sie sollten vorbereitete Anweisungen auf besondere Weise behandeln und alle sollten an einen Host weitergeleitet werden, was es unmöglich macht, die Skalierbarkeit des Proxys zu testen.
Zusätzlich zu den allgemeinen Konfigurationsoptionen kann jeder der Tests seine eigene Konfiguration haben. Sie können überprüfen, was möglich ist, indem Sie Folgendes ausführen:
[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]
Auch hier werden wir die wichtigsten Optionen besprechen. Zunächst einmal haben Sie die Kontrolle darüber, wie genau eine Transaktion aussehen wird. Im Allgemeinen besteht es aus verschiedenen Arten von Abfragen - INSERT, DELETE, verschiedene Arten von SELECT (Punktsuche, Bereich, Aggregation) und UPDATE (indiziert, nicht indiziert). Verwenden von Variablen wie:
--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]
Sie können definieren, wie eine Transaktion aussehen soll. Wie Sie anhand der Standardwerte sehen können, sind die meisten Abfragen SELECTs - hauptsächlich Punktauswahlen, aber auch verschiedene Arten von Bereichs-SELECTs (Sie können sie alle deaktivieren, indem Sie range_selects auf off setzen). Sie können die Arbeitslast in Richtung einer schreiblastigeren Arbeitslast optimieren, indem Sie die Anzahl der Aktualisierungen oder INSERT/DELETE-Abfragen erhöhen. Es ist auch möglich, Einstellungen in Bezug auf sekundäre Indizes, automatisches Inkrement, aber auch die Datensatzgröße (Anzahl der Tabellen und wie viele Zeilen jede von ihnen enthalten soll) zu optimieren. Auf diese Weise können Sie Ihre Arbeitslast ganz gut anpassen.
--skip_trx[=on|off] Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]
Dies ist eine weitere Einstellung, die bei der Arbeit mit Proxys sehr wichtig ist. Standardmäßig versucht SysBench, Abfragen in expliziten Transaktionen auszuführen. Auf diese Weise bleibt der Datensatz konsistent und wird nicht beeinflusst:SysBench führt beispielsweise INSERT und DELETE in derselben Zeile aus und stellt sicher, dass der Datensatz nicht wächst (was sich auf Ihre Fähigkeit auswirkt, Ergebnisse zu reproduzieren). Proxys behandeln explizite Transaktionen jedoch anders – alle Abfragen, die innerhalb einer Transaktion ausgeführt werden, sollten auf demselben Host ausgeführt werden, wodurch die Möglichkeit zur Skalierung der Arbeitslast entfällt. Bitte beachten Sie, dass das Deaktivieren von Transaktionen dazu führt, dass der Datensatz vom ursprünglichen Punkt abweicht. Es kann auch einige Probleme wie doppelte Schlüsselfehler oder ähnliches auslösen. Um Transaktionen deaktivieren zu können, sollten Sie sich auch Folgendes ansehen:
--mysql-ignore-errors=[LIST,...] list of errors to ignore, or "all" [1213,1020,1205]
Mit dieser Einstellung können Sie Fehlercodes von MySQL angeben, die SysBench ignorieren (und die Verbindung nicht beenden) soll. Um beispielsweise Fehler wie Fehler 1062 (Doppelter Eintrag '6' für Schlüssel 'PRIMARY') zu ignorieren, sollten Sie diesen Fehlercode übergeben:--mysql-ignore-errors=1062
Wichtig ist auch, dass jeder Benchmark eine Möglichkeit bieten sollte, einen Datensatz für Tests bereitzustellen, sie auszuführen und ihn nach Abschluss der Tests zu bereinigen. Dies geschieht mit den Befehlen „prepare“, „run“ und „cleanup“. Wie das geht, zeigen wir im nächsten Abschnitt.
Beispiele
In diesem Abschnitt gehen wir einige Beispiele durch, wofür SysBench verwendet werden kann. Wie bereits erwähnt, konzentrieren wir uns auf die beiden beliebtesten Benchmarks – OLTP Read Only und OLTP Read/Write. Manchmal kann es sinnvoll sein, andere Benchmarks zu verwenden, aber zumindest können wir Ihnen zeigen, wie diese beiden angepasst werden können.
Primärschlüsselsuche
Zunächst müssen wir uns entscheiden, welchen Benchmark wir ausführen, Read-Only oder Read-Write. Technisch gesehen macht es keinen Unterschied, da wir Schreibvorgänge aus dem R/W-Benchmark entfernen können. Konzentrieren wir uns auf den schreibgeschützten.
Als ersten Schritt müssen wir einen Datensatz vorbereiten. Wir müssen entscheiden, wie groß es sein soll. Für diesen speziellen Benchmark führen 1 Million Zeilen unter Verwendung der Standardeinstellungen (so dass sekundäre Indizes erstellt werden) zu ~240 MB an Daten. Zehn Tabellen mit jeweils 1.000.000 Zeilen entsprechen 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
Dies sollte Ihnen eine Vorstellung davon geben, wie viele Tische Sie möchten und wie groß sie sein sollten. Angenommen, wir möchten die In-Memory-Workload testen, also möchten wir Tabellen erstellen, die in den InnoDB-Pufferpool passen. Andererseits möchten wir auch sicherstellen, dass genügend Tabellen vorhanden sind, um nicht zu einem Engpass zu werden (oder dass die Anzahl der Tabellen mit dem übereinstimmt, was Sie in Ihrer Produktionsumgebung erwarten würden). Bereiten wir unseren Datensatz vor. Bitte beachten Sie, dass SysBench standardmäßig nach dem Schema „sbtest“ sucht, das vorhanden sein muss, bevor Sie den Datensatz vorbereiten. Möglicherweise müssen Sie es manuell erstellen.
[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'...
Sobald wir unsere Daten haben, bereiten wir einen Befehl vor, um den Test auszuführen. Wir wollen die Suche nach Primärschlüsseln testen, daher werden wir alle anderen Arten von SELECT deaktivieren. Wir werden auch vorbereitete Anweisungen deaktivieren, da wir regelmäßige Abfragen testen möchten. Wir werden niedrige Parallelität testen, sagen wir 16 Threads. Unser Befehl könnte wie folgt aussehen:
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
Was haben wir hier gemacht? Wir setzen die Anzahl der Threads auf 16. Wir haben entschieden, dass unser Benchmark 300 Sekunden lang ausgeführt werden soll, ohne Begrenzung der ausgeführten Abfragen. Wir haben die Konnektivität zur Datenbank, die Anzahl der Tabellen und deren Größe definiert. Wir haben auch alle Bereichs-SELECTs deaktiviert, wir haben auch vorbereitete Anweisungen deaktiviert. Schließlich setzen wir das Berichtsintervall auf eine Sekunde. So könnte eine Beispielausgabe aussehen:
[ 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
Jede Sekunde sehen wir eine Momentaufnahme der Workload-Statistiken. Dies ist sehr nützlich zum Verfolgen und Plotten - der Abschlussbericht gibt Ihnen nur Durchschnittswerte. Zwischenergebnisse ermöglichen es, die Leistung sekundengenau zu verfolgen. Der Abschlussbericht könnte wie folgt aussehen:
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
Hier finden Sie Informationen über ausgeführte Abfragen und andere (BEGIN/COMMIT)-Anweisungen. Sie erfahren, wie viele Transaktionen ausgeführt wurden, wie viele Fehler aufgetreten sind, wie hoch der Durchsatz und die insgesamt verstrichene Zeit waren. Sie können auch Latenzmetriken und die Abfrageverteilung über Threads hinweg überprüfen.
Wenn wir an der Latenzverteilung interessiert wären, könnten wir auch das Argument „--histogram“ an SysBench übergeben. Dies führt zu einer zusätzlichen Ausgabe wie unten:
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
Sobald wir mit unseren Ergebnissen zufrieden sind, können wir die Daten bereinigen:
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
Viel Schreibverkehr
Stellen wir uns hier vor, dass wir eine schreiblastige (aber nicht nur schreibbare) Arbeitslast ausführen und beispielsweise die Leistung des I/O-Subsystems testen möchten. Zunächst müssen wir entscheiden, wie groß der Datensatz sein soll. Wir gehen von ~48 GB Daten aus (20 Tabellen mit jeweils 10.000.000 Zeilen). Wir müssen es vorbereiten. Dieses Mal verwenden wir den Read-Write-Benchmark.
[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
Sobald dies erledigt ist, können wir die Standardeinstellungen optimieren, um mehr Schreibvorgänge in den Abfragemix zu erzwingen:
[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
Wie Sie den Zwischenergebnissen entnehmen können, sind die Transaktionen jetzt schreiblastig:
[ 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
Ergebnisse verstehen
Wie wir oben gezeigt haben, ist SysBench ein großartiges Tool, das dabei helfen kann, einige der Leistungsprobleme von MySQL oder MariaDB zu lokalisieren. Es kann auch für die anfängliche Optimierung Ihrer Datenbankkonfiguration verwendet werden. Natürlich müssen Sie bedenken, dass Sie, um das Beste aus Ihren Benchmarks herauszuholen, verstehen müssen, warum die Ergebnisse so aussehen, wie sie aussehen. Dazu wären Einblicke in die internen Metriken von MySQL mithilfe von Überwachungstools erforderlich, z. B. ClusterControl. Dies ist sehr wichtig, um sich daran zu erinnern - wenn Sie nicht verstehen, warum die Leistung so war, ziehen Sie möglicherweise falsche Schlüsse aus den Benchmarks. Es gibt immer einen Engpass, und SysBench kann dabei helfen, die Leistungsprobleme aufzudecken, die Sie dann identifizieren müssen.