检查用户名是否可用于庞大的数据集的最快方法是什么?

时间:2019-05-01 19:01:42

标签: php mysql redis

我正在寻找最快/最有效的方法来搜索数千万个用户名中是否有给定的用户名。目前,我正在使用运行每个按键的普通MySQL SELECT查询,但是我对性能不满意。我正在使用索引,分区等,我知道MySQL可以优化得非常快,但是我也知道有更好的解决方案。

那么最快的用户名搜索是什么

  • Redis EXISTS命令
  • Elasticsearch
  • 其他地方

例如:Gmail在注册时如何在数十亿个电子邮件地址中进行搜索。 Facebook是如何做到的?我以为他们不只是运行SQL查询。

我正在寻找适用于PHP应用程序的实用解决方案。

现在我只是使用一个非常基本的选择:

SELECT username FROM users WHERE username = $username LIMIT 1

用户名列具有唯一索引

3 个答案:

答案 0 :(得分:3)

我同意您应该将其全部粘贴到RAM中(例如Redis)。

但是,如果您不想一路走下去,请执行以下操作:将列表存储在较慢的位置(例如S3或SQL数据库)。接下来,从该列表中创建一个Bloom过滤器(在Wikipedia上有东西,并且有一个漂亮的Redis模块,您可以使用-https://oss.redislabs.com/redisbloom)。

现在,BF告诉您永远不会给您带来误报,因此您可以有效地检查用户名是否可用。但是,有时BF会报告用户名不可用(误报),您已决定是否可以使用该用户名。

答案 1 :(得分:0)

将列表加载到关联数组中。测试密钥的存在。做完了如今,“数百万”的数据并不多。它适合RAM。

如果您的内存不足并且不介意天文学上出现误报的可能性很小,则可以使用SHA2-256哈希值代替完整值。这些只是40字节的十六进制编码,原始格式为20字节。在许多情况下,甚至甚至 O(1)时间,检查哈希键是否已编入索引都是很简单的。

请记住,只有当您处理的峰值负载超过每秒1000个查询时,这才有意义。不要过早地对此进行优化。大多数数据库基本上可以在零时间内进行用户名测试,这甚至不难,而且每秒进行一千次测试不会破坏您的服务器。

如果您确实有一个可衡量的性能问题,那么您随时可以探索索引选项。 MySQL supports different index typesBTREEHASH。它们的表现不同。

答案 2 :(得分:0)

您的示例中提到了使用高端系统的公司。显然,没有任何系统可以做到这一点,这就是原因:

让我们假设一个巨大的公司如何处理数十亿用户名:

有一种服务,可能是用C编写的,甚至不是用C ++编写的。

它部署在Unix或Linux集群上

还有一个服务充当第一个服务的健康检查程序,该服务检查每个其次是标准的用户名和密码

该服务将所有数据(通常是用户名和密码)加载到内存中

当数据在源处发生更改时,它被称为采用更改,这是从数据源触发的

当需要对数据进行调用(我们的情况)时,对主服务处于活动状态的运行状况检查程序的两个副本进行2(最少)异步调用(以避免服务中断延迟)

当任何健康检查程序均回复“ ok”时,将调用(检查程序的)主服务,并验证是否请求了用户名和/或密码。

呼叫者然后根据答复继续。

最后,无论哪种解决方案都尽可能快地起作用。像上面提到的redis这样的内存'db'有点接近-考虑到差异,这意味着足够接近。如果一家大型公司的业绩为10分,而一个简单的网站按照相似的做法(遵循相同的原则)的业绩为8-9分,且成本根据每个公司的规模进行了调整,那么我认为这是一个成功的选择。