Come impedire a due utenti di registrarsi nello stesso istante con lo stesso nome utente?


11

Non possiamo serializzare le registrazioni poiché ci sono milioni di utenti che si registrano contemporaneamente. È necessario che si verifichino registrazioni parallele.

Supponiamo che il database non contenga il nome utente 'user1'. Quando due utenti tentano di registrarsi nello stesso momento con "user1", lo accetteranno. Ma in seguito causerà problemi. Questo non dovrebbe succedere.

Sto cercando una soluzione logica. Niente di specifico. Solo un'idea per risolvere questo.


data una spiegazione nel tuo precedente tentativo di pubblicarlo su The Workplace, prendi in considerazione l'idea di dare una lettura a Perché le domande di intervista fanno scarse domande su Programmers.SE?
moscerino

4
È un legittimo problema di architettura software. Non è il tipo di problema che fa solo una buona domanda per l'intervista e nient'altro.
Karl Bielefeldt,

7
Milioni di utenti che si registrano contemporaneamente? Veramente? Se hai milioni di utenti che si registrano contemporaneamente, hai problemi più grandi, come la gestione di miliardi di utenti registrati. E probabilmente i soldi per permettersi i server che lo gestiscono.
gnasher729,

2
@AddzyK Questo è un problema ipotetico affrontato in futuro a cui si desidera una soluzione logica? Abbastanza sicuro che qui sia fuori portata.
paparazzo,

3
Ecco una risposta ipotetica: pagare qualcun altro per farlo che già sa cosa fare. Con milioni di nuovi utenti / secondo, avrai i soldi.
whatsisname

Risposte:


15

Supponiamo che il database non contenga il nome utente 'user1'. Quando due utenti tentano di registrarsi nello stesso momento con "user1", lo accetteranno.

Perché dovrebbe accettarlo? È semplice applicare un vincolo univoco, utilizzare il nome utente come chiave primaria o semplicemente eseguire il check in del codice dell'applicazione all'interno di una transazione.

Dovresti assolutamente essere in grado di utilizzare una transazione del database per utilizzare il database per evitare che ciò accada. Altrimenti, nessuna applicazione sarebbe in grado di mantenere invarianti nei dati del database.

In termini di ridimensionamento, i database hanno già inventato le tecnologie di cui hai bisogno, come varie modalità di blocco in base esattamente al tipo di coerenza di cui hai bisogno, database distribuiti per più server di database, ecc.


Il blocco delle registrazioni non impedisce ad altri utenti di registrarsi contemporaneamente?
Addzy K,

2
+1, ho appena eseguito alcuni calcoli approssimativi e persino Facebook ha in media solo poche iscrizioni al secondo. Quindi basarsi sui vincoli del database dovrebbe essere sufficiente.
GrandmasterB,

2
@AddzyK: il blocco si verifica solo per il breve momento in cui il database deve applicare i vincoli. Sì, gli altri utenti che si registrano contemporaneamente devono attendere in linea, ma l'attesa è molto breve e si verifica raramente, anche sui sistemi più grandi.
Robert Harvey,

1
@GrandmasterB Le medie potrebbero non raccontare l'intera storia qui. Ho ipotizzato in base alla domanda che questo fosse per la gestione del carico di punta pesante, ad esempio il censimento australiano.
DeadMG,

@AddzyK Potrebbe fare. In sostanza, puoi cavartela solo bloccando la parte del tavolo. Esistono numerosi schemi per gestirlo, come la risposta di gnasher729, ma credo che dovresti essere in grado di ottenere un prodotto di database distribuito standard che può gestirlo per te. Anche se devi implementare il tuo schema di blocco parziale, ci sono molti modi noti per gestirlo, come DHT.
DeadMG,

7

C'è una soluzione standard a questo. Crea più lavoratori per effettuare le registrazioni. Ogni richiesta ha un hash applicato al nome utente e l'hash determina quale lavoratore elabora la richiesta. In questo modo non è possibile elaborare contemporaneamente due richieste per lo stesso nome utente.

