Informationen zur Leistung von Datenbanken mit einem Thread im Vergleich zu Datenbanken mit mehreren Threads


58

H2 ist eine Single-Threaded-Datenbank mit einem guten Ruf in Bezug auf die Leistung. Andere Datenbanken sind multithreaded.

Meine Frage ist: Wann wird eine Multi-Thread-Datenbank interessanter als eine Single-Thread-Datenbank? Wie viele Benutzer? Wie viele Prozesse? Was ist der Auslöser? Hat jemand Erfahrung zu teilen?

Zusammenfassung

  • Der übliche Engpass ist der Festplattenzugriff
  • SSDs sind schnell, aber zerbrechlich (Ausfallverfahren ist ein Muss)
  • Eine lange Abfrage auf einem einzelnen Thread-System blockiert alle anderen
  • Das Konfigurieren eines Multithreading-Systems kann schwierig sein
  • Multithread-Datenbanken sind selbst auf Single-Core-Systemen von Vorteil

Thread bedeutet "Thread oder Prozess" für den Zweck dieser Frage, soweit ich das beurteilen kann - z. B. Postgres ist kein Multithread, aber die Frage versucht nicht, (H2, Postgres) mit (Oracle, SQL Server usw.) zu vergleichen
Jack Douglas

Antworten:


31

Hier ist meine Meinung:

Normalerweise ist der Engpass (oder der langsamste Teil) eines DB-Systems die Festplatte. Die CPU spitzt sich nur während arithmetischer Operationen, der Verarbeitung oder anderer Aufgaben, die die CPU ausführt, zu. Bei richtiger Architektur kann Multithreading dazu beitragen, die Last einer Abfrage auf der CPU auszugleichen, anstatt langsame Lese- / Schreibvorgänge auf der Festplatte durchzuführen. Es gibt Fälle, in denen es schneller ist, einen Wert mithilfe der CPU-Zyklen zu berechnen, als eine berechnete Spalte (die zuvor auf der Festplatte gespeichert wurde) zu erstellen und diese Spalte von der Festplatte zu lesen.

In einigen RDBMS gibt es einen temporären DB (tempdb), der von allen DBs in dieser Instanz zum Sortieren, Hashing, temporären Variablen usw. verwendet wird. Durch Multithreading und Aufteilen dieser Tempdb-Dateien kann der Durchsatz des Tempdb verbessert werden Dadurch wird die Serverleistung insgesamt verbessert.

Mit Multithreading (Parallelität) kann die Ergebnismenge einer Abfrage aufgeteilt werden, um auf den verschiedenen Kernen des Servers verarbeitet zu werden, anstatt nur einen Kern zu verwenden. Diese Funktion verbessert nicht immer die Leistung, aber es gibt Fälle, in denen dies der Fall ist, und daher ist die Funktion verfügbar.

Die für die Datenbank verfügbaren Threads werden für viele Zwecke verwendet: Lesen / Schreiben auf die Festplatte, Benutzerverbindungen, Hintergrundjobs, Sperren / Verriegeln, Netzwerk-E / A usw. Abhängig von der Betriebssystemarchitektur werden die Threads vorab an die CPU weitergeleitet und werden verwaltet mit Wartezeiten und Warteschlangen. Wenn die CPU diese Threads ziemlich schnell knacken kann, sind die Wartezeiten gering. Eine Datenbank mit mehreren Threads ist schneller als eine Datenbank mit einem einzelnen Thread, da in einer Datenbank mit einem einzelnen Thread nur ein Thread recycelt werden muss, anstatt dass andere Threads verfügbar sind.

Die Skalierbarkeit wird auch zu einem Problem, da mehr Threads erforderlich sind, um das skalierte DB-System zu verwalten und auszuführen.


Danke für den Einblick. Ich höre Leute, die Solid-State-Laufwerke loben. Ich denke, in diese zu investieren ist wahrscheinlich das Beste, nachdem Sie sichergestellt haben, dass die Abfragen gut geschrieben sind und die Anwendung angemessen parallelisiert ist.
Jérôme Verstrynge

@Stan - Ich denke multithreadedin diesem Zusammenhang bedeutet es etwas anderes , dass alle Transaktionen serialisiert werden, wie Luke in seiner Antwort erwähnt.
Jack Douglas

@JVerstry ~ Nein, nicht wirklich. Lesen Sie Jeff Atwoods Gedanken zu SSDs. Sie weisen eine hohe Ausfallrate auf. Das Beste, was Sie tun können, ist, die Daten ordnungsgemäß zu indizieren und gut geschriebene Abfragen zu haben.
jcolebrand

