我在接受采访时被问到这个问题。问题陈述是这个
您有一个处理数百万用户负载的网站。您在各种负载平衡Web服务器上都有一个共享数据库,该服务器已在表中获得优惠券的详细信息。每个登录的人都会从表中获得一个随机的优惠券ID。
问题是你将如何设计你的系统以满足这么多用户的需求?
在我看来,每次用户登录时,我们都必须运行一个选择查询来获取优惠券ID并使用删除查询将其从表中删除,以确保不会将其分配给其他用户。
但是我不知道它将如何扩展到数百万用户?在我的设计中,直到第一个用户的删除尚未完成,我无法招待任何其他用户。这就是为什么很多slave和master数据库服务器都无济于事的原因。因为必须将master中的删除同步到从属服务器以便不进行复制。
我可以通过什么方式解决这个问题以扩展我的后端?此外,如果应该在这里使用缓存,我的方法应该是什么?
答案 0 :(得分:2)
问题陈述没有说哪个优惠券分发给每个用户。我假设任何都可以。
您当前的设计无法扩展,因为它有一个争用点:使用第一张优惠券。
相反,只需从表中获取任何优惠券即可。将随机数列添加到存储优惠券的表中。它的值范围应为[0,1000000)。
如果必须使用优惠券,请选择随机数最小的优惠券,该优惠券高于您刚刚绘制的数字:
SELECT TOP 1 *
FROM Coupons
WHERE RandomNumber >= RAND(0, 1000000)
ORDER BY RandomNumber
这会消除所有争用,因为写入发生在表中的随机点。这里的查询形式为写:
DELETE x FROM
(
SELECT TOP 1 *
FROM Coupons
WHERE RandomNumber >= RAND(0, 1000000)
ORDER BY RandomNumber
) x
这具有确保原子性的正确锁定语义。