0%

星巴克教会我们软件的可扩展性

尽管许多人可能想要构建可伸缩性的软件,但它可能比最初想定的要困难。当我们处理单独的任务时,我们可能会陷入一个陷阱,认为所有的事情都同等重要,需要同样的资源,并且按照预定的顺序同步发生。

事实证明并非如此,至少在可扩展系统中不是这样,在星巴克也不是这样。

如何煮咖啡

在星巴克准备咖啡一共四步。首先,客户按照先到先得的规则在柜台排队并下订单。其次,员工(咖啡师)从客户那里接单并接受付款。第三,他们开始准备饮料。第四,准备就绪后,他们将饮料放在柜台上,并喊出顾客的名字。

尽管这听起来像是一个合理的模型,但它可能很快导致排长队。一个人不可能一次完成一件事情,因此,当咖啡师按顺序处理每个订单时,客户开始排队。如果他们想为更多的客户提供服务,则需要扩大规模。让我们看看他们如何做的。

扩展咖啡师

星巴克可以扩大规模的一种方法是聘请超级咖啡师—非常有才华,高效工作且聪明的人。他们需要在开发上投入大量资金,优化工作的各个方面,并不断提高效率。在软件中,这种方法称为Scaling Up(垂直伸缩)。

垂直伸缩策略的问题在于一个人可以工作多快(以及工作多长)是有限制的。在某些时候,即使是超级咖啡师也无法满足需求。发生这种情况时,顾客会沮丧地离开商店并且可能不会回来。

同样,如果所有事情都按顺序运行,那么我们优化软件的程度也是有限的。我们买不到200GHz的CPU。即使是最牛的CPU也是多核的,每个核的时钟频率不超过3-4GHz。

星巴克可以扩展的另一种方式是以允许增加更多普通工作人员的方式组织工作,这是软件中并行处理的本质。一位咖啡师接受订单后,另一位咖啡师可以开始准备。然后,第一位咖啡师可以同时接受另一笔订单。

您可能认为最好的办法是仅在系统达到一定访问量后再考虑并发处理。但并不是那么简单。没有任何神奇的开关可以让我们在需要时打开并发。我们需要提前准备。

星巴克知道这一点。当一家新商店开业时,即使每个班次只有一名员工,并发所需的一切也从第一天就准备就绪。他们准备随时添加更多人员。

经验教训:如果我们不能以一种支持并发处理的方式构建系统,那我们就不能轻松地使用并发处理。

现在让我们来看看星巴克是如何做到这一点的。

从消息开始

如果你曾经在星巴克买过咖啡,可能会注意到杯子上的小格子上满是符号。这些符号是咖啡师用来快速识别饮料以及任何其他饮料(例如鲜奶油,泡沫等)的一种简写形式。

杯子或消息对于员工之间的沟通至关重要。它向咖啡师发出信号,表明需要制作饮料,并且上面写的符号提供了有关准备哪种饮料的详细信息。即使咖啡店不忙,只有一个人为客户服务,他们仍然会在杯子上添加符号。

乍一看,这似乎是多余的工作。但是,如果一大群客户突然进入商店,则后面的其他员工可以立即进入流程帮助。无需任何其他沟通,他们就可以根据消息开始制作饮料。

经验教训:如果我们可以随时轻松地增加更多的员工并分配工作,那么突然的高峰就不会出现问题。使用消息可以做到这一点。

分而治之

如前所述,整个咖啡制作过程可以由一名员工(咖啡师)负责。但是,星巴克的默认设置是让一名员工(收银员)接受订单和付款,另一名员工(咖啡师)进行饮料。

通常,过程中最慢的部分是准备咖啡,这就是为什么许多咖啡师在商店忙时准备饮料的原因。通常,他们会从同一堆杯子中拿杯子,然后平均分配工作。这就是典型的竞争消费者模式。