@jcolebrand Ok, er scheint sie für Geschwindigkeit nur mit einem starken Backup-System zu befürworten, wenn sie versagen
Jérôme Verstrynge

2
@Jverstry ~ Ja, und wenn Sie dieses Konzept verstehen und damit einverstanden sind und nichts dagegen haben, Ihre gesamte Produktionsumgebung neu zu erstellen (oder darauf zu warten, dass in naher Zukunft ein automatisches Failover einsetzt und dann in naher Zukunft neu erstellt wird) Mach es, sie werden die Dinge noch schneller machen, ja.
Jcolebrand

47

Wenn es eine Sache gibt, die ich über MySQL sagen kann, ist die Tatsache, dass InnoDB, seine transaktionale (ACID-kompatible) Speicher-Engine, tatsächlich Multithread-fähig ist. Es ist jedoch so multithreadingfähig, wie SIE ES KONFIGURIEREN !!! InnoDB ist auch in einer Single-CPU-Umgebung mit seinen Standardeinstellungen sofort einsatzbereit. Um die Multithreading-Funktionen von InnoDB nutzen zu können, müssen Sie zahlreiche Optionen aktivieren.

innodb_thread_concurrency legt die Obergrenze für die Anzahl gleichzeitiger Threads fest, die InnoDB offenhalten kann. Die am besten einzustellende Rundenzahl ist (2 x Anzahl der CPUs) + Anzahl der Festplatten. UPDATE : Wie ich aus erster Hand auf der Percona NYC-Konferenz erfahren habe, sollten Sie diesen Wert auf 0 setzen, um InnoDB Storage Engine zu benachrichtigen, damit die beste Anzahl von Threads für die Umgebung ermittelt wird, in der sie ausgeführt wird.

innodb_concurrency_tickets legt die Anzahl der Threads fest, die die Prüfung auf Parallelität ungestraft umgehen können. Nachdem dieses Limit erreicht ist, wird die Thread-Parallelitätsprüfung wieder zur Norm.

innodb_commit_concurrency legt die Anzahl gleichzeitiger Transaktionen fest, die festgeschrieben werden können. Da der Standardwert 0 ist, können durch Nichteinstellung beliebig viele Transaktionen gleichzeitig festgeschrieben werden.

innodb_thread_sleep_delay legt die Anzahl der Millisekunden fest, die ein InnoDB-Thread inaktiv sein kann, bevor er erneut in die InnoDB-Warteschlange eingibt . Die Standardeinstellung ist 10000 (10 Sek.).

innodb_read_io_threads und innodb_write_io_threads (beide seit MySQL 5.1.38) weisen die angegebene Anzahl von Threads für Lese- und Schreibvorgänge zu. Die Standardeinstellung ist 4 und das Maximum ist 64.

innodb_replication_delay setzt einem Slave eine Thread-Verzögerung auf, wenn innodb_thread_concurrency erreicht ist.

innodb_read_ahead_threshold ermöglicht das lineare Lesen der festgelegten Anzahl von Speicherbereichen (64 Seiten [Seite = 16 KB]), bevor auf asynchrones Lesen umgeschaltet wird.

Die Zeit würde mir entgehen, wenn ich mehr Optionen nennen würde. Sie können darüber in der MySQL-Dokumentation nachlesen .

Die meisten Leute kennen diese Funktionen nicht und sind ziemlich zufrieden damit, dass InnoDB nur ACID-kompatible Transaktionen durchführt. Wenn Sie eine dieser Optionen anpassen, geschieht dies auf eigene Gefahr.

Ich habe mit MySQL 5.5 Multiple Buffer Pool Instances (162 GB in 9 Buffer Pool Instances) gespielt und versucht, Daten auf diese Weise automatisch im Speicher zu partitionieren. Einige Experten sagen, dass dies zu einer Leistungsverbesserung von 50% führen sollte. Was ich bekam, war eine Menge Thread-Sperren, die InnoDB tatsächlich crawlen ließen. Ich habe auf 1 Puffer (162GB) umgestellt und alles war wieder in Ordnung in der Welt. Ich nehme an, Sie benötigen Percona-Experten, die Ihnen zur Verfügung stehen, um dies einzustellen. Ich werde morgen auf der Percona MySQL-Konferenz in New York sein und danach fragen, ob sich die Gelegenheit bietet.

Zusammenfassend lässt sich sagen, dass sich InnoDB in einem Multi-CPU-Server aufgrund der Standardeinstellungen für Multithreading-Vorgänge jetzt gut verhält. Sie zu optimieren erfordert große Sorgfalt, große Geduld, gute Dokumentation und guten Kaffee (oder Red Bull, Jolt usw.).

Guten Morgen, guten Abend und gute Nacht !!!

