限量抢票系统Ticketmaster的设计问题


最近,Ticketmaster因泰勒·斯威夫特巡回演唱会门票销售时发生重大系统故障而成为新闻。该网站在需求的重压下崩溃,导致粉丝不满,声誉受损。

首先,我们将看看Ticketmaster的官方声明,试图从系统设计和架构的角度找出问题所在。然后,我们可以努力了解他们的工程师可能如何防止这种情况再次发生。

事实是,这不是大公司第一次面临这样的公共系统故障(我们也会谈论其中的一些)。只要公司依赖技术,它肯定不会是最后一次。但我们能从这件事中学到什么呢?

为了构建能够处理需求高峰的可扩展系统,工程师必须了解如何使用正确的组件构建系统。这需要仔细考虑基础设施、缓存层、API等-所有这些都可以帮助分配负载并防止崩溃。我们将讨论一些设计高度可伸缩系统的行业最佳实践。

验证粉丝系统中的缺陷
Ticketmaster最初实施了验证粉丝系统,以区分机器人和真实的人类,以打击黄牛党和门票经销商。
有350万验证粉丝注册了预售。其中,150万人收到了邀请密码,200万人在等待名单中。
这通常是一个很好的解决方案,可以缩短等待时间,使售票更加顺畅。
然而:

  • Ticketmaster 已做好准备应对 150 万名受邀购票的认证粉丝,但当超过 1400 万名粉丝出现时,Ticketmaster 却不知所措。
  • 整个网站超过 15% 的互动出现了问题,包括密码验证错误。
  • 一旦系统容量超载,他们的系统就无法拒绝新的请求,因此用户继续发送请求,最终导致超载和服务器崩溃。

最终,这意味着一些用户在购票后仍无法退票。为了控制损失,Ticketmaster 试图让更多用户等待并延迟销售,结果导致排队时间延长。许多通过验证的粉丝在排队等候数小时后,却收到了错误信息。

换句话说,一盎司的预防胜过一磅的治疗。硬性限制申请数量本可以避免大量的混乱和挫折。

一连串的故障
虽然从一开始就清楚 "年代巡演 "会产生巨大的购票需求,但这一需求的巨大程度在意识到时已为时过晚。

Ticketmaster 的第一个失误是对试图购票的客户数量准备不足。容量规划是系统设计的一个重要方面,如果系统没有足够的保障措施来控制请求,事情很快就会失控。

事后分析发现了一些重要的促成因素:

  • 供应少,需求大:与 1400 万试图购买门票的客户和机器人相比,Ticketmaster 售出了 240 万张门票。他们的事后分析表明,大多数受邀参加预售的粉丝平均购买 3 张门票。
  • 机器人(DDoS 攻击):更糟糕的是,Ticketmaster 不得不面对倒卖门票者,他们使用没有预售代码的机器人,试图在验证用户有机会购买门票之前购买门票,这破坏了 "验证粉丝 "系统的预期效果。
  • "重试地狱":当用户反复尝试购买门票时,会产生倍增效应,因为他们无法知道自己的请求是否会通过或成功。
  • 第三方依赖:Ticketmaster 依赖于 PayPal 等第三方支付处理商,因此当他们的系统崩溃时,这些服务无法及时处理支付或返回信息。

在这四个因素的作用下,请求数量激增至惊人的 35 亿次,几乎是之前峰值的四倍。

由此产生的影响类似于 DDoS 攻击。虽然我确信 Ticketmaster 将学会在未来优先采取更强大的容量规划措施,但看到一家本应为这种时刻做好准备的公司在压力下失败,还是有点出乎意料。

从这一特殊案例研究中得到的主要启示应该是,企业在容量规划方面采取积极主动的方法至关重要。有了正确的应急措施,类似的情况就可以避免。

您应该如何构建一个系统,以便在高需求时进行扩展?
现场排队是一个很难解决的问题。如果 Ticketmaster 的目标是让数十万甚至数百万用户现场排队等待门票下架,这将需要大量的处理能力。时间戳的粒度不足以让相当数量的并发用户排队。(有比实时排队更好的为客户服务的方法,但我们稍后再谈)。

