Facebook是如何防止消息系统在新年前夕发生崩溃?


这是一篇来自IEEE Spectrum的文章,Facebook的Messenger的13亿用户会在新年前夜集中发送的消息,比如新年快乐等祝愿,这种发送量比一年中任何其他日子都多得多。
如果一切顺利,这些消息将在不到100毫秒的时间内到达收件人,但是,如果消息系统服务停止或失败,位于公司纽约办事处的一个小型软件工程师团队将不得不对其负责。
工程经理Isaac Ahdout和软件工程师Thomas Georgiou都在该团队中。他们全年都对应用程序进行了测试和调整,很快就会面临最大的年度性能考试。Messenger的13亿月活跃用户会在新年前夜发送的消息,许多人在各自时区的午夜时间段会使用Messenger中点击按钮“发送”问候。
对于在一天或一年中的特定时间看到使用量急剧增加的网络或服务的任何人来说,这是一个熟悉的问题。由于类似的原因,美国电信公司经常在Super Bowls,州博览会和总统就职典礼之前安装新的基站。
对于Facebook的Messenger团队来说,这种挑战比将一个简单的消息从一个用户直接发送另一个用户要稍微复杂一些。Facebook允许人们设置大型群组聊天,并在每次发送,发送或阅读消息时向发件人显示结果,意味着必须在跨服务分发的消息总数。
与平均日相比,用户在新的一年中发送和接收的照片和视频的比例也更高。人们经常会尝试重新发送似乎没有立即通过的消息,这些消息会堆积更多的请求。

最大的担心问题是:你如何防止这种级联故障发生?

一种方法是提前进行广泛的负载测试,模拟Facebook在新年前夜根据前几年的活动预期的消息量。(该公司拒绝分享其预测细节,并且不会说前几年发送了多少消息。)。
例如,在上一个新年前夕,一个数据中心因收到的消息量而堵塞,因此团队将流量从该中心转移到另一个中心。在此事件发生后,该小组建立了工具,使他们能够在今年更轻松地进行这些变更。

除了转移负载之外,Messenger团队还开发了其他杠杆,如果事情变得非常糟糕,它可以采取Pull拉的方式,发送到服务器的每条新消息都作为名为Iris的服务的一部分进入队列  。在那里,消息被分配超时设置,之后该消息将从队列中退出以为新消息腾出空间。在高容量事件期间,这能让团队快速丢弃某些类型的消息,例如读取收据,以将其资源集中于提供用户已经点击后组合的消息。

Iris服务宁愿发送信息并放弃阅读回执,而不是丢弃信息并发送阅读回执,这里面有流量的优先级设置。

还可以牺牲Messenger应用中表示朋友目前在线的功能,减慢在线情况的更新点频率可以缓解网络拥塞,或者,团队可以指示系统暂时延迟某些功能 - 例如删除有关旧消息的信息 - 几个小时以释放通常执行该任务的CPU,以便在此刻处理更多消息。
 
所有这些选择都属于“优雅回退”的概念。不是让你的服务死亡,以至于没有人使用它,会让它变得不那么棒,但人们仍然可以使用它。

除了这些努力之外,Messenger工程师还花费大量时间在旨在充分利用每台服务器内CPU和内存的效率项目上。例如,在2018年新年前夕,该团队添加了一个调度程序,该程序允许系统将类似的消息“批处理”在一起。服务器同时收到很多请求,在向下游发送请求之前,您可以将其中的一些捆绑在一起。这样做可以减少下游系统的计算负担。

基于亲和力聚合的原理形成批次一次性发送消息,这可以源自各种特征,如果两个消息正在前往同一个接收者,或者需要来自后端的类似资源,则它们可能具有更高的亲和力。随着流量的增加,Messenger团队可以更积极地拥有系统批处理。这样做会将延迟(消息的往返延迟)增加几毫秒,但更有可能使所有消息都通过。