UPDATE 2011-05-27 20:11

Kam am Donnerstag von der Percona MySQL-Konferenz in New York zurück . Was für eine Konferenz. Ich habe viel gelernt, habe aber eine Antwort erhalten, die ich in Bezug auf InnoDB untersuchen werde. Ich wurde von Ronald Bradford darüber informiert, dass das Setzen von innodb_thread_concurrency auf 0 InnoDB intern über die beste Vorgehensweise bei gleichzeitiger Verwendung von Threads entscheiden lässt. Ich werde damit in MySQL 5.5 weiter experimentieren.

UPDATE 2011-06-01 11:20

InnoDB ist nach einer langen Abfrage ACID-konform und funktioniert mit MultiVersion Concurrency Control sehr gut . Transaktionen sollten Isolationsstufen aufweisen (standardmäßig wiederholbare Lesevorgänge), die verhindern, dass andere Benutzer auf Daten zugreifen können.

Bei Multi-Core-Systemen hat InnoDB einen langen Weg zurückgelegt. In der Vergangenheit konnte InnoDB in einer Multicore-Umgebung keine gute Leistung erbringen. Ich erinnere mich, dass ich mehrere mysql-Instanzen auf einem einzelnen Server ausführen musste, um die mehreren Kerne zu erhalten, um die mehreren mysqld-Prozesse auf die CPUs zu verteilen. Dank Percona und später MySQL (eh, Oracle, das macht mich immer noch wahnsinnig) ist dies nicht mehr erforderlich, da sie InnoDB zu einer ausgereifteren Speicher-Engine entwickelt haben, die ohne viel Tuning auf die Kerne zugreifen kann. Die derzeitige Instanz von InnoDB kann auf einem einzelnen Core-Server problemlos ausgeführt werden.


11

Sobald Sie mehrere Benutzer oder Prozesse gleichzeitig haben oder sogar einen einzelnen Prozess mit Multithread-Datenbankzugriff, wird eine Datenbank, die Threading unterstützt, möglicherweise interessant.

H2 ist threadsicher, serialisiert jedoch alle Anforderungen an die Datenbank, was in einem Szenario mit hoher Auslastung zu einem potenziellen Leistungsproblem werden kann. Ob dies für ein bestimmtes Projekt tatsächlich der Fall ist, hängt von einer Kombination Ihrer Leistungsanforderungen, der Anzahl der Threads / Benutzer / Prozesse, die auf die Datenbank zugreifen, der Häufigkeit der Abfragen ab, die von diesen Threads ausgeführt werden, sowie der durchschnittlichen und der schlechtesten Leistung Ihres Projekts Abfragen.

Wenn Ihre Leistungsanforderungen beispielsweise eine Antwort innerhalb einer Sekunde enthalten sollen, dürfen nicht mehr als 10 Benutzer gleichzeitig eine einzelne Abfrage ausführen, deren Ausführung 0,05 Sekunden dauert, und eine Single-Threaded-Datenbank würde es Ihnen weiterhin ermöglichen, diese Ziele zu erreichen (obwohl Multithreading möglich ist würde wahrscheinlich schon einen spürbaren Leistungsschub geben). Angesichts des gleichen Szenarios mit einer einzelnen potenziellen Abfrage und einer Leistung im schlechtesten Fall von einer halben Sekunde können Sie Ihre Leistungsziele nicht mehr erreichen, wenn Sie Ihren Datenbankzugriff serialisieren.

Wenn Sie derzeit H2 in Ihrem Projekt verwenden, würde ich Ihnen raten, einen Profiler für Ihre Codebasis in einem Ladeszenario auszuführen (starten Sie einfach eine x-fache Anzahl von Threads, die Ihren Code unter Verwendung einiger typischer Verwendungsfälle gleichzeitig treffen). Auf diese Weise erhalten Sie tatsächliche Messdaten zur Leistung und zu Engpässen in Ihrer Codebasis, anstatt nur zu theoretisieren. Wenn dies anzeigt, dass Ihre Anforderungen einen großen Teil ihrer Zeit darauf warten, auf die Datenbank zuzugreifen, ist es Zeit, zu einer Datenbank mit Threads zu wechseln.


Serialisiert H2 alle Anfragen - oder nur DML?
Jack Douglas

8

Soweit ich das beurteilen kann, ist "single-threaded" für H2 ein bisschen eine Fehlbezeichnung. Der Punkt ist, dass alle Transaktionen serialisiert werden (dh sie werden einzeln ausgeführt ).

Die entscheidende Frage, ob dies für Ihre Anwendung "in Ordnung" ist oder nicht, lautet "Wie viele Benutzer?". oder sogar "Wie viele Prozesse?", aber "Wie lange werden meine Transaktionen dauern?"

