系统设计面试问题:设计Spotify

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版,欢迎购买。点击进入详情

目录

初始阶段:基础版本

估计:数据数学

高层设计

数据存储

SQL数据库结构

把它们放在一起

规模化阶段:5000 万用户、2 亿首歌曲

引入 CDN

扩展数据库:领导者-跟随者技术


这是一道系统设计面试题,就是设计Spotify。在真正的面试中,通常,您会关注应用程序的一两个主要功能,但在本文中,我想对如何设计这样的系统进行高级概述,然后您可以更深入地研究如果需要的话,可以将其分为每个单独的部分。

初始阶段:基础版本

要求:最初的要求是处理50 万用户和 30M 首歌曲。我们将有播放歌曲的用户和上传歌曲的艺术家。

估计:数据数学

让我们首先估计我们需要的存储空间。首先,我们需要将歌曲存储在某种存储中。

  • 歌曲存储: Spotify 和类似服务通常使用 Ogg Vorbis 或 AAC 等格式进行流式传输,假设平均歌曲大小为 3MB,则我们需要3MB * 3000 万 = 90TB的歌曲存储空间。
  • 歌曲元数据:我们还需要存储歌曲元数据和用户个人资料信息。每首歌曲的平均元数据大小约为 100 字节 — 100 字节 * 3000 万 = 3GB
  • 用户元数据:平均而言,我们将为每个用户存储 1KB 的数据 — 1KB * 500,000 = 0.5GB

高层设计

移动应用程序:我们将有一个移动应用程序,它是用户与服务交互的前端。用户可以搜索歌曲、播放音乐、创建播放列表等。当用户执行操作(例如播放歌曲)时,应用程序会向后端服务器发送请求。

负载均衡器:但在到达服务器之前,我们有一个负载均衡器,它将传入流量分配到多个 Web 服务器上。这提高了我们的应用程序可用性和容错能力。

Web 服务器 (API): Web 服务器是处理来自移动应用程序的传入请求的 API。例如,如果用户想要播放歌曲,请求就会发送到这些网络服务器。然后,服务器确定歌曲所在的位置(在数据库或存储服务中)以及如何检索它。

数据存储

数据存储将分为两个独立的服务 -歌曲的 Blob 存储(我们将在其中存储实际的歌曲文件)和SQL 数据库(我们将在其中存储歌曲和用户元数据)

歌曲 - Blob 存储(例如,AWS S3、GCP、Azure Blob 存储):实际的歌曲文件存储在 Blob(二进制大对象)存储服务中。这些服务旨在存储大量非结构化数据。

用户、艺术家和歌曲元数据 — SQL 数据库:此 SQL 数据库存储结构化数据,例如用户信息(如用户名、密码和电子邮件地址)和歌曲元数据(如歌曲名称、艺术家姓名、专辑详细信息等)。

为什么是 SQL?SQL 数据库非常适合此类结构化数据,因为它们允许复杂的查询以及不同类型数据之间的关系。

每个歌曲文件都存储为“blob”,SQL 数据库通常会存储对此文件的引用(如 URL)

SQL数据库结构

以下是 SQL 数据库中的表及其关系的基本概述:

我们需要一个包含用户元数据的用户表,如用户 ID、用户名、电子邮件、密码哈希、CreatedAt、LastLogin 等。

歌曲将保存歌曲元数据信息,例如歌曲 ID、标题、艺术家 ID、持续时间、发行日期和文件 URL,文件 URL 是歌曲文件存储位置(例如,在 Blob 存储中)的 URL。

艺术家表将包含艺术家信息——艺术家 ID、姓名、简介、国家/地区等。

关系:我们将在ArtistsSongs Table中加入 Artists 和 Songs 表,其中我们将有ArtistID(指向 Artists 表的外键)和SongID(指向 Songs 表的外键)。从那里,我们可以获得歌曲元数据,其中还将包含FileURL指向歌曲所在Blob 存储的属性。

把它们放在一起

因此,Web 服务器将从 SQL 数据库获取歌曲元数据,并从歌曲元数据获取 ,fileURL然后将其从服务器逐块流式传输到移动应用程序。或者我们可以直接将它们从对象存储传输到客户端,绕过网络服务器以减少负载。

规模化阶段:5000 万用户、2 亿首歌曲

现在,如果我们扩展到 5000 万用户和 2 亿首歌曲怎么办?我们首先需要重新计算数据。这意味着 SQL 数据存储需要存储 200/30 = ~6.66 倍的歌曲元数据:
每首歌曲 100 字节 * 2 亿首歌曲 = 20GB

用户元数据也是如此:
每个用户 1KB * 5000 万用户 = 50GB

引入 CDN

由于流量增加 - 我们需要引入缓存和 CDN(如 Cloudfront / Cloudflare)来提供歌曲,并且每个 CDN 在地理位置上都将靠近一个区域;因此,它可以比网络服务器更快地提供歌曲。

我们可以使用LRU(最近最少使用)驱逐策略来缓存流行歌曲,不流行的歌曲仍然会从Blob存储中获取,然后缓存到CDN。

歌曲文件还可以直接从云存储传输到客户端,这将减少网络服务器的负载。

扩展数据库:领导者-跟随者技术

数据库也需要扩展。由于我们知道我们的应用程序的读取次数多于写入次数,这意味着有很多用户在听歌曲,但上传歌曲的艺术家数量相对较少 - 我们可以使用 Leader → Follower 技术,并拥有一个可以接受的Leader 数据库读/写和多个追随者或从属数据库将是只读的,用于检索歌曲和用户元数据。

如果有必要,我们还可以实现数据库分片,将其拆分为多个 SQL 数据库,或者实现 Leader ↔ Leader 技术,但这些都是更复杂的场景,并且你不会遇到对此问题问得太深的面试。

职场攻略与副业指南,成就你的IT人生。快扫描下面二维码关注吧!

ba1e8177db424136a3b666cf83ea7eef.png

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值