SQL Server-Datenbank-Sharding - Was tun mit allgemeinen Daten / nicht Sharded-Daten?

10

Wir haben eine sehr große Datenbank auf Unternehmensebene. Als Teil unseres Geschäftsmodells greifen alle Webbenutzer jeden Monat zur gleichen Zeit auf unsere Webserver zu, was wiederum unsere SQL-Box hämmert. Der Verkehr ist sehr stark und wächst weiter, je größer das Unternehmen wird. Die SQL Proc-Optimierung wurde durchgeführt und die Hardware wurde bereits auf ein sehr hohes Niveau skaliert.

Wir möchten die Datenbank jetzt aufteilen, um sicherzustellen, dass wir das Unternehmenswachstum und zukünftige Belastungen bewältigen können.

Wir haben entschieden, welche bestimmten Daten gespeichert werden sollen. Es ist eine Teilmenge unserer Datenbank, die stark genutzt wird.

Meine Frage bezieht sich jedoch auf die nicht gesplitteten Daten, die allgemein / universell sind. Ein Beispiel für solche Daten kann beispielsweise eine Inventartabelle oder möglicherweise eine Mitarbeitertabelle, eine Benutzertabelle usw. Sein.

Ich sehe zwei Möglichkeiten, um mit diesen gemeinsamen / universellen Daten umzugehen:

1) Design 1 - Platzieren Sie die gemeinsamen / universellen Daten in einer externen Datenbank. Alle Schreibvorgänge werden hier ausgeführt. Diese Daten werden dann auf jeden Shard repliziert, sodass jeder Shard diese Daten lesen und in t-sql procs mit diesen Daten verknüpfen kann.

2) Design 2 - Geben Sie jedem Shard eine eigene Kopie aller allgemeinen Daten. Lassen Sie jeden Shard lokal in diese Tabellen schreiben und verwenden Sie die SQL Merge-Replikation, um diese Daten auf allen anderen Shards zu aktualisieren / zu synchronisieren.

Bedenken hinsichtlich Design # 1

1) Transaktionsprobleme: Wenn Sie eine Situation haben, in der Sie Daten in einen Shard schreiben oder aktualisieren und dann beispielsweise eine gemeinsame / universelle Tabelle in 1 gespeicherten Prozess schreiben / aktualisieren müssen, können Sie dies nicht mehr einfach tun. Die Daten sind jetzt in separaten SQL-Instanzen und -Datenbanken vorhanden. Möglicherweise müssen Sie MS DTS einbeziehen, um festzustellen, ob Sie diese Schreibvorgänge in eine Transaktion einbinden können, da sie sich in einer separaten Datenbank befinden. Die Leistung ist hier ein Problem, und mögliche Umschreibungen können für Prozesse erforderlich sein, die in Sharded- und Common-Daten schreiben.

2) ein Verlust der referenziellen Integrität. Datenbankübergreifende referenzielle Integrität ist nicht möglich.

3) Neukodieren großer Bereiche des Systems, damit es gemeinsame Daten in die neue universelle Datenbank schreiben, aber gemeinsame Daten aus den Shards lesen kann.

4). erhöhte Datenbankfahrten. Wenn Sie wie oben beschrieben auf eine Situation stoßen, in der Sie Sharded-Daten und allgemeine Daten aktualisieren müssen, werden Sie mehrere Roundtrips durchführen, um dies zu erreichen, da sich die Daten jetzt in separaten Datenbanken befinden. Einige Netzwerklatenzzeiten hier, aber ich mache mir weniger Sorgen um dieses Problem als die oben genannten 3.

Bedenken bezüglich Design # 2

In Design Nr. 2 erhält jeder Shard eine eigene Instanz aller gemeinsamen / universellen Daten. Dies bedeutet, dass der gesamte Code, der mit allgemeinen Daten verknüpft oder diese aktualisiert, weiterhin wie heute funktioniert / ausgeführt wird. Das Entwicklungsteam benötigt nur sehr wenig Umcodierung / Umschreibung. Dieses Design hängt jedoch vollständig von der Zusammenführungsreplikation ab, um die Daten über alle Shards hinweg synchron zu halten. Die dbas sind hochqualifiziert und sehr besorgt darüber, dass die Zusammenführungsreplikation möglicherweise nicht in der Lage ist, dies zu handhaben. Sollte die Zusammenführungsreplikation fehlschlagen, ist die Wiederherstellung nach diesem Fehler nicht großartig und könnte sich sehr negativ auf uns auswirken.

