如何防止两个用户同时使用相同的用户名注册?


11

我们无法序列化注册,因为有数百万人同时注册。需要并行注册。

假设数据库不包含用户名“ user1”。当两个用户尝试同时使用“ user1”注册时,它将接受它。但是以后会引起问题。这不应该发生。

我正在寻找一个合理的解决方案。没有什么特别的。解决这个问题的一个想法。


您尝试将其发布到The Workplace 之前尝试给出解释时,考虑阅读以下内容:为什么面试问题会使Programmers.SE问题变差?
t

4
这是一个合法的软件体系结构问题。不是那种只能成为一个很好的面试问题的问题,别无其他。
卡尔·比勒费尔德

7
数百万用户同时注册?真?如果您有数百万个用户同时注册,那么您将遇到更大的问题-例如处理数十亿注册用户。可能还有钱买得起处理它的服务器。
gnasher729

2
@AddzyK这是您将来想要逻辑解决的假设问题?可以肯定的是,这超出了范围。
狗仔队

3
这是一个假想的答案:请别人去做已经知道该怎么做的事情。每秒有数百万的新用户,您将获得现金。
whatsisname

Answers:


15

假设数据库不包含用户名“ user1”。当两个用户尝试同时使用“ user1”注册时,它将接受它。

为什么会接受呢?应用唯一约束,使用用户名作为主键或在事务内部运行签入应用程序代码很简单。

您绝对应该能够使用数据库事务来使用数据库来防止这种情况的发生。否则,任何应用程序都将无法维护数据库数据中的不变性。

在扩展方面,数据库已经发明了您需要的技术,例如各种锁定模式(具体取决于所需的一致性类型),用于多个数据库服务器的分布式数据库等。


锁定注册不会阻止其他用户同时注册吗?
Addzy K

2
+1,只需进行一些粗略的算术运算,甚至Facebook每秒平均仅注册几次。因此,依靠数据库自身的约束就足够了。
GrandmasterB

2
@AddzyK:锁定仅在数据库必须强制执行约束的短暂时间内发生。是的,其他同时注册的用户必须排队等待,但是等待时间非常短,即使在最大的系统上也很少发生。
罗伯特·哈维

1
@GrandmasterB平均值可能无法在此处讲述完整的故事。基于这个问题,我假设这是为了处理高峰负荷(例如澳大利亚人口普查工作)。
DeadMG

@AddzyK可能会的。本质上,仅锁定表的一部分就可以逃脱。有许多解决方案,例如gnasher729的答案,但是我相信您应该能够获得可以为您解决此问题的现成的分布式数据库产品。即使必须使用自己的部分锁定方案,也可以使用许多已知的方法来处理它,例如DHT。
DeadMG,2016年

7

有一个标准的解决方案。创建多个工作人员进行注册。每个请求都有一个应用于用户名的哈希,并且哈希确定哪个工作进程处理该请求。这样,就不可能同时处理同一用户名的两个请求。

对于这种数量的请求,请考虑使用分布式键值存储(例如风险),而不是将所有数据库都用作数据存储。


2

这是个问题吗 ?

如果使用用户名(而不是用户电子邮件)登录,则不允许两个用户使用非唯一的用户名完成注册。

如果未使用用户名进行身份验证,则可以使用一些后台过程来识别并标记双打(例如基于时间戳),并强制用户在下次登录时更改其用户名

是的,这是一个问题

如您所问,我想用户名应该是唯一的ID。可以使用以下方法:

  1. 之前:在注册过程中,预见新用户必须检查其姓名是否可用的步骤。这样做时,请保留具有临时状态和会话ID的可用帐户名,以便完成注册。
  2. 同时:gnasher729答复的一个更通用,更灵活的变体是使用简单的哈希函数(例如用于管理符号表的哈希函数),将ID分配给唯一的注册服务器i(i = h(用户名)取模) number_of_servers),将在其有限/分段范围内处理唯一性
  3. 之后:注册结束时,如果用户单击register,则可以将请求发送到您的事务数据库,如果您可以将字段定义为唯一的话。出现错误时,向不幸的用户发送“糟糕,出现问题”消息,并要求他选择另一个ID。
  4. 异步:注册用户。之后立即重新读取用户记录,以确保该记录不变并且是单个记录。如果有问题,要么要求用户进行更改(不是那么异步),要么向他发送有问题的邮件(异步,但从用户的角度来看很烦人),或者让他注册但要求他提供电子邮件(以消除歧义),然后强制他在登录过程中更改用户名。

1

重新考虑您认为用户的唯一标识符。每个用户已经有一个唯一的电子邮件地址,因此该问题已经为您解决。当然,这意味着多个用户将能够注册相同的名称,例如“ Mike Nakis”。这有问题吗?你确定吗?例如,对于Facebook来说这不是问题。存在多个名为“ Mike Nakis”的facebook用户。查看facebook登录页面:它要求输入“电子邮件或电话”和“密码”。


0

随着数百万个用户同时注册,您仅使用26 x 26个注册服务器,其中一个用于aa开头的用户,一个用于ab开头的用户,依此类推。结果,只有数千个用户同时在每个服务器上注册。如果仍然无法解决问题,请使用26 x 26 x 26台服务器。


5
...然后您的产品所有者想走向国际...
Telastyn

2
只要Unicode字符串(如NFKD)处于规范化形式,它们的原理也相同。您还可以对用户名进行哈希处理,然后基于哈希进行应用。但是,这个答案基本上只是实现您自己的分布式数据库。
DeadMG

1
您是说他们在一个国家/地区同时有数百万个用户注册?在那种情况下,他们应该有足够的钱为真正的解决方案支付更多的钱。
gnasher729,2016年

更具体地说,这仅仅是完成DHT的开始。
DeadMG '16

如何解决两个用户同时注册相同名称的问题-两个名称都将以相同的两个字符开头,因此由同一注册服务器处理?
HorusKol
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.