Netflix Live Origin 是一台自研服务器,位于云端直播流媒体管线与 Open Connect——也就是 Netflix 的内容分发网络(CDN)——之间。它就像一个质量控制检查点,决定哪些视频分片会被发送给全球数百万观众。
当 Netflix 最初引入直播能力时,他们需要一个能够处理实时视频分发独特挑战的系统。与内容会提前准备好的点播视频(VOD)不同,直播运行在严格的时间约束之下。每个视频分片都必须在几秒钟内完成编码、封装并交付到观众手中。Live Origin 正是为了承接这些要求而专门设计的。
在这篇文章中,我们将看看这个系统的架构,以及 Netflix 在构建它时遇到的挑战。
免责声明:本文基于 Netflix Engineering Team 公开分享的细节整理而成。如果你发现有任何不准确之处,欢迎指出。
系统如何工作
Live Origin 以多租户微服务的形式运行在 Amazon EC2 实例上。它的通信模型相当直接:
- 负责准备视频分片以供分发的 Packager,会通过 HTTP PUT 请求把这些分片发送到 Origin。
- Open Connect 节点则通过 HTTP GET 请求取回这些分片。PUT 请求使用的 URL 与 GET 请求使用的 URL 相同,从而形成一种简单的存取模式。
见下图:

Netflix 做了几个架构决策,这些决策塑造了 Live Origin 的工作方式。
- 第一,他们通过冗余的区域级直播流媒体管线来实现可靠性。Netflix 不是依赖单一编码管线,而是同时运行两条彼此独立的管线。每条管线运行在不同的云区域,并拥有各自独立的编码器、打包器以及视频输入源。
- 第二,Netflix 采用了带有 segment template 和固定 segment duration 的 manifest 设计。它们不是不断更新 manifest 文件去列出当前可用的分片,而是使用一种可预测的模板,其中每个分片都有固定的 2 秒时长。这样的设计让 Origin 可以准确预测某个分片应在何时发布。
由于直播视频源本身不可预测,再加上实时发布时限非常严格,直播流中不可避免地会出现缺陷。常见问题包括:视频帧或音频采样缺失导致的短分片、整个分片完全缺失,以及解码时间戳错误导致的时间连续性中断。
同时运行两条独立管线,会大幅降低两条管线在同一时间都产出有缺陷分片的概率。因为这两条管线使用的是不同的云区域、不同的编码器和不同的视频源,所以当一条管线产生坏分片时,另一条通常仍会产生好分片。
多管线感知与智能选择
Live Origin 利用自己处在分发路径中的位置,做出智能决策。当 Open Connect 请求某个分片时,Origin 会按预先设定的顺序检查来自两条管线的候选分片,并选择第一个有效的分片。
为了检测缺陷,Packager 会执行轻量级媒体检查,并在向 Origin 发布分片时,把缺陷信息作为元数据一并附上。在极少数两条管线都产出缺陷分片的情况下,这些缺陷信息也会继续向下游传递,以便客户端适当地处理错误。
面向 Open Connect 的优化
当 Live 项目启动时,Open Connect 已经针对 VOD 分发做了高度优化。Netflix 花了很多年去调优 nginx(一个 Web 服务器)以及底层操作系统,以适应这类场景。与传统 CDN 按需填充缓存不同,Open Connect 会把 VOD 资源预先放置到精心挑选的服务器上,这些服务器被称为 Open Connect Appliances(OCA)。
直播并不能自然地套入这套模型,因此 Netflix 扩展了 nginx 的 proxy-caching 功能。他们做了多项优化,以减少不必要的流量并提升性能。
Open Connect 节点会收到与客户端相同的 segment template。借助这些模板信息,OCA 可以在任意时刻判断某个事件下哪些分片编号范围是合法的。这让它们可以立刻拒绝那些超出范围的分片请求,从而阻止无意义的请求继续穿过网络抵达 Origin。
当一个分片尚未可用,而 Origin 收到对它的请求时,Origin 会返回 404 状态码(File Not Found),同时附带一个过期策略。Open Connect 可以把这个 404 缓存到该分片即将发布前的那一刻,从而避免反复发起失败请求。
Netflix 针对 live edge,也就是流中最新的那部分内容,实现了一项巧妙优化。当某个请求到达时,如果它请求的是即将发布的下一个分片,Origin 不会再返回一个会沿着网络一路传回客户端的 404,而是会把这个请求挂住。等分片一发布,Origin 就立刻响应这个等待中的请求。这样能显著减少那些稍微提前到达的请求所带来的网络流量。
为了支持这个功能,Netflix 还给 nginx 增加了毫秒粒度的缓存。标准 HTTP Cache Control 只能以秒为单位工作,而当分片每 2 秒生成一次时,这种粒度就过于粗糙了。
通过 HTTP Header 传递流媒体元数据
Netflix 使用自定义 HTTP Header,以一种高度可扩展的方式传递流媒体事件信息。直播流媒体管线会向 Origin 提供通知,Origin 再把这些通知插入到当时刻生成的分片响应头中。这些 Header 是累积性的,也就是说,它们会持续附着到后续分片上。
每当一个分片到达某个 OCA 时,通知信息就会从响应头中提取出来,并以 event ID 为键存入内存。当 OCA 把某个分片发送给客户端时,它会把最新的通知数据附在响应中。这个系统保证了无论观众当前播放到流中的哪个位置,都能收到最新的通知数据。即便某次响应没有提供新分片,这些通知也仍然可以通过该响应传递给客户端。
这种方式让 Netflix 能够高效地把广告开始、内容提醒或直播事件更新等信息传递给数百万设备,而且不依赖于观众当前的播放位置。
缓存失效与 Origin Masking
Netflix 构建了一套失效系统,它可以通过修改缓存键所使用的版本号,刷新某个事件对应的全部内容。这在活动开始前的测试阶段尤其有用,因为它能让网络在每次测试之间都回到干净状态。
Live Origin 发布的每个分片都包含了元数据,说明它是由哪条编码管线生成、来自哪个区域。增强后的失效系统会把这些变体因素也考虑进去。Netflix 可以只失效某一段分片编号范围,但前提是它们来自特定编码器,或者来自某个特定区域中的某个特定编码器。
结合这套缓存失效能力,Live Origin 还支持选择性编码管线屏蔽(selective encoding pipeline masking)。这个功能允许运维团队在向 Open Connect 提供内容时,排除某一条特定管线中的问题分片。当直播事件中检测到坏分片时,这套系统就可以把这些有问题的内容隐藏起来,从而保护数百万观众。这个能力在 DVR 回看窗口中尤其重要,因为观众可能会把时间轴拖回到那段有问题的内容。
存储架构的演进
Netflix 最初为 Live Origin 使用的是 AWS S3 存储,这和它们的 VOD 基础设施类似。在低流量事件中,这个方案表现良好;但随着规模扩大,他们发现直播有一套与点播内容截然不同的需求。
虽然 S3 达到了其承诺的可用性水平,但直播事件天然存在严格的 2 秒重试预算,因此任何延迟都会成为问题。在直播里,每一次写入都是关键且有时限的。它所要求的,更像是一个全球化、低延迟、高可用数据库,而不是对象存储。
Netflix 为新的存储系统提出了五项关键要求。
- 第一,他们需要在单个 AWS 区域内实现极高的写可用性,并能以低延迟复制到其他区域。任何超过 500 毫秒的失败写操作都被视为一个 bug。
- 第二,系统必须支持高写吞吐,能够在区域之间复制数百 MB 的数据。
- 第三,它必须高效支持大写入,这些写入会在同一分区中累积出数千个键。
- 第四,他们需要同一区域内的强一致性,以把读取延迟压到 1 秒以内。
- 第五,在 Open Connect 出现最坏边缘情况时,系统可能需要承受 GB 级的读吞吐,而且不能影响写路径。
Netflix 以前构建过一个键值存储抽象层(Key-Value Storage Abstraction),它基于 Apache Cassandra,为大值提供分块存储。这个抽象层最初是为云端游戏存档设计的,但 Live 场景会在写可用性、累计分区大小和读吞吐方面把它逼到极限。
它的解决方案是把大负载拆成多个块,每个块都可以独立重试。再结合 Apache Cassandra 的 local-quorum 一致性模型——即便整个可用区故障也仍能保持写可用——以及面向写优化的 Log-Structured Merge Tree 存储引擎,Netflix 最终满足了前四项要求。
性能提升也相当扎实:中位延迟从 113 毫秒降到 25 毫秒,99 分位延迟从 267 毫秒降到 129 毫秒。新方案更贵,但降低成本并不是首要目标。
不过,要处理 Origin Storm 这种失败场景,还需要额外工作。在这种情况下,数十个 Open Connect 顶层缓存可能会同时请求多个大型视频分片。测算结果显示,最坏情况下读吞吐可能达到 100 Gbps 甚至更高。
Netflix 可以直接从 Apache Cassandra 以网络线速响应这些读取请求,但他们观察到并发写入会出现不可接受的性能退化。为了解决这个问题,他们引入了基于 EVCache 的 write-through cache。EVCache 是 Netflix 基于 Memcached 的分布式缓存系统。这样一来,几乎所有读取都可以由高度可扩展的缓存承担,从而在不影响写路径的情况下,把吞吐提升到 200 Gbps 甚至更高。
最终架构中,Live Origin 会对 KeyValue 进行读写;KeyValue 会把 write-through cache 写入 EVCache,并实现一个分块协议,把大值分散存储到 Apache Cassandra 集群中。几乎全部读负载都由缓存承担,只有缓存未命中才会落到存储层。过去一年多里,这套组合已经成功满足了 Live Origin 的高强度需求。
可扩展性与请求优先级
Netflix 的直播平台需要为每场直播事件处理大量、且类型多样的 stream rendition。这种复杂性来自它必须同时支持多种视频编码格式及多个质量档位、不同语言和格式的多条音频轨,以及带广告和不带广告等不同内容版本。在 2024 年 Tyson vs. Paul 那场比赛期间,Netflix 观察到了历史峰值:6500 万并发流。
Netflix 选择构建一个高度可扩展的 origin,而不是依赖传统 origin shield,因为这样能更好地控制缓存一致性,同时也能简化系统架构。Live Origin 会直接连接分布在多个站点、按地理分布的顶层 Open Connect 节点。为了尽量减轻 origin 的负载,在每个站点上,每个 stream rendition 只有指定节点可以直接从 origin 填充缓存。
见下图:

