在发生全球性事件时,比如奥运会或跨年夜,人们会在 Facebook 上庆祝或分享他们的精彩时刻。这些事件给 Facebook 的系统带来了巨大压力(流量高峰),特别是那些要求高带宽的内容,比如视频直播。Facebook 的生产工程团队所构建的基础设施确保了 Facebook 的系统在发生这些流量高峰期间仍然能够提供稳定可靠的服务。
这篇文章就会详细介绍 Facebook 在面对流量峰值时的一些处理策略。
作者 | Peter Knowles
翻译 | 薛命灯
来源 | 聊聊架构
Facebook 的基础设施可以应对不同类型的流量模式,大致可以分为三种:
日常( routine ):大部分在线系统都有常规且可预测的流量模式,比如来自世界各地的 Facebook 用户日常的使用流量,再比如周末的流量总是与工作日的流量不太一样。我们在构建服务之初就已经把这类流量考虑在内了;
非预期( spontaneous ):计划之外的全球性事件会带来非预期的流量模式,比如气候突变或自然灾害,或者病毒性的媒体传播现象(比如 2014 年的 ALS 冰桶挑战赛)。要应对这类突发性的流量通常十分棘手,它要求我们的整体服务具备很强的弹性;
计划内( planned ):计划内的事件包括跨年夜、即将召开的冬奥会和 2018 年足球世界杯。通常这类事件会带来短暂的流量高峰,不在日常的容量规划范围之内。因为它们是可预测的,所以需要进行特别的规划。
为了说明我们是如何应对这类计划内的事件,这篇文章将以跨年夜的视频直播为例。
跨年夜应对计划
12 月 31 号对于 Facebook 的系统( 包括 Facebook Live )来说是一个非常重要的日子。我们的目标是确保人们能够持续不断地在 Facebook Live 上分享他们的视频,这中间不能出现中断或系统响应变慢的情况。
因为流量规模较大,所以我们从 10 月份就开始为跨年夜做准备。生产工程团队需要负责端到端的可靠性,同时也要协调好其他基础设施和产品团队。
架构一览
为了更好地了解流量对 Facebook Live 造成的影响,我们先来了解一下它的整体架构,以及数据是如何流经这个系统的:
用户设备成实时的 H.264 / AAC 媒体流;
媒体流通过 RTMPS TCP 发送到 PoP( Point of Presence )服务器上;
媒体流从 PoP 路由到数据中心的服务器上( FBLS );
媒体流被编码成多种分辨率和比特率的 MPEG-DASH 视频片段;
视频片段进入 Facebook 内容分发网络( FBCDN ),用户可以进行视频回放;
视频内容被保存到分布式存储系统里,以便永久保留;
保存在分布式存储系统里的视频内容用于后续的非实时回放。
正如基础设施架构图所显示的那样,流量的增长会影响到其中的三类资源:
网络:流入流量和流出流量;
CPU:用于视频内容的编码;
存储:用于保存视频内容。
简单地说就是网络、视频基础设施和存储。大部分大型的分布式系统都涉及日志存储、度量指标收集和配置分发,它们也都会受到流量增长的影响,所以它们也都包含在规划的范围之内。
负载指标
在为跨年夜做容量规划时,我们主要考虑三个指标:
12 月 31 号当天的 Facebook Live 广播总量。用于保存视频内容的分布式存储系统需要使用这项指标来规划存储容量;
12 月 31 号当天任意时刻的高峰并发数。这项指标用于计划存储系统的写入操作数量和用于编码视频的 CPU 使用量;
为了扩展 Facebook Live 基础设施而给其他系统造成的负载。
在这三个指标当中,高峰并发数是最难预估的一个。因为直播流自身的特点,我们无法使用非高峰期时段的方式来计算高峰期的并发数,所以我们需要准备足够多的容量来应对实时出现的流量高峰。因此,高峰并发数是我们为跨年夜做容量规划时需要考虑的最主要的度量指标。
其他相关系统造成的负载虽然不是很大,但也不可忽视。在 2017 年 12 月份的一次测试中就出现过流量的增长,其实它就是一种常规的健康检测,从直播流路由服务器向 FBLS 服务器的 TCP 端口发送请求。健康检测请求需要在路由服务器和 FBLS 服务器之间建立起多个连接。
为了扩展容量,需要增加 FBLS 服务器数量,健康检测每秒所产生的网络流量可以达到数百兆,这样不仅降低了路由服务器的性能,还影响到了其他服务。尽管这个问题很容易解决(降低健康检测的频率和路由服务器到 FBLS 服务器之间的连接数),但我们必须意识到,增加系统某一部分的容量,有可能影响到系统的其他部分。
预估跨年夜的流量
之前已经说过,高峰并发数是在进行跨年夜流量规划时最主要的度量指标。于是,我们与生产工程团队、容量规划团队和数据科学家团队一起合作,预测当天任意时刻的高峰流量。
因为 Facebook Live 已经在生产环境运行了好几年,我们手头有很多历史数据,包括各个跨年夜流量并发数的区域数据和全球数据,我们可以利用这些数据来预测未来的流量负载。通过观察过去跨年夜当天 24 小时的数据,我们可以预估这次跨年夜的流量模式。流量高峰发生在各个时区的午夜,它们都很短暂,但数值很高。为了预估高峰并发数的绝对值,我们观察了更多近期的数据,包括日常的流量模式和过去一整年的流量变化情况。
扩展容量
在预估好跨年夜当天的高峰并发数之后,接下来我们要确保我们的系统能够扩展到相应的水平。为此,我们需要增加更多的硬件资源(用于视频编码的 CPU 、网络路由、存储等)。除了增加硬件,我们还要优化我们的系统。比如,分布式存储系统的并行写入操作可能会成为容量瓶颈,所以需要进行优化。在跨年夜以前,存储系统的分段写入需要 10 秒钟(差不多每秒 1 兆,每个分段为 1.25 兆)。
我们将分段延长到以 20 秒为单位,以此降低写入频率和存储系统的 IOPS ,但不会给系统的可靠性或性能造成影响。
负载测试
在为跨年夜做准备的过程中,测试是最为耗时的一个部分,这也就是为什么我们要从 10 月份就要开始做准备。测试的目的是为了确保我们所做出的变更能够按照预期的计划正常运行。
我们通过以下三种方式进行负载测试。
增加特定层的负载。Facebook Live 的基础设施由多个 FBLS 物理集群组成,这些集群分布在多个区域。通常,流量会被均等地分发给这些集群。不过,为了测试单个主机或集群能够承受的最大容量,我们有意识地将流量重定向到单个集群或主机上,并观察主机的资源使用情况,找出服务的临界点。
这种测试方式对于估算高峰期需要多少 CPU 来说是非常有效的。视频广播系统与编码系统是相互独立的,所以编码系统可以自由地进行水平伸缩。系统本身的上限是由每台主机的最大并发数乘以主机数量来决定的。
不过,这种测试方式无法用于测试系统所依赖的网络和存储,因为发送给依赖系统的整体流量是不变的。
依赖系统的测试。 这种方式主要用于测试存储系统的容量。我们在 FBLS 服务器上运行专门的负载测试客户端,客户端向分布式存储系统写入大量人造数据,这样就可以知道存储系统是否能够承担跨年夜的流量高峰。
这种负载测试针对的是特定的依赖系统,需要通过特定的客户端向目标系统生成大量的人造数据。
不过不管怎样,这是一种非常重要的验证工具。
影子流量(Shadow Traffic)。我们可以把生产环境的流量复制到 FBLS 服务器上,这样就可以根据实际需要生成额外的流量。这是我们首选的负载测试方式,因为它可以测试到 Facebook Live 的各个系统,包括存储系统和网络服务。它生成的流量与生产环境是非常接近的,因此我们有信心我们的系统能够应对最大的流量。
在使用影子流量时,如何安全地复制生产环境流量并做好影子流量与非影子流量之间的隔离工作是最大的挑战。
结论与思考
我们仔细预估了跨年夜的流量负载,规划了全功能的容量,扩展了我们的系统,并验证了我们所做出的变更,我们非常有信心我们的系统可以应对额外的流量负载。我们的工作也得到了回报,在跨年夜当天,超过 1000 万的 Facebook 用户通过 Facebook Live 分享了他们的视频,比往年的流量要高出 47% 。
这种针对特别事件进行的容量规划对于 Facebook 的生产工程团队来说仍然是一项非常重要且需要持续进行的工作。这些事件各不一样,而且系统本身也在持续地发生演化。我们马不停蹄地贡献我们的力量,保证我们的系统能够在这些事件中安全地存活下来,并确保人们能够通过这个平台向他们关心的人和社区分享他们的体验。
领取专属 10元无门槛券
私享最新 技术干货