Wenn alle Ihre Transaktionen in Sekundenbruchteilen ausgeführt werden, kann dies in Ordnung sein, und wenn einige mehrere Stunden dauern, ist dies möglicherweise nicht in Ordnung, da alle anderen ausstehenden Transaktionen darauf warten, dass sie abgeschlossen werden. Die Entscheidung, ob dies "in Ordnung" ist oder nicht, hängt von Ihren eigenen Leistungsanforderungen ab - dh, wie lange es dauern kann, bis meine Benutzer mit Transaktionen auf die Datenbank zugreifen.

--BEARBEITEN

Es scheint, dass H2 Transaktionen nicht wirklich serialisiert - nur DML. Mit anderen Worten, viele kurze Aktualisierungen innerhalb einer einzelnen langen Transaktion werden andere Aktualisierungen nicht blockieren . Wenn Sie jedoch nicht die experimentelle MVCC-Funktion verwenden , hat die Tabellensperre in der Praxis ähnliche Auswirkungen. Es gibt auch eine experimentelle Funktion "multi_threaded", die jedoch nicht gleichzeitig mit MVCC verwendet werden kann


5

Ich zitiere Teile der PostgreSQL-Site ... Bitte beachten Sie, dass ich absolut keine Ahnung von den Vorzügen dieser Argumente habe - sie passten lediglich nicht in einen Kommentar.

In den Entwickler-FAQ ("Warum werden keine Threads verwendet ..."):

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F

Derzeit werden keine Threads anstelle von mehreren Prozessen für Backends verwendet, weil: (...)

  • Ein Fehler in einem Backend kann andere Backends beschädigen, wenn sie Threads innerhalb eines einzelnen Prozesses sind
  • Die Geschwindigkeitsverbesserungen bei Verwendung von Threads sind im Vergleich zur verbleibenden Startzeit des Backends gering.
  • Die gemeinsame Nutzung schreibgeschützter ausführbarer Zuordnungen und die Verwendung von shared_buffers bedeuten, dass Prozesse wie Threads sehr speichereffizient sind
  • Die regelmäßige Erstellung und Zerstörung von Prozessen schützt vor Speicherfragmentierung, die in lang laufenden Prozessen nur schwer zu bewältigen ist

Aus der Todo-Liste ("Features, die wir nicht wollen"):

http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want

Alle Backends laufen als Threads in einem Prozess (nicht erwünscht)

Dadurch entfällt der Prozessschutz, den wir vom aktuellen Setup erhalten. Die Erstellung von Threads ist in der Regel derselbe Aufwand wie die Erstellung von Prozessen auf modernen Systemen. Die Verwendung eines reinen Thread-Modells erscheint daher unklug. MySQL und DB2 haben gezeigt, dass Threads so viele Probleme verursachen, wie sie lösen. (...)

Also wieder ... Ich habe absolut keine Ahnung von den Vorzügen der oben genannten. Es war einfach zu lang, um in einen Kommentar zu passen.


-3

Eine Multithread-Datenbank hat nur dann Vorteile, wenn mehr als eine parallele Abfrage an die Datenbank gesendet wird. Dies hängt von der Anzahl der Benutzer ab. Wenn mehr als zehn Benutzer gleichzeitig an der Anwendung arbeiten, werden sie höchstwahrscheinlich gleichzeitig mehr als eine Abfrage in der Datenbank erstellen.

Darüber hinaus kann eine Multithread-Datenbank nur dann von Nutzen sein, wenn auf der CPU mehrere Kerne vorhanden sind. Wenn es einen einzelnen Kern gibt, muss eine Datenbank mit mehreren Threads den Job in die Warteschlange stellen und diese nacheinander auf dem einzelnen Kern ausführen. Wenn es mehrere Kerne gibt, kann jeder Kern einen Thread parallel ausführen. Also bessere Leistung.

Beantwortet dies Ihre Frage?


7
Multithread-Datenbanken sind selbst auf Single-Core-Systemen von Vorteil. Dadurch wird verhindert, dass eine einzige Abfrage mit langer Laufzeit den gesamten Datenbankzugriff blockiert. Außerdem können mehrere Threads auf der Festplatte oder den Netzwerk-E / A warten, während ein anderer Thread aktiv Abfragen analysiert, vorab abgerufene Daten verarbeitet usw.

Ein Benutzer könnte ein Programm verwenden, das einige Vorgänge paralellisiert. Dieses Programm würde höchstwahrscheinlich davon profitieren, wenn die Datenbank auch Multi-Threading- / Multi-Processing-Funktionen besitzt.
Joanolo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.