我们目前有一个使用单一数据库的商店/购物车系统。我们有一个包含库存数量(比如100个小部件)的字段的产品。我们有一张顾客桌。当有人将一个小部件添加到他们的购物车中时,我们在客户和表示购买意向的产品之间的联接表中插入一个记录。该customer_product记录的状态指示它在购物车中或已完成购买(“未决”,“购买”)。
当客户请求到达系统以将产品添加到他们的购物车中时,我们计算该产品的购买和挂起customer_product记录的数量,如果该数量等于总数(100),则不允许该记录。这样,我们确保我们不允许101人拥有100件物品。
数据库是我们的系统瓶颈,连接表受到了很大的打击。我怀疑行锁和页锁会影响负载下的性能。我猜想像Amazon/eBay这样的系统必须有一个分布式的db体系结构,但却不知怎么地解决了两个人同时想把最后一件东西放到购物车里的问题。我想重新架构我们的商店/购物车,以减轻db约束。
对于单个数据库,我们可以在联接记录insert WHERE子句中执行一些操作,以包括一个子查询计数,以便如果两个db事务同时尝试执行“最后一个小部件”插入,那么无论哪个尝试提交第二个,都会失败,因为计数将在第二个到最后一个事务获取最后一个小部件并更改计数之后阻止它。但在分布式数据库中,我猜这个技巧是行不通的。
在解决分布式系统中的此类并发和共享资源挑战时,应用了什么样的一般系统架构指导原则或模式?
注意:我知道类似的问题(比如在电子商务网站中管理并发到一个篮子中的最佳实践)。这个问题是关于如何在分布式体系结构中处理这个问题,其中每个db实例都有一个表的副本,并且每隔一段时间都会与其他的表和更改相对应(至少我是这么想的--我以前还没有真正建立过分布式db系统)。
发布于 2017-01-13 18:51:32
这取决于小部件。
如果小部件很少见且昂贵(确切地说是10法拉利),那么您所遵循的方法是正确的。当然,你也需要考虑库存正在退回,但还没有被重新储存,库存是为修理,等等。
如果小部件更常见(5,000把扳手),那么通常的方法是:
发布于 2017-01-13 22:21:25
通过使用简单的id而不是外键,并通过应用程序来弥补非空要求,您可以为用户使用单独的数据库。
与单个数据库相比,这将减少一些争用。
库存数据库可以存储每个项目的总可用库存计数,还可以在该库存数据库(如您建议的那样)中存储/缓存所有用户/购物车数据库中的计算值,即购物车声称的总计数,该数据库将需要在购物车索赔/释放项目时进行更新。
这将减少用户/购物车数据库的一些负载,而牺牲了应用程序对缓存值的管理(为性能而缓存/取消规范化)。
用户/购物车数据库和库存数据库都可以跨多个数据库进行切碎。
切分将相同的表存储在多个数据库中,但不是相同的数据,因为在每个数据库中专门选择了不同的行,以便将各种访问和修改负载分散到这些数据库中。分片对于不需要同时/在同一个查询中访问的用户和库存(我们通常不需要同时查询所有用户(例如,所有用户的计数)或所有库存项目,例如所有库存的总数)都很有效。
如果分块策略很简单(例如,对于库存,库存id将碎片的数量模块化),则相对容易识别哪个库存碎片有该库存项。
以上两者的结合将大大减少对数据库服务的争用。
与上面的部分正交,您还可以在库存副本之间分配库存计数,如果您有5000小部件和2个副本,则每个副本的数量为2500。
在达到最低阈值之前不需要协调(例如,一个副本销售2400台,现在降到100台)。
到那时,系统可能要求从另一个副本中重新平衡库存,因此,如果另一个副本仍有2000份剩余,那么其中的一半可以由另一个副本拿走。
库存方法的复制/分发可以与分片方法相结合,因为复制可以被切分。
https://softwareengineering.stackexchange.com/questions/340145
复制相似问题