Per questo tipo di volume di richieste, considerare un archivio di valori chiave distribuito come rischio anziché un intero database come archivio dati.


2

È un problema ?

Consentire a due utenti di terminare la registrazione con un nome utente non univoco non è accettabile se il nome utente (e non l'e-mail dell'utente) viene utilizzato per l'accesso.

Se il nome utente non viene utilizzato per l'autenticazione, è possibile utilizzare un processo in background per identificare e contrassegnare i doppi (ad esempio in base al timestamp) e forzare l'utente a modificare il nome utente al successivo accesso

Sì, è un problema

Come mi stai chiedendo, suppongo che il nome utente dovrebbe essere un ID univoco. Potrebbero essere utilizzati i seguenti approcci:

  1. Prima: nel processo di registrazione, prevedere un passaggio in cui il nuovo utente deve verificare la disponibilità del proprio nome. In tal caso, conservare il nome account disponibile con uno stato temporaneo e un ID sessione che consentirà di terminare la registrazione.
  2. Stesso tempo: una variante più generale e flessibile della risposta di gnasher729 sarebbe quella di utilizzare una semplice funzione hash (come quelle usate per gestire le tabelle dei simboli), per assegnare l'id a un server di registrazione univoco i (i = h (nome utente) modulo number_of_servers) che gestirà l'unicità nel suo ambito limitato / segmentato
  3. Dopo: al termine della registrazione, quando l'utente fa clic su registerinvia la richiesta al database transazionale, se è possibile definire il campo come univoco. In caso di errore, invia all'utente sfortunato "spiacenti, si è verificato un problema" e chiedigli di scegliere un altro ID.
  4. Asincrono: registra l'utente. Rileggi il record utente subito dopo per assicurarti che sia invariato e quello singolo. Se si tratta di un problema, chiedi all'utente di cambiare (non così asincrono) o di inviargli una mail in cui si è verificato un problema (asincrono, ma fastidioso dal punto di vista dell'utente), oppure lascia che si registri ma chiedigli la sua e-mail (per chiarire le ambiguità) e costringerlo a cambiare nome utente come parte della procedura di accesso.

1

Riconsidera quello che pensi come l'identificatore univoco per un utente. Ogni utente ha già un indirizzo email univoco, quindi il problema è già stato risolto per te. Ovviamente, ciò significa che più utenti saranno in grado di registrare lo stesso nome, come "Mike Nakis". C'è un problema con quello? Sei sicuro? Ad esempio, non è un problema per Facebook. Esistono più utenti di Facebook chiamati "Mike Nakis". Guarda la pagina di accesso di Facebook: richiede "email o telefono" e "password".


0

Con milioni di utenti che si registrano contemporaneamente, usi solo 26 x 26 server di registrazione, uno per gli utenti che iniziano con aa, uno per gli utenti che iniziano con ab e così via. Di conseguenza, ci sono solo migliaia di utenti che si registrano su ciascun server contemporaneamente. Se ancora non riesci a gestirlo, usa server 26 x 26 x 26.


5
... e poi il proprietario del tuo prodotto vuole diventare internazionale ...
Telastyn,

2
Gli stessi principi si applicano alle stringhe Unicode purché siano in forma normalizzata, come NFKD. È inoltre possibile eseguire l'hashing del nome utente e applicarlo in base all'hash. Tuttavia, questa risposta è fondamentalmente solo l'implementazione del proprio database distribuito.
DeadMG

1
Vuoi dire che hanno milioni di utenti che si registrano contemporaneamente in un paese ? In tal caso dovrebbero avere abbastanza soldi per pagare di più per una soluzione reale.
gnasher729,

Più specificamente, questo è solo l'inizio di come vengono fatti i DHT.
DeadMG,

in che modo questo risolve il problema di due utenti che registrano lo stesso nome contemporaneamente: entrambi i nomi inizierebbero con gli stessi due caratteri e quindi sarebbero gestiti dallo stesso server di registrazione?
HorusKol,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.