系统设计:Netflix 系统设计目录

2025-05-25

系统设计:Netflix

系统设计

目录

让我们设计一个类似Netflix的视频流服务,类似于Amazon Prime VideoDisney PlusHuluYoutubeVimeo等服务。

什么是 Netflix?

Netflix 是一项基于订阅的流媒体服务,允许其会员在联网设备上观看电视节目和电影。它可在 Web、iOS、Android、电视等平台上使用。

要求

我们的系统应满足以下要求:

功能要求

  • 用户应该能够流式传输和共享视频。
  • 内容团队(或 YouTube 的用户)应该能够上传新视频(电影、电视节目剧集和其他内容)。
  • 用户应该能够使用标题或标签搜索视频。
  • 用户应该能够对类似于 YouTube 的视频发表评论。

非功能性需求

  • 高可用性和最小延迟。
  • 可靠性高,上传不会丢失。
  • 该系统应具有可扩展性和高效性。

扩展要求

  • 某些内容应该受到地理封锁
  • 从用户停止的地方继续播放视频。
  • 记录视频的指标和分析。

估计和约束

让我们从估计和约束开始。

注意:请务必与面试官核对任何与规模或交通相关的假设。

交通

这将是一个阅读量很大的系统。假设我们拥有 10 亿用户,其中每日活跃用户 (DAU) 为 2 亿,平均每位用户每天观看 5 个视频。这意味着每天观看的视频数量为 10 亿。

200   n × 5   d e = 1   b n / d 一个 y 2亿\space个\space视频乘以5\space个视频=10亿\space个/天
假设200:1读写比率为 5000 万,每天将上传约 5000 万个视频。
1 200 × 1   b n = 50   n / d 一个 y \frac{1}{200} \times 1 \space 十亿 = 50 \space 百万/天
我们的系统的每秒请求数(RPS)是多少?

每天 10 亿个请求相当于每秒 12000 个请求。

1   b n ( 24   h r × 3600   e c n d ) = 12   r e e / e c n d \frac{1 \space 十亿}{(24 \space 小时 \times 3600 \space 秒)} = \sim 12K \space 请求/秒
### 贮存

如果我们假设每个视频平均为 100 MB,那么我们每天将需要大约 5 PB 的存储空间。

50   n × 100   B = 5   B / d 一个 y 50 \space 百万 \times 100 \space MB = 5 \space PB/天
而 10 年后,我们将需要高达 18,250 PB 的存储空间。
5   B × 365   d 一个 y × 10   y e 一个 r = 18 250   B 5 \space PB \times 365 \space 天 \times 10 \space 年 = \sim 18,250 \space PB
### 带宽

由于我们的系统每天要处理 5 PB 的入口数据,因此我们需要每秒约 58 GB 的最低带宽。

5   B ( 24   h r × 3600   e c n d ) = 58   B / e c n d \frac{5 \space PB}{(24 \space 小时 \times 3600 \space 秒)} = \sim 58 \space GB/秒
### 高级估算

以下是我们的高级估计:

类型 估计
每日活跃用户(DAU) 2亿
每秒请求数 (RPS) 12K/秒
存储(每天) ~5 PB
储存(10年) ~18,250 PB
带宽 ~58 GB/秒

数据模型设计

这是反映我们要求的通用数据模型。

netflix 数据模型

我们有下表:

用户

该表将包含用户的信息,例如,,,name其他详细信息。emaildob

视频

顾名思义,该表将存储视频及其属性,例如title,,等streamURLtags我们还将存储相应的userID

标签

该表将仅存储与视频相关的标签。

视图

该表帮助我们存储视频收到的所有观看次数。

评论

该表存储了有关视频(如 YouTube)的所有评论。

我们应该使用什么样的数据库?

虽然我们的数据模型看起来相当相关,但我们不一定需要将所有内容存储在单个数据库中,因为这会限制我们的可扩展性并很快成为瓶颈。

