Antworten:
Der beste Ansatz für das Sharding von MySQL-Tabellen, um dies nicht zu tun, es sei denn, es ist absolut unvermeidlich, dies zu tun.
Wenn Sie eine Anwendung schreiben, möchten Sie dies normalerweise so tun, dass die Geschwindigkeit und die Entwicklergeschwindigkeit maximiert werden. Sie optimieren die Latenz (Zeit bis die Antwort fertig ist) oder den Durchsatz (Anzahl der Antworten pro Zeiteinheit) nur bei Bedarf.
Sie partitionieren Partitionen und weisen sie dann nur dann verschiedenen Hosts (= Shard) zu, wenn die Summe aller dieser Partitionen nicht mehr auf eine einzelne Datenbankserverinstanz passt - der Grund dafür ist entweder Schreiben oder Lesen.
Der Schreibfall ist entweder a) die Häufigkeit der Schreibvorgänge überlastet die Festplatten dieses Servers dauerhaft oder b) es werden zu viele Schreibvorgänge ausgeführt, sodass die Replikation in dieser Replikationshierarchie dauerhaft zurückbleibt.
Der Lesefall für das Sharding liegt vor, wenn die Daten so groß sind, dass der Arbeitssatz nicht mehr in den Speicher passt und Datenlesevorgänge auf die Festplatte gelangen, anstatt die meiste Zeit aus dem Speicher bereitgestellt zu werden.
Nur wenn Sie haben Scherbe Sie es tun.
In dem Moment, in dem Sie scherben, zahlen Sie auf verschiedene Weise dafür:
Ein Großteil Ihrer SQL ist nicht mehr deklarativ.
Normalerweise teilen Sie der Datenbank in SQL mit, welche Daten Sie möchten, und überlassen es dem Optimierer, diese Spezifikation in ein Datenzugriffsprogramm umzuwandeln. Das ist gut so, weil es flexibel ist und weil das Schreiben dieser Datenzugriffsprogramme eine langweilige Arbeit ist, die der Geschwindigkeit schadet.
In einer Sharded-Umgebung verbinden Sie wahrscheinlich eine Tabelle auf Knoten A mit Daten auf Knoten B, oder Sie haben eine Tabelle, die größer als ein Knoten ist, auf Knoten A und B und verbinden Daten daraus mit Daten auf Knoten B und C. Sie beginnen, anwendungsseitige Hash-basierte Join-Auflösungen manuell zu schreiben, um dies zu beheben (oder Sie erfinden den MySQL-Cluster neu), was bedeutet, dass Sie am Ende viel SQL haben, das nicht mehr deklarativ ist, sondern die SQL-Funktionalität auf prozedurale Weise ausdrückt (zB verwenden Sie SELECT-Anweisungen in Schleifen).
Sie haben eine große Netzwerklatenz.
Normalerweise kann eine SQL-Abfrage lokal aufgelöst werden, und der Optimierer kennt die mit lokalen Festplattenzugriffen verbundenen Kosten und löst die Abfrage so auf, dass die Kosten dafür minimiert werden.
In einer Sharded-Umgebung werden Abfragen gelöst, indem entweder Schlüsselwertzugriffe über ein Netzwerk auf mehrere Knoten ausgeführt werden (hoffentlich mit Batch-Schlüsselzugriffen und nicht mit einzelnen Schlüssel-Lookups pro Roundtrip) oder indem Teile der WHERE
Klausel an die Knoten weitergeleitet werden, an denen sie können angewendet werden (das heißt "Bedingungs-Pushdown") oder beides.
Aber selbst im besten Fall beinhaltet dies viel mehr Netzrundfahrten als eine lokale Situation, und es ist komplizierter. Zumal der MySQL-Optimierer überhaupt nichts über Netzwerklatenz weiß (Ok, der MySQL-Cluster wird langsam besser, aber für Vanilla MySQL außerhalb des Clusters ist das immer noch der Fall).
Sie verlieren viel Ausdruckskraft von SQL.
Ok, das ist wahrscheinlich weniger wichtig, aber Fremdschlüsseleinschränkungen und andere SQL-Mechanismen für die Datenintegrität können nicht mehrere Shards umfassen.
MySQL verfügt über keine API, die funktionierende asynchrone Abfragen zulässt.
Wenn sich Daten desselben Typs auf mehreren Knoten befinden (z. B. Benutzerdaten auf den Knoten A, B und C), müssen horizontale Abfragen häufig für alle diese Knoten aufgelöst werden ("Alle Benutzerkonten suchen, die seit 90 Tagen nicht angemeldet waren oder mehr"). Die Datenzugriffszeit wächst linear mit der Anzahl der Knoten, es sei denn, mehrere Knoten können parallel abgefragt und die Ergebnisse beim Eingang aggregiert werden ("Map-Reduce").
Voraussetzung dafür ist eine asynchrone Kommunikations-API, die für MySQL nicht gut funktioniert. Die Alternative ist viel Gabelung und Verbindungen in den Kinderprozessen, die die Welt des Saugens auf einem Saisonpass besuchen.
Sobald Sie mit dem Sharding beginnen, werden Datenstruktur und Netzwerktopologie als Leistungspunkte für Ihre Anwendung sichtbar. Um eine einigermaßen gute Leistung zu erzielen, muss sich Ihre Anwendung dieser Dinge bewusst sein, und das bedeutet, dass nur Sharding auf Anwendungsebene sinnvoll ist.
Die Frage ist eher, ob Sie automatisch Sharding durchführen möchten (z. B. durch Hashing von Primärschlüsseln bestimmen, welche Zeile in welchen Knoten verschoben wird) oder ob Sie die Funktion manuell aufteilen möchten ("Die Tabellen zur xyz-User Story gehen dahin master, während abc und def verwandte Tabellen zu diesem Master gehen ").
Funktionales Sharding hat den Vorteil, dass es für die meisten Entwickler die meiste Zeit unsichtbar ist, wenn es richtig gemacht wird, da alle Tabellen, die sich auf ihre User Story beziehen, lokal verfügbar sind. Dadurch können sie so lange wie möglich von deklarativem SQL profitieren und haben weniger Netzwerklatenz, da die Anzahl der netzwerkübergreifenden Übertragungen minimal gehalten wird.
Funktionales Sharding hat den Nachteil, dass keine einzelne Tabelle größer als eine Instanz sein kann und die manuelle Aufmerksamkeit eines Designers erforderlich ist.
Funktionales Sharding hat den Vorteil, dass es relativ einfach an einer vorhandenen Codebasis mit einer Reihe von Änderungen durchgeführt werden kann, die nicht übermäßig groß sind. http://Booking.com hat es in den letzten Jahren mehrmals gemacht und es hat gut für sie funktioniert.
Nachdem ich das alles gesagt habe und Ihre Frage betrachte, glaube ich, dass Sie die falschen Fragen stellen, oder ich verstehe Ihre Problemstellung völlig falsch.
Sharding auf Anwendungsebene: dbShards ist das einzige mir bekannte Produkt, das "anwendungsbewusstes Sharding" ausführt. Es gibt ein paar gute Artikel auf der Website. Nur per Definition wird anwendungsbewusstes Sharding effizienter sein. Wenn eine Anwendung genau weiß, wohin sie mit einer Transaktion gehen soll, ohne sie nachschlagen oder von einem Proxy umleiten zu müssen, ist dies an sich schneller. Und Geschwindigkeit ist oft eines der Hauptanliegen, wenn nicht das einzige, wenn sich jemand mit Scherben befasst.
Einige Leute "scherben" mit einem Stellvertreter, aber in meinen Augen macht das den Zweck des Scherbens zunichte. Sie verwenden lediglich einen anderen Server, um Ihren Transaktionen mitzuteilen, wo sich die Daten befinden oder wo sie gespeichert werden sollen. Mit anwendungsbewusstem Sharding weiß Ihre Anwendung von selbst, wohin sie gehen muss. Viel effizienter.
Dies ist wirklich das gleiche wie # 2.
Kennen Sie interessante Projekte oder Tools in diesem Bereich?
Mehrere neue Projekte in diesem Bereich:
Shard-Query ist eine OLAP-basierte Sharding-Lösung für MySQL. Hier können Sie eine Kombination aus Sharded-Tabellen und nicht gehärteten Tabellen definieren. Die nicht gehärteten Tabellen (wie Nachschlagetabellen) können frei mit Sharded-Tabellen verbunden werden, und Sharded-Tabellen können miteinander verbunden werden, solange die Tabellen durch den Shard-Schlüssel verbunden werden (kein Cross-Shard oder Self-Joins, die Shard-Grenzen überschreiten). Als OLAP-Lösung hat Shard-Query normalerweise eine Mindestantwortzeit von 100 ms oder weniger, selbst bei einfachen Abfragen, sodass es für OLTP nicht funktioniert. Shard-Query dient zur parallelen Analyse großer Datenmengen.
OLTP-Sharding-Lösungen gibt es auch für MySQL. Zu den Closed-Source-Lösungen gehören ScaleDB und DBShards . Zu den Open Source-OLTP-Lösungen gehören JetPants , Cubrid oder Flock / Gizzard (Twitter-Infrastruktur).
Bewerbungsniveau natürlich.
Der beste Ansatz, den ich je in diesem Buch gefunden habe
Hochleistungs-MySQL http://www.amazon.com/High-Performance-MySQL-Jeremy-Zawodny/dp/0596003064
Kurzbeschreibung: Sie können Ihre Daten in viele Teile aufteilen und ~ 50 Teile auf jedem Server speichern. Es wird Ihnen helfen, das zweitgrößte Problem des Splitterns zu vermeiden - das Neuausgleichen. Verschieben Sie einfach einige von ihnen auf den neuen Server und alles wird gut :)
Ich empfehle Ihnen dringend, es zu kaufen und den Teil "MySQL-Skalierung" zu lesen.
Ab 2018 scheint es dafür eine MySql-native Lösung zu geben. Es gibt tatsächlich mindestens 2 - InnoDB Cluster und NDB Cluster (es gibt eine kommerzielle und eine Community-Version davon).
Da die meisten Benutzer der MySql Community Edition mit der InnoDB-Engine besser vertraut sind, sollte dies als erste Priorität untersucht werden. Es unterstützt die sofortige Replikation und Partitionierung / das Sharding und basiert auf MySql Router für verschiedene Routing- / Lastausgleichsoptionen.
Die Syntax für die Erstellung Ihrer Tabellen muss sich beispielsweise ändern:
CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH ( YEAR(col3) );
(Dies ist nur einer von vier Partitionierungstypen )
Eine sehr wichtige Einschränkung:
InnoDB-Fremdschlüssel und MySQL-Partitionierung sind nicht kompatibel. Partitionierte InnoDB-Tabellen können weder Fremdschlüsselreferenzen noch Spalten enthalten, auf die durch Fremdschlüssel verwiesen wird. InnoDB-Tabellen, die Fremdschlüssel haben oder auf die von Fremdschlüsseln verwiesen wird, können nicht partitioniert werden.
PARTITION BY HASH(YEAR...)
scannt alle Partitionen , wenn Sie einen Datumsbereich haben. Yuck.