Comment empêcher deux utilisateurs de s'inscrire au même instant avec le même nom d'utilisateur?

11

Nous ne pouvons pas sérialiser les enregistrements car des millions d'utilisateurs s'enregistrent en même temps. Des enregistrements parallèles doivent avoir lieu.

Disons que la base de données ne contient pas le nom d'utilisateur 'user1'. Lorsque deux utilisateurs essaient de s'enregistrer en même temps avec 'user1', il l'acceptera. Mais cela causera plus tard des problèmes. Cela ne devrait pas arriver.

Je cherche une solution logique. Rien de précis. Juste une idée pour résoudre ce problème.

Addzy K
la source
compte tenu des explications que vous avez fournies lors de votre précédente tentative de publication sur The Workplace, envisagez de lire Pourquoi les questions d'entrevue rendent-elles les programmeurs pauvres?
moucher
4
C'est un problème légitime d'architecture logicielle. Pas le genre de problème qui ne fait qu'une bonne question d'entretien et rien d'autre.
Karl Bielefeldt
7
Des millions d'utilisateurs s'inscrivent en même temps? Vraiment? Si vous avez des millions d'utilisateurs qui s'inscrivent en même temps, vous avez de plus gros problèmes - comme gérer des milliards d'utilisateurs enregistrés. Et probablement l'argent pour se permettre des serveurs qui le gèrent.
gnasher729
2
@AddzyK Il s'agit d'un problème hypothétique rencontré à l'avenir auquel vous souhaitez une solution logique? Je suis sûr que cela est hors de portée ici.
paparazzo
3
Voici une réponse hypothétique: payer quelqu'un d'autre pour le faire qui sait déjà quoi faire. Avec des millions de nouveaux utilisateurs / seconde, vous aurez de l'argent.
whatsisname

Réponses:

15

Disons que la base de données ne contient pas le nom d'utilisateur 'user1'. Lorsque deux utilisateurs essaient de s'enregistrer en même temps avec 'user1', il l'acceptera.

Pourquoi l'accepterait-il? Il est simple d'appliquer une contrainte unique, d'utiliser le nom d'utilisateur comme clé primaire ou d'exécuter simplement le code d'application d'intégration dans une transaction.

Vous devez absolument pouvoir utiliser une transaction de base de données pour utiliser la base de données pour éviter que cela ne se produise. Sinon, aucune application ne serait en mesure de conserver des invariants dans les données de la base de données.

En termes de mise à l'échelle, les bases de données ont déjà inventé les technologies dont vous avez besoin, comme divers modes de verrouillage selon exactement le type de cohérence dont vous avez besoin, des bases de données distribuées pour plusieurs serveurs de bases de données, etc.

DeadMG
la source
Le verrouillage des enregistrements n'empêche-t-il pas les autres utilisateurs de s'inscrire en même temps?
Addzy K
2
+1, vient d'exécuter quelques calculs approximatifs, et même Facebook ne fait en moyenne que quelques inscriptions par seconde. Donc, s'appuyer sur les propres contraintes de la base de données devrait être suffisant.
GrandmasterB
2
@AddzyK: Le verrouillage ne se produit que pour le bref instant où la base de données doit appliquer les contraintes. Oui, les autres utilisateurs qui s'inscrivent simultanément doivent faire la queue, mais cette attente est très courte et se produit rarement de toute façon, même sur les plus gros systèmes.
Robert Harvey
1
@GrandmasterB Les moyennes peuvent ne pas raconter toute l'histoire ici. J'ai supposé sur la base de la question qu'il s'agissait de gérer de fortes charges de pointe, par exemple les recensements australiens.
DeadMG
@AddzyK Cela pourrait faire l'affaire. Essentiellement, vous pouvez vous en sortir en ne verrouillant qu'une partie de la table. Il existe de nombreux schémas pour y faire face, comme la réponse de gnasher729, mais je pense que vous devriez être en mesure d'obtenir un produit de base de données distribué standard qui peut gérer cela pour vous. Même si vous devez rouler votre propre schéma de verrouillage partiel, il existe de nombreuses façons connues de le gérer, comme le DHT.
DeadMG
7

Il existe une solution standard à cela. Créez plusieurs employés pour effectuer les enregistrements. Chaque demande a un hachage appliqué au nom d'utilisateur, et le hachage détermine quel travailleur traite la demande. De cette façon, il n'est pas possible de traiter simultanément deux demandes pour le même nom d'utilisateur.

