设计电商网站(第二部分)

原文:Design eCommerce Website (Part II)

译者:飞龙

协议:CC BY-NC-SA 4.0

自豪地采用谷歌翻译

这是设计电子商务网站系列文章的第二篇文章。 如果你还没有阅读第一篇文章,最好先查看一下,因为我们将在这里继续讨论。

为了简要地提醒你我们在前一篇文章中讨论过的内容,我们从电子商务网站的数据模型设计开始。 尽管关系数据库是最常见的方法,但是我们注意到像 MongoDB 这样的 NoSQL 数据库,在构建电子商务网站时提供了很多优势和灵活性。 为了扩展系统,并发性是要考虑的关键因素之一。

在这篇文章中,我主要关注电子商务网站的可扩展性。 构建单机系统可能很简单,但是当我们决定使用多个服务器扩展网站,来支持数百万甚至数十亿个请求时,需要考虑大量的可扩展性问题。

并发(续)

一种常见的情况是商店里只剩下一本书,两个人同时购买。没有任何并发​​机制,它们都成功地购买了这本书是完全可能的。

在我们以前的文章中,我们知道有一种方法是,每当有人访问资源(书)时,就对该行进行锁定,以便一次最多只能有一个人读/写数据。该解决方案称为悲观并发控制。尽管这种方法可以防止两个人同时访问相同的数据,但是上锁却开销较大。你将如何更有效地解决这个问题?

乐观并发控制是并发的另一种方式。这个想法非常简单 - 不使用锁,每个进程/线程都可以自由地访问数据。但是,在提交更改之前,每个事务都应检查数据是否与上次读取时的状态相同。换句话说,你在事务开始时检查数据,并在提交之前再次检查它们是否仍然相同。

如果数据没有修改,你可以安全地提交它。否则,请回滚并重试,直到没有冲突。比较两种方法是很重要的。对于 OCC(乐观并发控制),除非存在冲突,否则读/写数据显然更为高效。考虑到这一点,对于不太可能发生冲突的系统来说,OCC 是一个更好的选择。但是,当多个客户端频繁访问资源时,在 OCC 中重新启动事务变得开销很大,并且在每个事务中上锁(PCC)必然会更好。

在像亚马逊这样的应用中,有这么多的产品,多个人并不经常同时访问同一个产品。因此,OCC 是一个更好的选择。

电子商务中的可用性

如果亚马逊网站宕机一分钟,这是一个巨大的损失。要在分布式系统中实现高可用性,最好的方法是拥有数百或数千个冗余,以便可以容忍许多故障。但是,这里值得注意的是,可用性和一致性是齐头并进的。

如果你有很多冗余,确保每个冗余都有相同的数据是非常困难的。另一方面,如果你想达到高一致性,你最好有更少的冗余,因此系统很容易失败。

这里的想法并不是要同时实现。相反,根据产品的性质,你应该能够做出权衡。对于电子商务网站而言,延迟和停机时间通常意味着收入的减少,有时这可能是个很大的数字。因此,我们可能更关心可用性而不是一致性。后者可以通过其他途径改进。

电子商务的一致性

鉴于我们有成百上千的冗余,你如何保证每个冗余持有相同的数据?为了详细解释这个问题,假设数据 D 被复制到多个服务器中。当进程尝试将 D 更新为 D1 时,它将从一台服务器开始,并按照特定顺序传播更改。与此同时,另一个进程正试图将 D 更新为 D2 ,并可能从另一台服务器开始。结果,一些服务器拥有数据 D1 另一些拥有 D2。

强一致性

一种方法是强制所有更新以原子方式,以相同的顺序执行。更具体地说,当有人更新资源时,它将锁定所有服务器,直到所有服务器都持有相同的值(更新后)。因此,如果一个应用建立在强一致性的系统上,则与在单台机器上运行完全一样。显然,这是开销最大的方法,因为不仅锁定是开销较大的,而且它也阻止了系统的每次更新。

弱一致性

另一个极端的情况是我们可以提供最低限度的策略。每个冗余都会看到每个更新,但是,它们可能会有不同的顺序。因此,这种方法使得更新操作非常轻量化,但缺点是保证了最低限度的一致性。

注意:我们没有解释一致性模型的准确定义。相反,我们想用实例来说明思想,这对于准备系统设计面试更有帮助。

最终的一致性

你可以想像,更实用的方法在两者之间。简而言之,系统只保证每个冗余最终具有相同的值。在一定的时间内,数据可能不一致。但从长远来看,系统能够解决冲突。

让我们以亚马逊的 Dynamo 为例。基本上,每个冗余可能在特定的时间保存不同版本的数据。所以当客户端读取数据时,可能会得到多个版本。此时,客户端(而不是数据库)负责解决所有冲突并将其更新回服务器(译者注:读时一致,类似于 RAID1)。

你可能想知道客户端如何解决这些冲突。这主要是一个产品决策。以购物车为例,不丢失任何添加是非常重要的,因为丢失添加意味着收入的减少。所以当面对不同的值时,客户端可以选择物品最多的那个。

总结

你可以看到的,这里的很多技术在分布式系统中很常见。 重要的是理解彼此之间的权衡,并选择最适合产品的方法。

顺便提一下,如果你想得到资深的面试官的更多指导,可以查看 Gainlo,以便与 Google,Facebook 等公司的工程师进行模拟面试。