我们将数据拆分到不同的服务,每个服务拥有特定表的所有权。然后,我们可以将关系数据库(例如PostgreSQL)或分布式 NoSQL 数据库(例如Apache Cassandra)用于我们的用例。

API 设计

让我们为我们的服务做一个基本的 API 设计:

上传视频

通过给定字节流,此 API 可以将视频上传到我们的服务。



uploadVideo(title: string, description: string, data: Stream<byte>, tags?: string[]): boolean


Enter fullscreen mode Exit fullscreen mode

参数

标题(string):新视频的标题。

描述 ( string):新视频的描述。

数据(Byte[]):视频数据的字节流。

标签(string[]):视频的标签(可选)

返回

结果(boolean):表示操作是否成功。

流式传输视频

此 API 允许我们的用户使用首选的编解码器和分辨率来流式传输视频。



streamVideo(videoID: UUID, codec: Enum<string>, resolution: Tuple<int>, offset?: int): VideoStream


Enter fullscreen mode Exit fullscreen mode

参数

视频ID(UUID):需要流式传输的视频的ID。

编解码器(Enum<string>):请求视频所需的编解码器h.265,例如、、h.264VP9

分辨率(Tuple<int>):请求的视频的分辨率。

偏移量(int):视频流与视频中任意点之间的数据流偏移量(以秒为单位)(可选)

返回

流(VideoStream):请求的视频数据流。

搜索视频

该 API 将使我们的用户能够根据标题或标签搜索视频。



searchVideo(query: string, nextPage?: string): Video[]


Enter fullscreen mode Exit fullscreen mode

参数

查询(string):来自用户的搜索查询。

下一页(string):下一页的令牌,可用于分页(可选)

返回

视频(Video[]):符合特定搜索查询的所有视频。

添加评论

此 API 将允许我们的用户对视频发表评论(如 YouTube)。



comment(videoID: UUID, comment: string): boolean


Enter fullscreen mode Exit fullscreen mode

参数

VideoID(UUID):用户想要评论的视频的ID。

评论(string):评论的文本内容。

返回

结果(boolean):表示操作是否成功。

高层设计

现在让我们对我们的系统进行高层设计。

建筑学

我们将使用微服务架构,因为它可以更轻松地水平扩展和解耦我们的服务。每个服务都拥有自己的数据模型。让我们尝试将系统划分为几个核心服务。

用户服务

该服务处理与用户相关的问题,例如身份验证和用户信息。

流服务

推文服务将处理与视频流相关的功能。

搜索服务

该服务负责处理与搜索相关的功能。我们将另行详细讨论。

媒体服务

该服务将负责视频的上传和处理。具体细节我们将另行讨论。

分析服务

该服务将用于指标和分析用例。

服务间通信和服务发现怎么样?

由于我们的架构基于微服务,因此服务之间也会相互通信。通常,REST 或 HTTP 的性能表现良好,但我们可以使用更轻量、更高效的gRPC来进一步提升性能。

服务发现是我们需要考虑的另一件事。我们还可以使用服务网格,实现各个服务之间可管理、可观察且安全的通信。

注意:了解有关REST、GraphQL、gRPC 的更多信息以及它们之间的比较。

视频处理

在处理视频时,变量非常多。例如,高端摄像机拍摄的两小时原始 8K 视频的平均数据量很容易就达到 4 TB,因此我们需要进行某种处理来降低存储和传输成本。

以下是内容团队(或 YouTube 的用户)上传视频后,我们在消息队列中排队等待处理时的处理方式。

视频处理管道

让我们讨论一下它是如何工作的:

  • 文件分块器

这是我们处理流程的第一步。文件分块是将文件分割成更小的块(称为“块”)的过程。它可以帮助我们消除存储中重复数据的重复副本,并通过仅选择已更改的块来减少通过网络发送的数据量。

