十五、设计谷歌云盘
近年来,Google Drive、Dropbox、微软 OneDrive、苹果 iCloud 等云存储服务变得非常流行。在这一章中,你被要求设计 Google Drive。
在开始设计之前,让我们花点时间了解一下 Google Drive。Google Drive 是一种文件存储和同步服务,可以帮助您在云端存储文档、照片、视频和其他文件。您可以从任何电脑、智能手机和平板电脑上访问您的文件。您可以轻松地与朋友、家人和同事分享这些文件[1]。图 15-1 和 15-2 分别显示了 Google drive 在浏览器和移动应用上的样子。
步骤 1 -了解问题并确定设计范围
设计 Google drive 是一个大项目,所以提问来缩小范围是很重要的。
候选 : 最重要的特征是什么?
面试官 :上传下载文件,文件同步,通知。
候选人 : 这是一款手机 app,还是一款 web app,还是两者都有?
面试官 :都有。
候选人 :支持哪些文件格式?
面试官 :任何文件类型。
考生 :文件需要加密吗?
采访 :是的,存储中的文件必须加密。
候选人 :文件大小有限制吗?
采访 :是的,文件必须是 10 GB 或者更小。
候选人 : 产品有多少用户?
面试官 : 10M DAU。
在本章中,我们重点介绍以下特性:
添加文件。添加文件最简单的方法是将文件拖放到 Google drive 中。
下载文件。
跨多个设备同步文件。当文件添加到一个设备时,它会自动同步到其他设备。
参见文件修订。
与朋友、家人和同事分享文件
当文件被编辑、删除或与您共享时,发送通知。
本章未讨论的特性包括:
谷歌文档编辑与协作。Google doc 允许多人同时编辑同一个文档。这超出了我们的设计范围。
除了阐明需求,理解非功能性需求也很重要:
可靠性。可靠性对于存储系统来说极其重要。数据丢失是不可接受的。
同步速度快。如果文件同步花费太多时间,用户会变得不耐烦并放弃产品。
带宽使用率。如果一个产品占用了大量不必要的网络带宽,用户会不高兴,特别是当他们使用移动数据计划时。
扩展性。这个系统应该能够处理大量的交通流量。
高可用性。当某些服务器脱机、速度变慢或出现意外网络错误时,用户应该仍然能够使用系统。
信封估算的背面
假设该应用拥有 5000 万注册用户和 1000 万 DAU。
用户获得 10 GB 免费空间。
假设用户每天上传 2 个文件。平均文件大小为 500 KB。
1:1 读写比。
总分配空间:5000 万 * 10gb = 500 Pb
QPS 上传 API: 1000 万 * 2 次上传 / 24 小时 / 3600 秒 = ~240
巅峰 QPS = QPS * 2 = 480
第二步-提出高层次设计并获得认同
我们将使用稍微不同的方法,而不是从一开始就展示概要设计图。我们将从简单的事情开始:在单个服务器中构建一切。然后,逐步扩大规模,支持数百万用户。通过做这个练习,它将刷新你对书中涉及的一些重要话题的记忆。
让我们从下面列出的单个服务器设置开始:
上传和下载文件的网络服务器。
跟踪元数据的数据库,如用户数据、登录信息、文件信息等。
存储文件的存储系统。我们分配 1TB 的存储空间来存储文件。
我们花了几个小时设置了一个 Apache web 服务器,一个 MySql 数据库,以及一个名为 drive/
的目录作为根目录来存储上传的文件。在 drive/
目录下,有一个目录列表,称为名称空间。每个名称空间包含该用户的所有上传文件。服务器上的文件名与原始文件名保持一致。通过连接命名空间和相对路径,可以唯一地标识每个文件或文件夹。
图 15-3 显示了左侧的 /drive
目录及其右侧的展开视图。
API
API 看起来像什么?我们主要需要 3 个 API:上传文件、下载文件和获取文件修订。
1。将文件上传到 Google Drive
支持两种上传类型:
简单上传。当文件较小时,使用此上传类型。
可恢复上传。当文件很大并且网络中断的可能性很高时,使用此上传类型。
下面是一个可恢复上传 API 的例子:
https://api.example.com/files/upload?uploadType=resumable
参数:
uploadType=resumable
数据:要上传的本地文件。
可恢复上传通过以下 3 个步骤实现【2】:
发送初始请求以检索可恢复的 URL。
上传数据并监控上传状态。
如果上传中断,恢复上传。
2。从 Google Drive 下载文件
示例 API:https://api.example.com/files/download
参数:
path
:下载文件路径。
示例参数:
{ "path":"/recipes/soup/best_soup.txt " }
3。获取文件修订版
示例 API:https://api.example.com/files/list_revisions
参数:
path
:您想要获取修订历史的文件的路径。
limit
:返回的最大修订数。
示例参数:
{ "path":"/recipes/soup/best_soup.txt", "limit": 20 }
所有的 API 都需要用户认证并使用 HTTPS。安全套接字层(SSL)保护客户端和后端服务器之间的数据传输。
远离单一服务器
随着更多的文件上传,最终你会得到如图 15-4 所示的空间已满的警告。
只剩下 10 MB 的存储空间了!这是一个紧急情况,因为用户不能再上传文件。我想到的第一个解决方案是对数据进行分片,这样就可以将数据存储在多个存储服务器上。图 15-5 显示了基于 user_id
的分片示例。
你熬了一整夜来建立数据库分片并密切监控它。一切又顺利了。您已经扑灭了大火,但是您仍然担心万一存储服务器停机,可能会丢失数据。你四处打听,你的后台专家朋友 Frank 告诉你,许多领先的公司,如网飞和 Airbnb,都使用亚马逊S3
进行存储。“亚马逊简单存储服务(亚马逊 S3)是一种对象存储服务,提供行业领先的可扩展性、数据可用性、安全性和性能”[3]。你决定做一些研究,看看它是否是一个很好的适合。
经过大量阅读,你对S3
的存储系统有了很好的了解,并决定在S3
存储文件。亚马逊S3
支持同区域和跨区域复制。区域是亚马逊网络服务(AWS)拥有数据中心的地理区域。如图 15-6 所示,数据可以在同一区域(左侧)和跨区域(右侧)复制。冗余文件存储在多个区域,以防止数据丢失并确保可用性。存储桶就像文件系统中的文件夹。
把文件放到S3
后,你终于可以睡个好觉,不用担心数据丢失了。为了防止将来发生类似的问题,你决定对你可以改进的地方做进一步的研究。以下是你能找到的几个领域:
负载均衡器:添加一个负载均衡器来分配网络流量。负载平衡器确保流量均匀分布,如果 web 服务器出现故障,它将重新分配流量。
Web 服务器:添加负载均衡器后,可以根据流量负载轻松添加/删除更多 Web 服务器。
元数据库:将数据库移出服务器,避免单点故障。同时,设置数据复制和分片,以满足可用性和可伸缩性要求。
文件存储:亚马逊S3
用于文件存储。为了确保可用性和持久性,文件在两个不同的地理区域进行复制。
在应用了上述改进之后,您已经成功地将 web 服务器、元数据数据库和文件存储从单个服务器中分离出来。更新后的设计如图 15-7 所示。
系统设计面试的行家指南(下)(2)https://developer.aliyun.com/article/1481950