Ich bin gespannt, ob sich jemand für Designoption 2 entschieden hat. Ich bin auch neugierig zu wissen, ob ich eine 3. oder 4. Designoption übersehen habe, die ich nicht sehe.

danke im Voraus.

Matt
quelle
10
Was ist in diesem Fall "eine sehr große Unternehmensdatenbank" und Hardware, die "bereits auf ein sehr hohes Niveau skaliert wurde"? 10 von 10 Fällen ist Sharding nicht die Lösung. Fragen Sie sich also, welches Problem Sie lösen.
Mark Storey-Smith
5
In aller Ernsthaftigkeit sagen Sie, dass Ihre Webserver Ihre SQL-Box "hämmern". Welches Verhältnis wird gelesen: schreiben? Es gibt viele, viele Möglichkeiten, Lesevorgänge ohne Sharding zu skalieren, mit Kompromissen bei Leistung, Kosten oder Komplexität, je nachdem, wie aktuell die Daten wirklich sein müssen. Und natürlich gibt es Möglichkeiten, Schreibvorgänge in die Warteschlange zu stellen, je nachdem, wie hoch die Nanosekunden im Ruhezustand sein müssen.
Aaron Bertrand
3
Diese besondere Aussage erregte meine Aufmerksamkeit: "Hardware wurde bereits auf ein sehr hohes Niveau skaliert." Was ist in dieses Hardware-Scale-up geflossen?
Swasheck
2
Sie haben 64 logische Prozessoren und die CPU ist der Engpass? Was treibt die CPU genau an, kompiliert neu? Wissen Sie?
Aaron Bertrand
1
Überprüfen Sie Ihre Hosen, wenn Sie fertig sind.
Swasheck

Antworten:

5

Ihre Frage konzentrierte sich auf Folgendes:

Meine Frage bezieht sich jedoch auf die nicht gesplitteten Daten, die allgemein / universell sind. Ein Beispiel für solche Daten kann beispielsweise eine Inventartabelle oder möglicherweise eine Mitarbeitertabelle, eine Benutzertabelle usw. Sein.

Wenn Sie Sharding durchführen und Daten haben, die alle Shards sehen müssen, müssen Sie diese Daten mit einigen Attributen klassifizieren:

Ändert es sich häufig? In Ihren Beispielen haben Sie Inventar, Mitarbeiter und Benutzer aufgelistet. Normalerweise ändert sich das Inventar sehr schnell, aber die Mitarbeiterdatensätze ändern sich nur regelmäßig (z. B. einige hundert Aktualisierungen pro Tag).

Wie viel Verzögerung kann jeder Splitter tolerieren?Auch wenn sich das Inventar ständig ändert, können Sie in der Regel eine große Verzögerung (Minuten oder sogar Stunden) für eine solche Tabelle tolerieren. Wenn Sie einzigartige Artikel mit einer sehr begrenzten Menge verkaufen, die Sie niemals wieder auffüllen können (denken Sie an Originalkunstwerke), werden diese Daten überhaupt nicht gespeichert - Sie fragen nur die Originaldatenbank ab. In den meisten Online-Shops verkaufen Sie jedoch nicht jeden Tag jeden Artikel aus, und Sie werden die Dinge ohnehin schnell wieder auffüllen, sodass Sie keine Lagerbestände von bis zu Millisekunden benötigen. Tatsächlich benötigen Sie in den meisten Fällen nur ein In-Stock-Flag, das entweder 0 oder 1 ist, und ein zentraler Prozess aktualisiert dieses Flag. Auf diese Weise müssen Sie nicht jede Aufwärts- / Abwärtsbewegung der Gegenstandszählung auf jeden Splitter übertragen. Mitarbeiter- oder Benutzerdaten hingegen

Werden Sie sich von den Sharded-Tischen zu den nicht-Sharded-Tischen verbinden? Im Idealfall lautet die Antwort hier Nein. Sie sollten zwei separate Abfragen durchführen, um die Daten abzurufen, und sie dann auf der App-Seite verbinden. Aus App-Sicht wird dies viel schwieriger, aber Sie können die aktuellsten Daten aus jeder Quelle abrufen.