通常,可以根据时间戳将视频文件分割成大小相等的块,但 Netflix 却根据场景分割块,这种细微的变化成为改善用户体验的一个重要因素,因为每当客户端从服务器请求一个块时,中断的可能性就会降低,因为会检索到完整的场景。

文件分块

  • 内容过滤器

此步骤检查视频是否符合平台的内容政策,对于 Netflix 来说,可以根据媒体的内容评级进行预先批准,或者可以像 YouTube 一样严格执行。

整个步骤由机器学习模型完成,该模型会执行版权、盗版和 NSFW 检查。如果发现问题,我们会将任务推送到死信队列 (DLQ),以便审核团队进行进一步检查。

  • 转码器

转码是将原始数据解码为中间未压缩格式,然后将其编码为目标格式的过程。此过程使用不同的编解码器来执行比特率调整、图像下采样或媒体重新编码。

这样可以生成更小的文件,并针对目标设备提供更优化的格式。您可以使用FFmpeg等独立解决方案或AWS Elemental MediaConvert等云端解决方案来实现流水线的这一步骤。

  • 质量转换

这是处理管道的最后一步,顾名思义,此步骤处理上一步转码媒体转换为不同分辨率,例如 4K、1440p、1080p、720p 等。

这使我们能够根据用户的要求获取所需的视频质量,并且一旦媒体文件完成处理,它将被上传到分布式文件存储(如HDFSGlusterFS)或对象存储(如Amazon S3 ) ,以便在流式传输期间稍后检索。

注意:我们可以添加其他步骤(例如字幕和缩略图生成)作为管道的一部分。

我们为什么要使用消息队列?

将视频处理作为一项长期运行的任务更加合理,而且消息队列还能将视频处理流程与上传功能解耦。我们可以使用Amazon SQSRabbitMQ之类的工具来支持这一点。

视频流

无论从客户端还是服务器的角度来看,视频流传输都是一项极具挑战性的任务。此外,不同用户的网络连接速度差异很大。为了确保用户不会重复获取相同的内容,我们可以使用内容分发网络 (CDN)

Netflix 通过其Open Connect计划更进一步。通过这种方式,他们与数千家互联网服务提供商 (ISP) 合作,实现流量本地化,并更高效地交付内容。

Netflix 的 Open Connect 与传统内容分发网络 (CDN) 有何区别?

Netflix Open Connect 是我们专门构建的内容分发网络 (CDN),负责服务 Netflix 的视频流量。全球约 95% 的流量是通过 Open Connect 与其客户用于访问互联网的 ISP 之间的直接连接传输的。

目前,Netflix 在全球 1000 多个不同地点部署了 Open Connect Appliances(OCA)。一旦出现问题,Open Connect Appliances(OCA)可以进行故障转移,并将流量重新路由到 Netflix 服务器。

此外,我们可以使用自适应比特率流协议,例如HTTP 实时流 (HLS),该协议专为可靠性而设计,可通过优化播放以适应可用的连接速度来动态适应网络条件。

最后,为了从用户离开的地方播放视频(我们的扩展要求的一部分),我们可以简单地使用offset存储在views表中的属性来检索特定时间戳的场景块并为用户恢复播放。

搜索

有时,传统的 DBMS 性能不够强,我们需要一些能够快速、近乎实时地存储、搜索和分析海量数据,并在几毫秒内给出结果的工具。Elasticsearch可以帮助我们实现这一目标。

Elasticsearch是一个分布式、免费且开放的搜索和分析引擎,适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。它构建于Apache Lucene之上

我们如何识别热门内容?

趋势功能将基于搜索功能。我们可以缓存过去几秒内搜索最频繁的查询,并使用某种批处理机制N每秒更新一次。M

共享

共享内容是任何平台的重要组成部分,为此,我们可以提供某种 URL 缩短服务,为用户生成短 URL 以供共享。

更多详细信息,请参考URL Shortener系统设计。

详细设计

现在是时候详细讨论我们的设计决策了。

数据分区

