Wie kann verhindert werden, dass sich zwei Benutzer gleichzeitig mit demselben Benutzernamen registrieren?

11

Wir können Registrierungen nicht serialisieren, da sich Millionen von Benutzern gleichzeitig registrieren. Parallele Registrierungen müssen stattfinden.

Angenommen, die Datenbank enthält keinen Benutzernamen 'user1'. Wenn zwei Benutzer versuchen, sich gleichzeitig bei 'user1' zu registrieren, wird dies akzeptiert. Aber es wird später Probleme verursachen. Das sollte nicht passieren.

Ich suche nach einer logischen Lösung. Nichts Bestimmtes. Nur eine Idee, um dies zu lösen.

Addzy K.
quelle
Wenn Sie in Ihrem vorherigen Versuch , dies bei The Workplace zu veröffentlichen, eine Erklärung gegeben haben , lesen Sie bitte Warum
Mücke
4
Es ist ein legitimes Problem mit der Softwarearchitektur. Nicht die Art von Problem, die nur eine gute Interviewfrage macht und sonst nichts.
Karl Bielefeldt
7
Millionen von Benutzern, die sich gleichzeitig registrieren? "Ja wirklich?" Wenn sich Millionen von Benutzern gleichzeitig registrieren, haben Sie größere Probleme - beispielsweise den Umgang mit Milliarden registrierter Benutzer. Und wahrscheinlich das Geld, um sich Server zu leisten, die damit umgehen.
Gnasher729
2
@AddzyK Dies ist ein hypothetisches Problem in der Zukunft, für das Sie eine logische Lösung wünschen? Ich bin mir ziemlich sicher, dass dies hier nicht möglich ist.
Paparazzo
3
Hier ist eine hypothetische Antwort: Bezahle jemand anderen dafür, der bereits weiß, was zu tun ist. Mit Millionen neuer Benutzer pro Sekunde haben Sie das Geld.
Whatsisname

Antworten:

15

Angenommen, die Datenbank enthält keinen Benutzernamen 'user1'. Wenn zwei Benutzer versuchen, sich gleichzeitig bei 'user1' zu registrieren, wird dies akzeptiert.

Warum sollte es das akzeptieren? Es ist einfach, eine eindeutige Einschränkung anzuwenden, den Benutzernamen als Primärschlüssel zu verwenden oder einfach den eingecheckten Anwendungscode innerhalb einer Transaktion auszuführen.

Sie sollten unbedingt in der Lage sein, eine Datenbanktransaktion zu verwenden, um die Datenbank zu verwenden, um dies zu verhindern. Andernfalls könnte keine Anwendung Invarianten in Datenbankdaten verwalten.

In Bezug auf die Skalierung haben Datenbanken bereits die Technologien erfunden, die Sie benötigen, z. B. verschiedene Sperrmodi, je nachdem, welche Art von Konsistenz Sie benötigen, verteilte Datenbanken für mehrere Datenbankserver usw.

DeadMG
quelle
Verhindert das Sperren der Registrierungen nicht, dass sich andere Benutzer gleichzeitig registrieren?
Addzy K
2
+1, Ich habe nur ein paar grobe Berechnungen angestellt, und selbst Facebook meldet nur durchschnittlich ein paar Anmeldungen pro Sekunde. Es sollte daher ausreichend sein, sich auf die eigenen Einschränkungen der Datenbank zu verlassen.
Großmeister
2
@AddzyK: Das Sperren erfolgt nur für den kurzen Moment, in dem die Datenbank die Einschränkungen erzwingen muss. Ja, andere Benutzer, die sich gleichzeitig registrieren, müssen in der Schlange stehen, aber diese Wartezeit ist sehr kurz und tritt selbst auf den größten Systemen ohnehin selten auf.
Robert Harvey
1
@GrandmasterB Die Durchschnittswerte erzählen hier möglicherweise nicht die ganze Geschichte. Ich nahm aufgrund der Frage an, dass dies für die Bewältigung schwerer Spitzenlasten gedacht war - zum Beispiel für die australische Volkszählung.
DeadMG
@AddzyK Es könnte reichen. Im Wesentlichen können Sie davonkommen, indem Sie nur einen Teil des Tisches sperren . Es gibt zahlreiche Schemata, um damit umzugehen, wie die Antwort von gnasher729, aber ich glaube, dass Sie in der Lage sein sollten, ein verteiltes Datenbankprodukt von der Stange zu erhalten, das dies für Sie erledigt. Selbst wenn Sie Ihr eigenes Teilverriegelungsschema rollen müssen, gibt es viele bekannte Möglichkeiten, damit umzugehen, wie z. B. DHT.
DeadMG
7

Hierfür gibt es eine Standardlösung. Erstellen Sie mehrere Mitarbeiter, um die Registrierungen durchzuführen. Auf jede Anforderung wird ein Hash auf den Benutzernamen angewendet, und der Hash bestimmt, welcher Worker die Anforderung verarbeitet. Auf diese Weise können nicht zwei Anforderungen für denselben Benutzernamen gleichzeitig verarbeitet werden.

