像亚马逊这样的公司如何避免访问数据库层的瓶颈?


29

如果您想象一家像亚马逊(或任何其他大型电子商务网站应用程序)的公司正在大规模运营一家在线商店,而其仓库中的实物数量有限,那么他们如何优化这一点,以至于没有一个瓶颈?当然,它们必须具有多个具有复制功能的数据库,以及许多独立处理负载的服务器。但是,如果多个用户由不同的服务器提供服务,并且两个用户都试图将相同的商品添加到他们的购物车中,而该商品仅剩一个,则该商品的剩余数量必须有一些“真相来源”。这是否意味着至少,所有访问单个商品的产品信息的用户都必须串行查询同一数据库?

我想了解如何使用分布式计算来经营这么大的商店,而又不会在包含库存信息的单个数据库上造成巨大的瓶颈。


2000年中期的Amazon体系结构(仍然与您的问题有关):highscalability.com/amazon-architecture
Joeri Sebrechts

飞机上的座位也会发生这种情况(例如,在打包假期中,购物车中的一项代表那里的航班,出租车,酒店住宿和返程航班),许多不同的代理商在各自的站点上出售相同的座位。解决方案千差万别,但是它们全都归结为一个最终的真实数据库,其中包含每个零件的实际状态。
RemcoGerlich

1
@RemcoGerlich:您说“一个最终的事实数据库”的方式使我想到了一台拥有巨大神圣数据库的机器。实际上,关键数据发生的是,所有事务一次到达多个服务器,从而确保所有这些数据库始终保持同步。
Arseni Mourzenko 2013年

Answers:


27

但是,如果多个用户由不同的服务器提供服务,并且他们都试图将同一项目添加到他们的购物车中,而剩下的仅剩一个,那么该项目剩余的数量必须有一些“真相来源”。

并不是的。这不是需要100%完美的技术解决方案的问题,因为这两种错误情况的业务解决方案都不是很昂贵:

  • 如果您错误地告诉用户某物品已售罄,您将失去一笔交易。如果您每天销售数百万种商品,并且一天可能发生一次或两次,那么它就会在噪音中迷失方向。
  • 如果您接受订单并在处理过程中发现您的商品已用完,则只需告知客户,然后让他们选择等待,直到可以补充库存或取消订单为止。您有一个有点生气的客户。当99.99%的订单运行正常时,这也不是一个大问题。

实际上,我最近亲自经历了第二种情况,所以这不是假设的:那是发生的事情以及亚马逊如何处理它。

当您遇到理论上很难解决的问题时(无论是性能,优化还是其他方面),此概念通常适用:您通常可以使用在大多数情况下都非常有效的解决方案,并有时会接受失败,只要您可以检测到发生的故障并进行处理即可。


2
在“ 基于流沙”补偿交易中也介绍了Pat Helland的“ 记忆,猜测和道歉”,这是相关的想法。
德里克·埃尔金斯

1
您说“不是真的”,但我觉得您同意我的建议。听起来您的意思是,当用户只是浏览时,我们给出了剩余库存的缓存近似值,但是只有当他们实际尝试完成购买时,我们才进行写操作以减少剩余库存。包含该值的数据库将自动执行每个事务,并且如果两个用户同时尝试,我们将显示第二个错误消息,因为这不太可能发生。因此,最终一台机器上只有一个整数,其中包含“真相”。
mattgmg1990

2
@ mattgmg1990:正确,最终您当然必须在某个地方知道“真相”,但是重要的区别是订单的处理可以在队列中完成,因此您根本不需要并发的原子写访问。就我而言,“错误消息”实际上是在我在亚马逊网站上完成订单数小时后发出的-我收到一封电子邮件,说他们在该商品的供应方面存在问题,我可以选择取消订单或不采取任何行动,然后等待让他们实现它。我之所以选择后者,是因为我不需要立即使用它,而实际上他们是在几周后交付的。
Michael Borgwardt

@DerekElkins是一篇很棒的文章,尤其是关于数字数据不可避免地不完美的代表现实的观点,因为现实总是会发生变化,您的系统无法自动知道。
Michael Borgwardt

6

结合

  • 杂凑
  • 分片
  • 复制
  • 分配
  • 高故障转移
  • 键值存储

没有魔术,只有越来越复杂的情况。就像DNS一样,它是按比例缩放的。

“真相的单一版本”是此类系统的一部分。生成新密钥变得比仅生成序列中的下一个数字更为复杂。例如,存在其他序列。这是分布式数据库系统可以处理的那种复杂性,它们通过在创建新对象时对组件进行多次操作,使其对其他对象可用,确保序列在需要时是唯一的,复合键等来实现。 。


我已经阅读了所有这些概念,但是我一直坚持的部分是剩余库存的特定情况。如果仅剩5本书,并且用户在多台服务器上进行请求,那么在查询剩余库存以确保没有两个用户可以同时获得最后一本书时,他们是否总是解析为一个数据库表?上面的特定用途是什么,这样才不会减慢整个系统的速度,并且复制对于多个数据库实例仍然有用?
mattgmg1990 '16

增加了一些。抱歉,我无法真正解释此格式涉及的所有复杂性。
Michael Durrant

1
只有某些人对任何给定的书感兴趣,这意味着,书可以由负荷相对较小的碎片处理。
Basilevs

6
我认为在您描述系统的情况下,您只需要向用户道歉,即有人购买了最后一个副本。我想这确实会不时发生。
马修·詹姆斯·布里格斯

1
我敢打赌,只剩下5本书了,指标是更少的计算和更多的营销。
mouviciel 2016年

5

我已经看到“最后库存项目”问题通过以下方式解决:

每天更新所有库存水平,并根据阈值水平将产品标记为高,低,已订购或缺货类别。

显然,这是有问题的“低库存”项目

  • 库存水平高的物品

不要打扰检查库存水平。只需下订单

  • 库存水平低的物品

在浏览“最后几条!”时警告用户。当他们付款时,检查并减少库存水平。如果库存不足,请更新项目状态。

这样,您只需要在数据库中找到“低库存”项目,并且只有在客户的购买过程远远落后时才这样做。代价是某些客户将无法完成购买。

但是,在大多数情况下,“缺货”实际上只是意味着您正在等待其他交货,因此无论如何您都想接受订单,并且可能只是弹出警告或限制交货选项。因此,这些客户没有失去。

在销售等高负荷时间,您甚至可以关闭库存检查,稍后再向客户发送电子邮件,“对不起,我们用完了X,您是否要Y”

本质上,任何电子商务平台的目标都永远不会从数据库中读取。始终提供缓存的页面并在客户端进行所有操作。


2

在此视频中,Martin Fowler讨论了NoSQL数据库:

https://www.youtube.com/watch?v=qI_g07C_Q5I

要点之一(在某个地方)是,像亚马逊这样的地方宁愿通过接受他们的订单来让99%的人满意,而又无法“确定”是否确实可用,并且可能因为说“对不起,看起来有人击败了您”。

这就是说,您所描述的情况没有真正的处理方法,只是Amazon根据最近一次成功读取的库存以及是否存在并发事务(oopsie)来利用怀疑的好处。

(顺便说一句,如果您对NoSQL感到好奇,那将是一个很棒的视频)

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.