为了扩展数据库,我们需要对数据进行分区。水平分区(又称分片)是一个很好的第一步。我们可以使用以下分区方案:

  • 基于哈希的分区
  • 基于列表的分区
  • 基于范围的分区
  • 复合分区

上述方法仍然会导致数据和负载分布不均匀,我们可以使用一致性哈希来解决这个问题。

有关更多详细信息,请参阅分片一致性哈希

地理封锁

Netflix 和 YouTube 等平台使用地理封锁功能来限制特定地理区域或国家/地区的内容。这主要是因为 Netflix 与制作和发行公司签订协议时必须遵守合法的发行法规。对于 YouTube 而言,这将由用户在内容发布期间控制。

我们可以使用用户个人资料中的IP或区域设置来确定用户的位置,然后使用支持地理限制功能的Amazon CloudFront等服务或使用Amazon Route53 的地理位置路由策略来限制内容,如果内容在特定地区或国家/地区不可用,则将用户重新路由到错误页面。

建议

Netflix 使用机器学习模型,该模型利用用户的观看历史来预测用户接下来可能想看什么,可以使用协同过滤之类的算法。

然而,Netflix(与 YouTube 类似)使用自己的算法,称为 Netflix 推荐引擎,该算法可以跟踪多个数据点,例如:

  • 用户个人资料信息,如年龄、性别和位置。
  • 用户的浏览和滚动行为。
  • 用户观看影片的时间和日期。
  • 用于传输内容的设备。
  • 搜索次数以及搜索的术语。

有关更多详细信息,请参阅Netflix 推荐研究

指标和分析

记录分析和指标是我们的扩展需求之一。我们可以从不同的服务中捕获数据,并使用Apache Spark(一个用于大规模数据处理的开源统一分析引擎)对数据进行分析。此外,我们可以将关键元数据存储在视图表中,以增加数据中的数据点。

缓存

在流媒体平台中,缓存至关重要。为了提升用户体验,我们必须尽可能多地缓存静态媒体内容。我们可以使用RedisMemcached等解决方案,但哪种缓存驱逐策略最适合我们的需求呢?

使用哪种缓存驱逐策略?

对我们的系统来说,最近最少使用(LRU)策略可能是一个不错的选择。在这个策略中,我们首先丢弃最近最少使用的键。

如何处理缓存未命中?

每当出现缓存未命中时,我们的服务器可以直接访问数据库并使用新条目更新缓存。

有关详细信息,请参阅缓存

媒体流和存储

由于我们的大部分存储空间将用于存储缩略图和视频等媒体文件。根据我们之前的讨论,媒体服务将负责媒体文件的上传和处理。

我们将使用分布式文件存储(例如HDFSGlusterFS)或对象存储(例如Amazon S3)来存储和传输内容。

内容分发网络 (CDN)

内容分发网络 (CDN)可以提高内容可用性和冗余度,同时降低带宽成本。通常,静态文件(例如图像和视频)由 CDN 提供。对于这种情况,我们可以使用Amazon CloudFrontCloudflare CDN等服务。

识别并解决瓶颈

Netflix 高级设计

让我们识别并解决设计中的单点故障等瓶颈:

  • “如果我们的某项服务崩溃了怎么办?”
  • “我们将如何在组件之间分配流量?”
  • “我们如何才能减轻数据库的负载?”
  • “如何提高我们的缓存的可用性?”

为了使我们的系统更具弹性,我们可以执行以下操作:

  • 运行我们每项服务的多个实例。
  • 在客户端、服务器、数据库和缓存服务器之间引入负载平衡器。
  • 为我们的数据库使用多个读取副本。
  • 我们的分布式缓存有多个实例和副本。

本文是我在 Github 上提供的开源系统设计课程的一部分。

文章来源:https://dev.to/karanpratapsingh/system-design-netflix-3d9g
PREV
系统设计:Twitter 系统设计目录
NEXT
Docker化你的React应用