设计云盘

像谷歌云盘 Google Drive、Dropbox、微软 OneDrive、苹果 iCloud这样的产品。

理解问题

  1. 上传和下载文件,文件同步和通知
  2. 支持任意文件类型
  3. 存储的文件需要加密
  4. 文件最大为10GB
  5. 假设1000万DAU

封底估算

假设应用 5000 万注册用户 1000 万的DAU

每个用户10GB的免费空间,每位用户每天上传两个文件,每个文件平均大小500KB。总存储空间 5000万 x 10GB = 500PB。

用户读写操作比例 1:1

上传API的QPS:1000 万 x 2 / 24 /3600 = 240 峰值 QPS = QPS x 2 = 480

从简单的开始

从单个服务器开始,用一个Web服务器来上传和下载文件,用一个数据库来追踪元数据如用户数据、登录信息、文件信息等。 用一个文件系统来存储文件。

图15-3

API

一个用于上传文件,一个用于下载文件,还有一个用于获取文件修改信息。

支持两种上传,简单上传和可续上传。从云盘下载文件

跳出单服务器设计

随着越来越多文件要上传,文件系统空间会满。第一个简单解决方案是数据分片,这样数据就可以存储在多个存储服务器上。

如根据用户ID分片例子:

图15-5

虽然这样可以解决放不下问题,但是依然害怕存储服务器出现故障导致数据丢失,大公司基本都在用 Amazon S3 来存储数据, 亚马逊简单存储服务 Amazon Simple Storage,Amazon S3 是一种对象存储服务 提供领先的 可扩展性、数据可用性、安全性、性能。

Amazon S3 支持同地区和跨区复制。将冗余文件存储在多个地区,防止数据丢失并确保可用性,桶 Bucket 就像文件系统 的文件夹。

图15-6

考虑好 负载均衡器、Web服务器,元数据数据库需要设置好数据复制和分片满足可用性和扩展性。 文件存储 S3 文件在两个分隔的地理区域之间进行复制。

图15-7

同步冲突

当两个用户在同一时间修改同一个文件或文件夹时,冲突就会发生。

策略:系统先处理的版本胜出,系统后处理的版本将收到冲突通知。两个用户同时添加同名文件,还可以直接后端为二者重命名 避开冲突也是可行的。

高层级设计

块服务器,块服务器将块上传到云存储,一个文件可以被分成几个块,每个块都有一个唯一哈希值,存在元数据库里。 每个块被当作独立对象存储在Amazon S3。要重新构建一个文件,按照特定顺序将块连接在一起。块大小需要设置, Dropbox设置一个块是 4MB。

图15-10

进行合理的数据冷备份,以免真的末日到来亚马逊服务彻底崩了,虽然说不太可能。

API 服务器用于验证用户身份、管理用户资料、更新文件元数据等。

元数据数据库,存储用户、文件、块、版本等元数据,文件是存储在S3,元数据数据库只包含元数据。

元数据缓存:缓存某些元数据以便快速获取。

块服务器

可以有增量同步,当文件被修改时,通过同步算法,仅同步被修改的块而不是同步整个文件,对块进行压缩可以显著减小数据大小。

一个新文件被添加进来时块服务器进行工作

图15-11

下面展示增量同步例子,只有更改过的块才会被传给云存储,块服务器通过增量同步和压缩数据,节省了网络流量。

图15-12

高一致性需求

系统默认要求强一致性,在同一时间内,不同客户端上展示的同一个文件必须是一致的,需要为 元数据缓存和数据库层提供强一致性支持。

内存缓存默认采用最终一致模型,意味着不同的副本可能有不同的数据,为了实现强一致性,需要

关系型数据库中实现强一致性是容易的,因为它维护了 ACID,原子性 Atomicity、一致性 Consistency、隔离性 Isolation、持久性 Durability。NoSQL默认不支持ACID特性,需要编程将ACID特性纳入同步逻辑。

元数据数据库

图15-13

上传流程

并行发送两个请求,添加文件元数据和上传文件至云存储。

图15-14

客户端先请求写元数据 状态标记为待上传,然后客户端再请求上传文件 系统将块数据全部上传到 S3 把元数据状态标记更新为 已上传。

下载流程

下载,如果是多人共享文件,比如 一个人正在更新某个文件 同时其他人要下载或正在下载着那个文件, 处理好这种情景非常重要。

处理好服务器给客户端同步状态至关重要。

节约存储空间