如何设计一个 Youtube 系统

简化这个复杂的系统设计问题,把它分成几块:

  • 存储:数据库如何设计,图片和视频如何存储
  • 扩展:面对百万级别甚至上亿级别的用户,如何扩展存储和整个系统
  • Web 服务器:前端与服务器沟通进行用户验证,Session,取数据和更新用户数据等等,然后服务器与存储系统,推荐系统等等再沟通
  • 缓存:我们需要多个层次的缓存
  • 还有很多问题,比如推荐系统,安全系统等等,每一个问题都可以当成一个面试题

存储和数据模型

首先,我们需要定义用户数据模型,我们可以把 email ,姓名,注册信息等等存储在一个表里面。另外一种更常见的做法就是把用户数据拆成两个表,一个专门为了验证,存储 email ,密码,姓名,注册日期之类的,另外一个存储更详细的信息,例如地址,年龄等。

视频也一样,它包括一些基本信息。很明显,我们也应该把这些基本信息存储在一个独立的表里面。

另外需要的就是用户喜欢的视频用户关联的视频,这两部分信息需要单独建表。

视频和图片存储

其实 Youtube 的图片数量比视频数量要多,因为每个视频都有好几个不同大小的thumbnails,所以图片存储不可忽视。比较常见的做法就是使用 CDN 了。

热门 vs 冷门视频

如果你觉得把所有视频和图片都扔到 CDN 上,那你就大错特错了,大多数视频都是 long-tailed 冷门视频,一天也就 1-20 个观看。然而转念一想,这些热门视频随处可见,倒是一些冷门视频才让一个产品变得与众不同,吸引特定的一部分群体。如果你能提前预测的话,那么高效地存储这部分信息也是有可能的。

数据库扩展

  1. 首先仅当你确实需要扩展数据库的时候,你才去扩展数据库。
  2. 当业务发展到一定规模之后,可能会拥有一个master和几个slavesmaster/slave model)。
  3. 再往后,你可能会拆分数据库,开始着想sharding方法。例如,你可以根据用户的位置来拆分数据库,当一个请求进来的时候,你可以路由到相应的数据库去。

对于 Youtube 来说,我们还可以进一步优化。我们一定要分清楚瓶颈在哪里,在这里就是观看视频,通过把数据拆分成两个集群:视频集群和general集群,我们可以把更多的流量分给视频集群,其他行为相应的路由到能力较弱的这个集群上。

数据缓存

鉴于我们先前已经探讨过如果设计一个缓存系统,所以这里不多做介绍,但是有几个地方需要注意:

  • 一般人会想到服务器缓存,但前端缓存同样重要。如果你想让你的网站非常快速,前端缓存几乎不可避免。
  • 另外,Youtube 一般使用 long-tailed 用户比较多,把所有视频缓存起来很不现实。

安全

在安全问题上有很多可以考虑,我在这里提一下观看数量的问题。

  • 当一个 IP 有太多对数量接口的请求的时候,我们就屏蔽掉这个 IP
  • 我们甚至可以限制每个 IP 最多可以观看的数量
  • 也可以查看浏览器agent和历史记录,来预防一部分潜在攻击
  • 人们可以使用Tor)来隐藏IP,或者使用Mechanical Turk来刷榜
  • 一个观看数量只多,但是其他分享数量、评论数量、观看时间不多的视频,也是比较可疑的

Web 服务器

许多人大概都忽视了 Web 服务器,实际上还是有很多事情需要考虑的。

  • Youtube 一开始选择使用 Python 来快速开发,虽然性能有点慢,但是可以通过C extensions来解决。
  • 为了扩展Web服务器,你可以有多个replicas(A replica is an exact reproduction, such as of a painting, as it was executed by the original artist or a copy or reproduction, especially one on a scale smaller than the original),然后建一个load-balancer在它们之上
  • Web 服务器响应速度必须快

How to Design Youtube (Part I) How to Design Youtube (Part II) Wikipedia-Replica

results matching ""

    No results matching ""