但是,在某些情况下,这种方法会遇到麻烦。假设有3位咖啡师使用一台咖啡机和一台星冰乐咖啡机工作。三名顾客点了一杯咖啡,下一位顾客点了一杯星冰乐。接订单的员工会收到四个杯子上(队列),每个杯子上都有相应的符号。每个咖啡师拿一个杯子来煮咖啡。第一个开始做他们的饮料,其他两个现在被阻塞等待咖啡机。

我们可以通过分工来避免对资源的争夺。一种方法是将消息分成更细粒度的类型,以便可以不同方式处理它们。例如,我们已经了解了星巴克如何使用杯子作为消息来表明需要准备什么饮料。该系统还可以区分冷饮和热饮:纸杯提供热饮,塑料杯提供冷饮。当我们收到三份热咖啡订单,然后收到一份星冰乐咖啡订单时,我们现在有了三个纸杯和一个塑料杯,分别分成两堆。第一个咖啡师从第一堆咖啡纸杯中拿起纸杯,然后开始准备饮料。第二位咖啡师看到咖啡机很忙,从第二堆咖啡杯中拿起塑料杯,使用星冰乐咖啡机。

咖啡师将任务划分为并行工作的这种工作划分称为分区

经验教训:事实证明,分区是有效扩展策略的关键要素。并不是所有的工作都需要相同的扩展级别。快速完成的小任务可以由一个员工完成,而多个员工负责要求更高、速度更慢的任务。通过使用分区,我们可以独立地扩展每个活动。

并非所有工作都同样重要

星巴克成功的原因之一是他们训练员工认识到常客的重要性。就拿那个每天早上来拿两杯超大杯美式咖啡和两杯大杯拿铁的哥们来说吧。还有一个女人,她每周三点一杯焦糖玛奇朵,然后在店里待上一个小时看书。

如果咖啡师注意到周三走进店里的“焦糖玛奇朵女士”,他们甚至会在她来到柜台前就开始准备她喜欢的饮料。当顾客从来不说她想要什么时,她会得到一个惊喜。收银员已经知道她通常喝什么了,所以他们只需要跟她打个招呼,就可以付款。在付款完成之前,她的咖啡已经在柜台等着她了。

你可能会惊讶星巴克的常客比例有多高。给他们最好的体验是重中之重。通常,他们会比其他顾客更快地拿到饮料。这让他们觉得自己很重要,自然而然的再次购买,从而增加了他们对公司的价值。

经验教训:有些任务比其他的更重要。通过将标准活动组织为可重用的、独立的组件,我们可以轻松地修改流程,以便在需要时为更有价值的任务提供更优质的服务。

并非所有的错误都需要预防

在上述所有示例中,星巴克员工都需要验证客户在收到咖啡之前已经付款。为了避免用户没有付款,以要求顾客出示收据,然后再交付饮料。但实际并不是这样。

星巴克发现,很少有人不付钱喝咖啡。他们的分析表明,让咖啡师专注于完成订单而不是防止偶尔丢失咖啡,这会更有收益。如果有人碰巧拿了你买的咖啡,咖啡师会为你准备一杯新的咖啡,而不会提出任何问题。

经验教训:为了构建可伸缩的系统,我们需要接受这样一个观点:有些失败是不可避免的。要想完全预防,代价太大了。相反,我们应该集中精力确保我们能够迅速发现问题,并在出现问题时予以弥补。

总结

看似简单的四步煮咖啡的过程演变成了一个有趣的业务过程。乍一看,这似乎是异常罕见的,但事实证明,它是这家企业的一个重要因素。

像突然的需求高峰或失败可能每天发生多次。设计一个能够很好地处理这些问题的系统需要质疑常见的假设。通常第一个想到的方案或模型不会解决这些问题。此外,还有许多更特殊的情况需要考虑。例如,取消订单本身就是一个有趣的问题。

就像星巴克的例子,如果我们遵循一个幼稚的方法,我们的业务将无法扩展到服务更多的顾客。随着我们的顾客越来越多,我们的服务水平会下降,直到他们不再来。相反,我们需要以一种能够满足日益增长需求的方式来优化我们的工作。最后,构建可伸缩的系统与重新思考我们的业务流程同样重要。

坚持原创技术分享,您的支持将鼓励我继续创作!