尽管 origin 服务本身可以通过增加 EC2 实例水平扩展,但其他系统资源,比如存储平台容量和骨干带宽,并不能自动扩展。而且,并不是所有发往 live origin 的请求都有同样的重要性。Origin 写入最关键,因为写失败会直接影响流媒体管线;live edge 上的 Origin 读取也很关键,因为失败会影响绝大多数客户端;而 DVR 模式下的 Origin 读取则没那么关键,因为失败只会影响那些正在回看的客户端。
Netflix 实现了完整的发布隔离(publishing isolation),以保护对延迟和失败都非常敏感的 origin 写入路径。Origin 会把发布流量和 CDN 流量放在独立的 EC2 栈上;存储抽象层会为读和写分别使用不同集群;而存储层本身也把读路径(EVCache)与写路径(Cassandra)分离开来。这种完整路径隔离使发布流量与分发流量能够独立扩展,并防止 CDN 流量激增影响发布性能。
当底层系统承受压力时,Live Origin 会基于优先级实施限流。这种做法可以保证用户影响更大的请求优先成功,而让用户影响较小的请求在高负载时允许失败。在存储平台负载较高时,live edge 流量会优先于 DVR 流量。判断依据来自可预测的 segment template,它会被缓存在 origin 节点的内存中,因此无需访问数据存储就能完成优先级决策——这在数据存储承压时尤其重要。
为了缓解流量激增,Netflix 还把 TTL cache control 与优先级限流结合起来使用。当低优先级流量受影响时,Origin 会通过设置 max-age 指令并返回 HTTP 503 错误码,通知 Open Connect 把相同请求缓存 5 秒。这个策略通过阻止 5 秒窗口内的重复请求,有效抑制了流量洪峰。
处理 404 风暴
发布隔离和优先级限流,已经足以保护 live origin 免受 DVR 流量风暴冲击。然而,由对不存在分片的请求所引发的流量风暴,还带来了额外挑战,也带来了进一步优化的机会。
Live Origin 以分层方式组织元数据:事件(event)、stream rendition 和 segment。分片发布模板维护在 stream rendition 这一层。这种层次化组织方式,使 origin 可以利用高度可缓存的事件级与 rendition 级元数据,提前拒绝请求,从而避免不必要地去查询 segment 级元数据。
它的工作过程如下:
- 如果事件未知,请求会以 404 错误被拒绝。
- 如果事件存在,但分片请求的时间点与预期发布时间不匹配,请求会以 404 被拒绝,同时附带一个与预期发布时间一致的 cache control TTL。
- 如果事件存在,但请求的分片根本没有被生成,或者已经错过重试截止时间,请求会以 410(Gone)错误被拒绝,这会明确告诉客户端不要再继续请求。
在存储层,元数据与媒体数据分开存储在 control plane datastore 中。与媒体数据存储不同,control plane datastore 不使用分布式缓存,以避免缓存不一致。对于 live origin 实例而言,事件级和 rendition 级元数据在使用内存缓存时能获得很高的命中率。在针对不存在分片的流量风暴中,control plane 的缓存命中率很容易超过 90%。
通过对元数据使用内存缓存,Live Origin 可以在不对数据存储造成压力的情况下有效应对 404 风暴。这种元数据缓存与存储系统中的分布式媒体缓存相互补充,共同构成了一套完整的流量洪峰防护方案。
结论
Netflix Live Origin 是一套专门为超大规模直播场景打造的复杂系统。
通过冗余管线、智能分片选择、优化后的缓存策略、优先级化请求处理,以及定制化存储架构,Netflix 构建出了一套可靠基础设施,能够把直播事件交付给全球数百万并发观众。
这套系统成功平衡了写入可靠性、读取可扩展性与运维灵活性之间相互竞争的要求,并在 Tyson vs. Paul 这样的重大事件中证明了自身有效性——那场直播曾达到 6500 万并发流。
参考资料
本文为学习目的的个人翻译,译文仅供参考。
原文链接:How Netflix Live Streams to 100 Million Devices in 60 Seconds。
版权归原作者或原刊登方所有。本文为非官方译本;如有不妥,请联系删除。