Berücksichtigen Sie für diese Art von Anforderungsvolumen einen verteilten Schlüsselwertspeicher wie das Risiko anstelle einer vollständigen Datenbank als Datenspeicher.

Michael Shaw
quelle
2

Ist es ein Problem ?

Es ist nicht akzeptabel, zwei Benutzer ihre Registrierung mit einem nicht eindeutigen Benutzernamen abschließen zu lassen, wenn der Benutzername (und nicht die Benutzer-E-Mail-Adresse) für die Anmeldung verwendet wird.

Wenn der Benutzername nicht für die Authentifizierung verwendet wird, können Sie mithilfe eines Hintergrundprozesses die Doubles identifizieren und kennzeichnen (z. B. basierend auf dem Zeitstempel) und den Benutzer zwingen, seinen Benutzernamen bei der nächsten Anmeldung zu ändern

Ja, das ist ein Problem

Wie Sie fragen, nehme ich an, dass der Benutzername eine eindeutige ID sein soll. Folgende Ansätze könnten verwendet werden:

  1. Vorher: Sehen Sie im Registrierungsprozess einen Schritt vor, in dem der neue Benutzer die Verfügbarkeit seines Namens überprüfen muss. Reservieren Sie dabei den verfügbaren Kontonamen mit einem temporären Status und einer Sitzungs-ID, mit der die Registrierung abgeschlossen werden kann.
  2. Gleiche Zeit: Eine allgemeinere und flexiblere Variante der Antwort von gnasher729 wäre die Verwendung einer einfachen Hash-Funktion (wie sie zum Verwalten von Symboltabellen verwendet wird), um die ID einem eindeutigen Registrierungsserver i (i = h (Benutzername) modulo zuzuweisen Anzahl_der_Server), die die Eindeutigkeit seines begrenzten / segmentierten Bereichs behandeln
  3. Nachher: Wenn der Benutzer am Ende der Registrierung auf " registerAnfrage an Ihre Transaktionsdatenbank senden" klickt , können Sie das Feld als eindeutig definieren. Senden Sie dem unglücklichen Benutzer bei einem Fehler die Nachricht "Ups, es gab ein Problem" und bitten Sie ihn, eine andere ID zu wählen.
  4. Asynchron: Registrieren Sie den Benutzer. Lesen Sie den Benutzerdatensatz kurz danach erneut, um sicherzustellen, dass er unverändert und der einzelne ist. Wenn es sich um ein Problem handelt, bitten Sie den Benutzer, Änderungen vorzunehmen (nicht so asynchron) oder ihm eine E-Mail zu senden, dass ein Problem aufgetreten ist (asynchron, aber aus Anwendersicht ärgerlich), oder lassen Sie ihn sich registrieren, fragen Sie ihn jedoch nach seiner E-Mail-Adresse (zur Disambiguierung) und zwingen Sie ihn, den Benutzernamen im Rahmen des Anmeldevorgangs zu ändern.
Christophe
quelle
1

Überdenken Sie, was Sie als eindeutige Kennung für einen Benutzer betrachten. Jeder Benutzer hat bereits eine eindeutige E-Mail-Adresse, sodass das Problem bereits für Sie gelöst wurde. Dies bedeutet natürlich, dass mehrere Benutzer denselben Namen wie "Mike Nakis" registrieren können. Gibt es ein Problem damit? Bist du sicher? Dies ist beispielsweise für Facebook kein Problem. Es gibt mehrere Facebook-Nutzer namens "Mike Nakis". Schauen Sie sich die Facebook-Anmeldeseite an: Sie werden nach "E-Mail oder Telefon" und "Passwort" gefragt.

Mike Nakis
quelle
0

Bei Millionen von Benutzern, die sich gleichzeitig registrieren, verwenden Sie nur 26 x 26 Registrierungsserver, einen für Benutzer, die mit aa beginnen, einen für Benutzer, die mit ab beginnen, und so weiter. Infolgedessen registrieren sich nur Tausende von Benutzern gleichzeitig auf jedem Server. Wenn Sie damit immer noch nicht umgehen können, verwenden Sie 26 x 26 x 26 Server.

gnasher729
quelle
5
... und dann möchte Ihr Produktbesitzer international werden ...
Telastyn
2
Die gleichen Prinzipien gelten für Unicode-Zeichenfolgen, sofern sie in einer normalisierten Form vorliegen, z. B. NFKD. Sie können den Benutzernamen auch hashen und basierend auf dem Hash anwenden. Diese Antwort implementiert jedoch im Grunde nur Ihre eigene verteilte Datenbank.
DeadMG
1
Sie meinen, sie haben Millionen von Benutzern, die sich gleichzeitig in einem Land registrieren ? In diesem Fall sollten sie genug Geld haben, um mehr für eine echte Lösung zu bezahlen.
Gnasher729
Insbesondere ist dies nur der Anfang davon, wie DHTs durchgeführt werden.
DeadMG
Wie kann das Problem behoben werden, dass zwei Benutzer gleichzeitig denselben Namen registrieren - beide Namen beginnen mit denselben zwei Zeichen und werden daher von demselben Registrierungsserver behandelt?
HorusKol