这种情况在分布式计算领域并不陌生,甚至你可能听说过它的名字:"雷霆万钧 "问题。像 Facebook 这样的大型分布式系统就曾遇到过比泰勒-斯威夫特的粉丝更极端的 "雷群 "问题。发生在 Ticketmaster 身上的事情并不是一个悬而未决的问题。

从结果来看,我们可以认为 Ticketmaster 没有太多的弹性容量。弹性容量是指用于处理流量增加的备用服务器的可用性。通常,这些额外的服务器用于非关键数据或非时间敏感流程。当网站访问量激增时,可以访问这些备用服务器来帮助管理额外的负载。

不过,仅仅增加更多计算能力似乎有点简单化。因此,让我们来探讨一下在需求高涨时系统扩展的三种方法。

1) 缓存
应对高流量负载最明显的方法就是尽可能多地缓存数据。缓存可以在服务器或客户端层面进行,尤其适用于对经常请求的资源的响应。如果能加快交付速度,就能为更多用户提供服务,同时还能降低计算能力。

2) 优雅降级
这是一个经典的容量规划考虑因素,我将简要地谈一谈。优雅降级本质上是一种逐步拒绝请求的方式。随着负载的增加,工作流程会是这样的:

  • 所有系统正常运行,不拒绝任何请求。
  • 负载严重时,采用随机排队模式处理请求。
  • 负载严重,随机拒绝请求。
  • 系统生命支持,拒绝所有请求。

3) 建立等候室,设置购买时间限制
Ticketmaster 已经有了一个被称为 "Smart Queue "的等候室,并且设置了购票结账的时间限制。这些都是众所周知的解决僵尸攻击或用户持有门票却无意购买的最佳实践。

Ticketmaster 并没有明确规定当排队最终取消时,有多少用户可以尝试购票。Ticketmaster 系统会尝试 "保留 "放入购物车的门票,然后给出完成交易的时间限制。

问题就出在购物车中的门票实际上并不可用。在这种情况下,结账时会出现错误,用户会返回互动座位图 (ISM) 将另一张票放入购物车。这可能会造成前所未有的用户挤向系统列出的待售门票。

第三方依赖性是否会毁了Ticketmaster?
简而言之,Ticketmaster 防止这种情况发生的最佳方法取决于 Ticketmaster 的内部设计。一个系统的强弱取决于其最薄弱的环节。我相信他们的工程师正在努力解决和标记瓶颈问题。

由于大多数故障都发生在用户购票之后,因此可能是 VISA 和万事达卡等公司的支付处理依赖性导致了整个系统的连环故障。在 Ticketmasters 发布更全面的事后分析之前,我们真的不知道如何才能最好地解决他们的问题。

限量投放系统的未来一瞥
不同企业发布限量产品的方式可能大相径庭。在过去几年里,我们看到商品销售方式的变化比以往任何时候都要多。随着电子商务网站上机器人的不断出现,企业必须不断调整自己的模式,以满足合法客户的需求。

很显然,有限的降幅对消费者和软件系统都是一种压力。我们从耐克(甚至其他票务零售商)等公司那里看到的一种比较流行的方法是抽签法。一些用户被随机选中,有机会购买限量商品。如果你没有被选中,你将不得不求助于售后市场,但你可以感到欣慰的是,每个人都有平等的机会。

另一种方法是分批发布商品。分批发布商品通常比一次性发布商品要好得多,尤其是对软件系统而言。Ticketmaster 就曾尝试过多次限量预售,但如果他们也能在全面发售时实施这一策略,效果会更好。例如,可以按 IP 地区错开发布。是的,用户有可能通过 VPN 来欺骗系统,但这仍然有助于分散负载。

在分发高需求艺术家或巡演的门票时,抽签和分批这两种方法都能给用户带来更好的体验。无论是哪种策略,都可以在 Ticketmaster 的前端实施,并在降低服务器成本和系统压力方面带来巨大回报。

此外,这两种模式都不会妨碍 Ticketmaster 提供一站式购票和售票服务的能力。由于门票数量已经有限,如果用户错过了抽签或分批购票,Ticketmaster 仍可提供转售价格的门票作为替代。