如何设计类似百度 盘的系统?-百度 盘的系统设计分析

系统设计是软件工程中最重要和最令人担忧的方面之一。很难理解软件体系结构书籍中使用的术语,并且没有明确的分步指南。 每个人似乎都有不同的方法。 当然,还有一个心理障碍是这些可能本来就很难理解。 因此,我根据自己学习架构课程的经验着手设计一个系统。让我们设计一种云文件存储服务,Google Drive。它是一个文件存储和同步服务,使用户可以将其数据存储在远程服务器上。

现在,那些已经使用过Google Drive的人知道我们可以从任何设备上传任何大小的文件,并且可以在我们的手机,笔记本电脑,个人计算机等设备上找到这些文件。我们很多人想知道该系统如何处理如此大量的文件。

★系统定义

我们需要澄清系统的目标。 系统设计是一个巨大的话题。如果我们不将其范围缩小到特定目的,那么设计系统就会变得复杂,尤其是对于新手。

用户应该能够从任何设备上载和下载文件/照片。并且文件将在用户登录的所有设备中同步。

如果考虑到服务中有1000万用户,每天有1亿个请求,那么写入和读取操作的数量将是巨大的。为简化起见,我们仅设计Google云端硬盘存储空间。换句话说,用户可以上传和下载文件,从而有效地将它们存储在云中。

★系统要求

在这一部分中,我们决定系统的功能。我们可以将这些要求分为两部分:

  • 功能要求:

    用户应该能够从任何设备上载和下载文件。并且文件将在用户登录的所有设备中同步。
    这些是系统的主要目标。这是系统必须交付的要求。

  • 非功能需求NFR:

    现在分析的更关键的要求。让我们定义我们的NFR:

    用户可以从任何设备上载和下载文件。该服务应支持存储最大1 GB的单个大文件。服务应在设备之间自动同步;如果一个文件是从设备上传的,则应在用户登录的所有设备上同步该文件。

★服务器端组件设计

对于系统设计的新手,请记住:“如果您对从哪里开始系统设计感到困惑,请尝试从数据流开始。”

我们在该系统中的用户可以上传和下载文件。用户从客户端应用程序/浏览器上载文件,服务器将存储它们。用户可以从服务器下载更新的文件。因此,让我们看看我们如何为如此大量的用户处理文件的上传和下载。

上传/下载文件:

从图中可以看到,如果我们上传完整大小的文件,则会浪费我们的存储和带宽。而且,延迟会增加以完成上载或下载。

我们的块大小需要更小。这将有助于优化空间利用率,而 络带宽是做出决定时的另一个考虑因素。元数据应包括每个文件的块信息的记录。

我们可以假设文件需要存储在2 MB的小块中。如果进程失败,则在文件较小的部分重试操作的情况下,我们也会受益。 如果未上传文件,则仅重试失败的块。

客户端和云存储之间较少的数据传输量将帮助我们获得更好的响应时间。不用发送整个文件,我们只需要发送文件的修改后的块。

当目标程序忙或未连接时,消息队列提供临时消息存储。它提供了异步通信协议。它 是一种将消息放入队列并且不需要立即响应即可继续处理的系统。RabbitMQ,Apache Kafka等是消息传递队列的一些示例。

如果是消息队列,则一旦客户端接收到消息,就会从队列中删除消息。因此,我们需要为客户端的每个订阅的设备创建几个响应队列。

★可扩展性

我们需要对元数据数据库进行分区,以便可以存储约100万用户和数十亿个文件/块的信息。我们可以对数据进行分区,以在服务器上分配读写请求。

元数据分区:

  1. 我们可以基于文件路径的首字母将文件块存储在分区中。例如,我们将所有以字母“ A”开头的文件保留在一个分区中,并将所有以字母“ B”开头的文件保留在另一个分区中,依此类推。这称为基于范围的分区。不太频繁出现的字母(例如“ Z”或“ Y”),我们可以将它们组合成一个分区。
    主要问题是,某些字母在首字母的情况下很常见。例如,如果我们将所有以字母“ A”开头的文件放入一个数据库分区中,而我们有太多以字母“ A”开头的文件,那么我们就无法将它们放入一个数据库分区中。
  2. 我们也可以基于文件’fileId’的哈希值进行分区。我们的哈希函数将随机生成一个服务器 ,并将文件存储在该服务器中。 但是我们可能需要要求所有服务器找到列表,然后将它们合并在一起以得到结果。因此,响应时间延迟可能会增加。
    如果我们使用这种方法,它仍然会导致分区过载,这可以通过使用“一致性哈希”来解决。

缓存:

众所周知,缓存是提高性能的常用技术。这对于降低延迟非常有帮助。服务器可以在访问数据库之前检查缓存服务器,以查看搜索列表是否已在缓存中。我们不能将所有数据都保存在缓存中。

当缓存已满时,我们需要用一个更新的块替换一个块。Least Recently Used(LRU)可以用于此系统。在这种方法中,首先从高速缓存中删除最近最少使用的块。

★安全性:

在文件共享服务中,用户数据的私密性和安全性至关重要。为了解决这个问题,我们可以将每个文件的权限存储在元数据数据库中,哪些文件可由哪个用户查看或修改。

★客户端:

客户端应用程序功能包括上传,下载文件。如上所述,我们将每个文件分成2MB的较小块,以便仅传输修改后的块,而不传输整个文件。

如果由于用户的离线状态而引起任何冲突,则应用需要对其进行处理。现在,我们可以在客户端保留元数据的本地副本,以使我们能够进行脱机更新。

客户端应用程序需要检测客户端文件夹中的文件是否已更改。我们可能有一个组件Watcher。它将检查客户端是否发生任何文件更改。

★客户如何知道云存储已完成更改h1>

客户端可以定期与服务器核对是否有任何更改,这是一项手动策略。但是,如果客户端经常检查服务器的更改,则会给服务器带来压力,使服务器繁忙。

我们可以使用HTTP 长时间轮询 技术。 在这种技术中,服务器不会立即响应客户端请求。服务器不发送空响应,而是使请求保持打开状态。 一旦准备好新信息,服务器就会向客户端发送响应。

★结论:

我们决定将文件分成较小的块,以节省存储空间,带宽使用并减少延迟。 我们添加了Loadbalancer,以在后端服务器之间平均分配传入请求。如果服务器停止工作了,则LB将停止向其发送任何请求。

在云架构中,用户数据的隐私和安全性至关重要。我们可以将每个文件的权限存储在元数据数据库中,以检查哪些文件对哪个用户可见或可以修改。

参见原文.

Charles @ Shenzhen,

2020-sep-23

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树使用JDBC操作数据库数据库操作92901 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年8月18日
下一篇 2020年8月18日

相关推荐