Kurzversion
Wenn ich meine Benutzer in Shards aufteile, wie biete ich eine "Benutzersuche" an? Offensichtlich möchte ich nicht, dass jede Suche jeden Splitter trifft.
Lange Version
Mit Shard habe ich mehrere Datenbanken, von denen jede einen Bruchteil der gesamten Daten enthält. Für ein naives Beispiel können die Datenbanken UserA, UserB usw. Benutzer enthalten, deren Namen mit "A", "B" usw. beginnen. Wenn sich ein neuer Benutzer anmeldet, prüfe ich einfach seinen Namen und setze ihn in die richtige Richtung Datenbank. Wenn sich ein wiederkehrender Benutzer anmeldet, schaue ich erneut auf seinen Namen, um die richtige Datenbank zu ermitteln, aus der er seine Informationen abrufen kann.
Der Vorteil von sharded vs read replication besteht darin, dass die read replication Ihre Schreibvorgänge nicht skaliert. Alle Schreibvorgänge, die zum Master gehen, müssen zu jedem Slave gehen. In gewisser Weise tragen sie alle dieselbe Schreiblast, obwohl die Lese-Last verteilt ist.
Währenddessen interessieren sich Scherben nicht für die Schreibweisen der anderen. Wenn sich Brian beim UserB-Shard anmeldet, muss der UserA-Shard nichts davon hören. Wenn Brian eine Nachricht an Alex sendet, kann ich diese Tatsache sowohl in den UserA- als auch in den UserB-Shards aufzeichnen. Wenn sich entweder Alex oder Brian einloggen, kann er alle seine gesendeten und empfangenen Nachrichten von seinem eigenen Shard abrufen, ohne alle Shards abzufragen.
So weit, so gut. Was ist mit Suchen? Wenn Brian in diesem Beispiel nach "Alex" sucht, kann ich UserA überprüfen. Aber was, wenn er nach Alex mit seinem Nachnamen "Smith" sucht? Es gibt Smiths in jeder Scherbe. Von hier aus sehe ich zwei Optionen:
Kann also die Suche skaliert werden? Wenn ja, ist dieser Indexierungsansatz der richtige? Gibt es noch andere?
Es gibt kein Wundermittel.
Die Suche nach jedem Shard in Folge ist natürlich aufgrund der unglaublich hohen Latenz nicht möglich.
Sie wollen also parallel suchen, wenn Sie müssen.
Es gibt zwei realistische Optionen, die Sie bereits aufgelistet haben: Indizierung und parallelisierte Suche. Erlauben Sie mir, näher darauf einzugehen, wie Sie sie gestalten würden.
Die wichtigste Erkenntnis, die Sie verwenden können, ist, dass Sie in der Suche selten den vollständigen Satz von Ergebnissen benötigen. Sie brauchen nur die erste (oder n-te) Seite der Ergebnisse. Es gibt also ziemlich viel Spielraum, um die Reaktionszeit zu verkürzen.
Indizierung
Wenn Sie die Attribute kennen, nach denen die Benutzer gesucht werden, können Sie benutzerdefinierte, separate Indizes für sie erstellen. Sie können Ihren eigenen invertierten Index erstellen, der auf das Tupel (shard, recordId) für jeden Suchbegriff oder auf Sie verweist kann es in der Datenbank speichern. Aktualisieren Sie es langsam und asynchron. Ich kenne Ihre Anwendungsanforderungen nicht, es könnte sogar möglich sein, den Index jede Nacht neu zu erstellen (was bedeutet, dass Sie an einem bestimmten Tag nicht die neuesten Einträge haben - aber das könnte für Sie in Ordnung sein). Stellen Sie sicher, dass dieser Index für die Größe optimiert wird, damit er in den Speicher passt. Beachten Sie, dass Sie diesen Index bei Bedarf überschreiben können.
Wenn Leute nach etwas wie "lastname='Smith' OR lastname='Jones'"
suchen können, können Sie natürlich den Index für Smith lesen, den Index für Jones lesen und die Union berechnen - Sie müssen nicht alle möglichen Abfragen speichern, nur ihre Gebäudeteile .
Parallele Suche
Senden Sie für jede Abfrage Anforderungen an alle Shards, sofern Sie nicht wissen, nach welchem Shard gesucht werden soll, da sich die Suche zufällig auf dem Verteilungsschlüssel befindet. Machen Sie die Anfragen asynchron. Antworten Sie dem Benutzer, sobald Sie die erste Seite der Ergebnisse erhalten; Sammeln Sie den Rest und cachen Sie lokal, so dass, wenn der Benutzer auf "Weiter" klickt, Sie die Ergebnisse bereit haben und die Server nicht erneut abfragen müssen. Wenn einige der Server länger dauern als andere, müssen Sie nicht darauf warten, dass die Server die Anfrage bearbeiten.
Wenn Sie schon dabei sind, protokollieren Sie die Antwortzeiten der Server, die sich im Sharded-Modus befinden, um mögliche Probleme mit ungleichmäßigen Daten und / oder Lastverteilung zu erkennen.
Ich gehe davon aus, dass Sie über Scherben sprechen: Ссылка
Wenn Sie diesen Artikel lesen, geht er genau auf Ihre Frage ein, aber lange Antwort kurz, Sie schreiben benutzerdefinierten Anwendungscode, um Ihre unterschiedlichen Splitter zusammen zu bringen. Sie können Smart Hashing durchführen, um einzelne Shards abzufragen und Daten in Shards einzufügen. Sie müssen eine spezifischere Frage stellen, um eine spezifischere Antwort zu erhalten.
Sie brauchen tatsächlich jede Suche, um jeden Shard zu treffen, oder zumindest muss jede Suche nach einem Index durchgeführt werden, der die Daten von allen Shards enthält, was auf dasselbe hinausläuft.
Vermutlich basiert das Shard auf einer einzigen Eigenschaft des Benutzers, wahrscheinlich auf einem Hash des Benutzernamens. Wenn Ihre Suchfunktion dem Benutzer ermöglicht, basierend auf anderen Eigenschaften des Benutzers zu suchen, ist klar, dass es keinen einzelnen Shard oder eine Teilmenge von Shards gibt, die eine Abfrage erfüllen können, da ein Shard Benutzer enthalten kann, die der Abfrage entsprechen. Sie können keine Shards vor der Suche ausschließen, was bedeutet, dass Sie die Abfrage für alle Shards ausführen müssen.
Sie können sich Sphinx ( Ссылка ) ansehen. Es unterstützt die verteilte Suche. GigaSpaces hat eine parallele Abfrage- und Zusammenführungsunterstützung. Dies kann auch mit MySQL Proxy ( Ссылка ) erfolgen.
Um eine nicht-sharded indizierte Arten zu erstellen, wird der Zweck des Shards an erster Stelle besiegt :-) Ein zentralisierter Index wird wahrscheinlich nicht funktionieren, wenn Shards notwendig sind.
Ich denke, alle Scherben müssen parallel getroffen werden. Die Ergebnisse müssen gefiltert, sortiert, sortiert, gruppiert und die Ergebnisse aus allen Shards zusammengeführt werden. Wenn die Scherben selbst überwältigt werden, musst du das übliche tun (Reshard, Scale Up, etc.), um sie wieder zu überwältigen.
Tags und Links database sharding scalability