Sind diese Originaldaten oder kopiert?Eine andere Art, sich diese Frage vorzustellen: Was müssen Sie sichern und wie oft? In der Regel möchten Sie in einer Sharding-Umgebung mit hohem Volumen, dass die Sicherungen so schnell und so klein wie möglich sind. (Schließlich müssen Sie jeden Knoten schützen, und Sie möchten, dass alle Shards zum gleichen Zeitpunkt auf DR umgeschaltet werden. Einige Shards enthalten keine neueren Daten als andere.) Dies bedeutet, dass die Shards und die Nicht-Shards Sharded-Daten sollten sich in vollständig separaten Datenbanken befinden - auch wenn sie sich auf demselben Server befinden. Möglicherweise benötige ich ständige Transaktionsprotokollsicherungen meiner Sharded-Daten (Originaldaten), aber möglicherweise muss ich die nicht Sharded-Daten überhaupt nicht sichern. Es ist wahrscheinlich einfacher für mich, meine Mitarbeiter- oder Benutzertabelle nur aus der einzigen Quelle der Wahrheit zu aktualisieren, als sie auf jedem Shard zu sichern. Wenn sich jedoch alle meine Daten in einer einzigen Datenbank befinden,

Nun zu Ihren Bedenken:

"Transaktionsprobleme ... Sie werden dies nicht mehr einfach tun können." Richtig. Werfen Sie in Sharded-Szenarien das Konzept einer Transaktion aus dem Fenster. Es wird auch schlimmer - für die Sharded-Daten kann es sein, dass ein Shard online und ein anderer Shard vorübergehend aufgrund eines Failovers oder Neustarts der Clusterinstanz heruntergefahren ist. Sie müssen jederzeit einen Ausfall eines Teils des Systems planen.

"Datenbankübergreifende referenzielle Integrität ist nicht möglich." Richtig. Wenn Sie eine einzelne Tabelle auf mehrere Server aufteilen, ziehen Sie Ihre großen Hosen an und teilen dem Datenbankserver mit, dass Sie schwierige Aufgaben wie Backups zu bestimmten Zeitpunkten, Beziehungen zwischen Tabellen und das Kombinieren von Daten von übernehmen mehrere Quellen. Es liegt jetzt an Ihnen und Ihrem Code.

"Große Bereiche des Systems neu codieren, damit es gemeinsame Daten in die neue universelle Datenbank schreiben, aber gemeinsame Daten aus den Shards lesen kann." Richtig auch hier. Es gibt keine einfache Schaltfläche dafür, aber sobald Sie diese in die App integriert haben, können Sie wie verrückt skalieren. Ich würde argumentieren, dass der einfachere Weg, dies zu tun, darin besteht, die Verbindungen der App durch Lesevorgänge aufzuteilen .

"Erhöhte Datenbankfahrten." - Ja, wenn Sie die Daten in mehrere Server aufteilen, muss die App das Netzwerk stärker erreichen. Der Schlüssel besteht darin, auch das Caching zu implementieren, damit einige dieser Daten in kostengünstigeren, sperrfreien Systemen mit höherem Durchsatz gespeichert werden können. Die schnellste Abfrage ist die, die Sie nie stellen.

Ich habe hier auch weitere Vor- und Nachteile für die Aufteilung von Datenbanken mit mehreren Mandanten festgelegt , z. B. die Leistungsoptimierung für einzelne Shards, verschiedene Sicherungs- / Wiederherstellungsstrategien pro Shard und Herausforderungen bei der Schemabereitstellung.

Brent Ozar
quelle
0

Auf hoher Ebene besteht der typische Weg zum Shard (oder zur horizontalen Partitionierung) von Daten darin, die Transaktionstabellen zu sharden und die Tabellen auf Master-Ebene zu replizieren. Wie die meisten Technologielösungen löst dies natürlich eine Reihe von Problemen und schafft eine ganze Reihe neuer Probleme ... aber wir sind mittlerweile alle daran gewöhnt, nicht wahr? ;-);

Ich würde jedoch fragen, ob SQLServer Ihre beste Lösung dafür ist. Entspricht die Arbeitslast eher OLTP oder eher DW / BI?

Prost, Dave Sisk

Dave Sisk
quelle
-2

Eine mögliche 3. Option. Mit relationalem Sharding (anstelle von Black-Box-Sharding) sollten Sie in der Lage sein, Ihre gesamte Datenbank zu sharden und zu verteilen. Da die Datenbank auf einem traditionellen relationalen Datenmodell basiert, weiß sie, welche Daten auf welchen Servern gespeichert sind und wo sie sich befinden, sodass alle Ihre Daten als "allgemein / universell" betrachtet werden können. Schauen Sie sich dbShards an, um den gesamten Sharding-Prozess zu vereinfachen.

Tyler Andrews
quelle
3
Diese Antwort macht keinen Sinn, ohne eine Erklärung für relationales Sharding, Black-Box-Sharding, was sie tun, warum eines besser ist als das andere und vorzugsweise das Eingeständnis, dass Ihr Arbeitgeber dbShards ist.
Jeremiah Peschka