Pour ce type de volume de demandes, envisagez un magasin de valeurs de clé distribué tel que risque au lieu d'une base de données tout comme magasin de données.

Michael Shaw
la source
2

C'est un problème ?

Laisser deux utilisateurs terminer leur inscription avec un nom d'utilisateur non unique n'est pas acceptable si le nom d'utilisateur (et non l'e-mail de l'utilisateur) est utilisé pour la connexion.

Si le nom d'utilisateur n'est pas utilisé pour l'authentification, vous pouvez utiliser un processus d'arrière-plan pour identifier et signaler les doublons (par exemple en fonction de l'horodatage) et forcer l'utilisateur à changer son nom d'utilisateur lors de la prochaine connexion.

Oui c'est un problème

Comme vous le demandez, je suppose que le nom d'utilisateur est censé être un identifiant unique. Les approches suivantes pourraient être utilisées:

  1. Avant: Dans le processus d'inscription, prévoyez une étape où le nouvel utilisateur doit vérifier la disponibilité de son nom. Ce faisant, pré-réservez le nom de compte disponible avec un statut temporaire et un identifiant de session qui permettront de terminer l'enregistrement.
  2. En même temps: Une variante plus générale et plus flexible de la réponse de gnasher729 serait d'utiliser une simple fonction de hachage (comme celles utilisées pour gérer les tables de symboles), pour assigner l'id à un serveur d'enregistrement unique i (i = h (nom d'utilisateur) modulo number_of_servers) qui gérera l'unicité de sa portée limitée / segmentée
  3. Après: à la fin de l'enregistrement, lorsque l'utilisateur clique sur registerenvoyer la demande à votre base de données transactionnelle, si vous pouvez définir le champ comme unique. En cas d'erreur, envoyez à l'utilisateur malchanceux "oups, il y a eu un problème" et demandez-lui de choisir un autre identifiant.
  4. Asynchrone: enregistrez l'utilisateur. Relisez l'enregistrement utilisateur juste après pour vous assurer qu'il est inchangé et unique. Si c'est un problème, demandez à l'utilisateur de changer (pas si asynchrone), ou envoyez-lui un e-mail qu'il y a eu un problème (asynchrone, mais ennuyeux du point de vue de l'utilisateur), ou laissez-le s'enregistrer mais demandez-lui son e-mail (pour lever l'ambiguïté) et le forcer à changer de nom d'utilisateur dans le cadre de la procédure de connexion.
Christophe
la source
1

Reconsidérez ce que vous pensez comme l'identifiant unique d'un utilisateur. Chaque utilisateur possède déjà une adresse e-mail unique, ce problème a donc déjà été résolu pour vous. Bien sûr, cela signifie que plusieurs utilisateurs pourront enregistrer le même nom, comme "Mike Nakis". Y a-t-il un problème avec ça? Êtes-vous sûr? Ce n'est pas un problème pour Facebook, par exemple. Il existe plusieurs utilisateurs de Facebook appelés "Mike Nakis". Regardez la page de connexion facebook: elle demande "email ou téléphone" et "mot de passe".

Mike Nakis
la source
0

Avec des millions d'utilisateurs s'inscrivant en même temps, vous utilisez simplement 26 x 26 serveurs d'enregistrement, un pour les utilisateurs commençant par aa, un pour les utilisateurs commençant par ab, etc. Par conséquent, seuls des milliers d'utilisateurs s'enregistrent simultanément sur chaque serveur. Si vous ne pouvez toujours pas gérer cela, utilisez des serveurs 26 x 26 x 26.

gnasher729
la source
5
... et puis votre propriétaire de produit veut aller à l'international ...
Telastyn
2
Les mêmes principes s'appliquent aux chaînes Unicode tant qu'elles sont sous une forme normalisée, telle que NFKD. Vous pouvez également hacher le nom d'utilisateur et l'appliquer en fonction du hachage. Cependant, cette réponse consiste simplement à implémenter votre propre base de données distribuée.
DeadMG
1
Vous voulez dire qu'ils ont des millions d'utilisateurs qui s'inscrivent en même temps dans un pays ? Dans ce cas, ils devraient avoir suffisamment d'argent pour payer plus cher pour une vraie solution.
gnasher729
Plus précisément, ce n'est que le début de la façon dont les DHT sont effectués.
DeadMG
comment cela résout-il le problème de deux utilisateurs enregistrant le même nom en même temps - les deux noms commenceraient par les deux mêmes caractères et seraient donc gérés par le même serveur d'enregistrement?
HorusKol