招行面试:万亿GB网盘, 从0到1设计,如何实现?

简介: 本文由40岁老架构师尼恩撰写,针对一线互联网企业如得物、阿里、滴滴等的面试场景,特别是招商银行Java后端面试中的绝命12题,进行了深度解析。尼恩通过系统化、体系化的梳理,帮助读者提升技术肌肉,让面试官爱到“不能自已”。文章详细分析了如何设计一个支持万亿GB网盘实现秒传与限速的系统,涵盖了高并发处理、秒传实现、限速设计等核心技术挑战,并提供了完整的架构设计和代码示例。此外,还介绍了《尼恩Java面试宝典PDF》V171版本,帮助读者更好地准备面试。关注公众号【技术自由圈】,回复“领电子书”,获取更多资源。

本文原文链接

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,

最近有小伙伴面试招商银行,遇到下面的绝命 12题,狠狠被拷打了, 彻底懵了。 项目场景题太难了,不好好准备,真的答不出!

image.png

所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

当然,这些面试题 以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V171版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

最新《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请关注本公众号【技术自由圈】获取,回复:领电子书

绝命12题, 尼恩将给出全部的深度答案:

1.如何让系统抗住双十一的预约抢购活动?

16大绝招,完成10Wqps秒杀架构(3万字架构长文)

2.如何从零搭建10万级QPS大流量、高并发优惠券系统?

尼恩的 参考答案 , 点击查看 尼恩如何实现 1W + 的系统化、体系化作答

3.百万级别数据的 Excel 如何快速导入到数据?

尼恩的 参考答案 , 点击查看 如何实现 1W + 的系统化、体系化作答

4.如何设计一个支持万亿GB网盘实现秒传与限速的系统?

本文。

5.如何根据应用场景选择合适的消息中间件?

即将发布。

6.如何提升 RocketMQ 顺序消费性能?

即将发布。

7.使用分布式调度框架该考虑哪些问题?

即将发布。

9.如何让系统抗住双十一的预约抢购活动?

16大绝招,完成10Wqps秒杀架构(3万字架构长文)

10.问 : 如何解决高并发下的库存抢购超卖少买?

即将发布。

11.为什么高并发下数据写入不推荐关系数据?

即将发布。

12.如果让你设计一个分布式链路跟踪系统?

即将发布。

本文目录

前言

网盘的主要技术挑战是海量数据的高并发读写访问。

用户上传的海量数据如何存储?

如何避免部分用户频繁读写文件,消耗太多资源,而导致其他的用户体验不佳?

尼恩从0到1 ,设计一个 NetBoxApp 技术架构,看看尼恩 如何解决这些问题。

1、亿级网盘的功能模块设计

尼恩带大家设计一个 NetBoxApp,实现网盘(云盘)功能,提供文件托管、上传下载、断点续传服务。用户能通过它保管并共享照片、视频等。另外,由于 网盘 成本高,会对普通用户上传下载流速控制,让付费用户获更多网络资源。

首先对NetBoxApp 进行功能模块划分 ,遵循高内聚低耦合原则:

一、用户管理模块

(1)用户注册与登录

NetBoxApp 支持用户通过多种方式进行注册,包括但不限于邮箱注册、手机号注册、第三方平台(如微信、QQ、支付宝等)授权登录注册。

(2)用户信息管理:

NetBoxApp 允许用户修改个人信息,包括用户名、头像、联系方式、个性签名等,用户可根据自身需求更新个人信息,系统将更新后的信息存储在数据库中并更新用户信息展示界面。

二、文件上传

(1)文件上传选择

NetBoxApp 支持多种文件类型的上传,涵盖常见的文档(如 docx、pdf、txt)、图片(如 jpg、png、gif)、音频(如 mp3、wav)、视频(如 mp4、avi、mov)、压缩文件(如 zip、rar)等。

通过直观的文件选择界面,选择文件上传。

(2) 分段上传

NetBoxApp 实现大文件上传功能,对于较大的文件(如几 GB 甚至几十 GB 的文件),采用分片上传技术,将大文件分割成多个小的文件片段进行上传,提高上传的稳定性和效率。

NetBoxApp 提供文件上传进度条,向用户实时显示文件上传的进度,包括已上传部分的比例、已上传的数据量、预计剩余时间等信息,使用户能够直观了解上传状态。

(3) 断点续传上传

NetBoxApp 支持断点续传,当文件上传中断时,系统在服务器端记录已上传的文件片段信息,在用户恢复上传操作时,自动从断点处继续上传,避免用户重新上传整个文件,节省时间和网络资源。

三、文件管理

(1)文件目录管理

NetBoxApp 提供文件目录管理功能,用户可创建、删除、重命名文件夹,方便用户对文件进行分类存储。用户可以将文件拖放或移动到不同的文件夹中,系统更新文件的存储位置信息并更新数据库中文件的元数据。

(2)文件元数据管理

NetBoxApp 支持文件元数据存储,存储文件的名称、大小、类型、创建时间、修改时间、所有者等信息,以便用户查询和管理文件,同时也方便系统进行文件的检索和维护。

四、文件下载模块

(1)文件下载选择

NetBoxApp 支持用户从服务器端下载已存储的文件,用户可在文件列表中选择文件进行下载操作,系统将文件从存储节点传输到用户的本地设备。

(2)文件下载进度显示

NetBoxApp 实现文件下载进度显示,向用户展示下载进度信息,包括已下载部分的比例、下载速度、预计剩余时间等,方便用户掌握下载情况。

(3) 断点续传下载

NetBoxApp 具备断点续传功能,当文件下载因网络故障、设备故障或用户主动暂停而中断时,系统可在用户恢复下载操作时,从断点处继续下载,提高下载的效率和用户体验。

五、用户权限和服务控制模块

NetBoxApp 区分普通用户和付费用户,为不同类型的用户分配不同的权限。

(1)普通用户

NetBoxApp 普通用户拥有基础的文件存储、下载、共享等功能,但在存储容量、文件大小限制、下载速度等方面受到一定限制。

(1)付费用户

NetBoxApp 付费用户可根据不同的NetBoxApp 套餐等级,享受更高的存储容量、更大的文件上传和下载限制、更快的上传和下载速度等特权。系统根据用户的付费套餐信息,对用户的操作权限进行动态调整。

1.1 亿级网盘的 NetBoxApp 功能 用例图

尼恩为大家画了一个 亿级网盘的 NetBoxApp 功能 用例图分析图 , 大致如下:

image.png

2、亿级网盘NetBoxApp 非功能需求分析

2.1 总存储量的估算

一个亿的用户,每个用户平均100个文件, 100 亿个文件,每个文件平均10M ,约 多少GB ?

image.png

100亿个文件,每个文件平均10M,总大小约为97656250GB。 那么,是多少TB,多少PB?

image.png

2.2 高并发的估算

NetBoxApp 设计目标 支持 1 亿用户注册使用,免费用户最大可拥有 1TB 存储空间。

预计日活用户占总用户的 20%,即 2000 W用户。

按照尼恩的3高架构理论, 吞吐量为 2Wqps。

2.3 带宽的估算

2000 W用户,每个活跃用户平均每天上传、下载 4 个文件 假设 每次上传下载文件平均大小 100MB,

所以需要网络带宽负载 计算过程如下:

image.png

平均带宽负载为 763Gb/s。 这是一个多大的带宽规模。

2.4 高可靠存储的要求

NetBoxApp 设计目标 文件不丢失,持久存储可靠性达到 99.9999% 。

即 100 万个文件最多丢失(或损坏)1 个文件。

2.5 高可用的要求

NetBoxApp 设计目标 可用性在 99.99% 以上,即一年最多 53 分钟不可用。

最好是 99.999% 以上,即一年最多 5 分钟不可用。

尼恩架构团队,正在制作 超高可用 99.999% (5个9) 的方案和实操,非常牛逼的架构方案。

后面大家可以对照实操一下,然后写入简历, 这个绝对可以让北京、上海、深圳 的it圈 抖三抖

3、亿级网盘NetBoxApp概要设计

网盘设计的关键是元数据与文件内容的分离存储与管理

  • 文件元数据就是文件所有者、文件属性、访问控制这些文件的基础信息, 而 NetBoxApp 是将元信息存储在数据库中

  • 文件内容则使用另外专门的存储体系。

NetBoxApp 设计 成为 分布式微服务架构,通过元数据和文件内容的分离存储、API 服务器集群和数据块服务器集群的功能分离和解耦,确保系统的高并发性、高可用性和良好的用户体验。

3.1 客户端模块 设计:

  • 用户界面

提供用户与 NetBoxApp 交互的界面,用户可以在此界面上进行各种操作,包括登录、文件操作、文件共享等。该界面需要具备良好的用户体验,易于操作和导航,可能会根据不同设备(如电脑、手机等)有不同的显示和操作逻辑。

  • 文件上传客户端

负责从用户本地设备选择文件,并将文件发送到服务器端。在上传过程中,它要与 API 服务器集群中的文件操作 API 交互,启动文件上传操作。同时支持断点续传功能,当上传中断时,能够保存已上传进度,并在后续恢复上传时,从断点处继续上传。

  • 文件下载客户端

允许用户发起文件下载请求,通过文件操作 API 从服务器端获取文件。它要显示下载进度,并且在下载中断时,能够记录下载进度,后续通过断点续传服务继续下载文件。

  • 文件共享客户端

让用户可以将自己的文件共享给其他用户,包括生成共享链接、指定共享用户等操作。它会调用文件共享 API 完成文件共享操作,并在接收共享文件时,调用文件下载客户端进行文件下载。

3.2 API 服务器集群模块 设计 :

  • 用户认证与授权

对用户的登录信息进行验证,确保用户的身份合法。在用户登录、注册、修改密码等操作时,处理用户的身份信息,保证只有授权用户才能使用系统。它可能会与数据库中的文件元数据存储部分交互,验证用户信息的真实性,并发放访问令牌或会话信息,以便后续操作的权限验证。

  • 文件元数据管理 API

负责处理文件元数据的相关操作,包括文件的基本信息(如所有者、属性、创建时间等)的存储、更新、查询和删除。这些操作需要与数据库中的文件元数据存储部分进行交互,确保文件元数据的一致性和准确性。

  • 文件操作 API

接收用户的文件操作请求,如文件的上传、下载、重命名、删除等操作请求。它会协调文件传输服务和文件元数据管理 API,完成文件的整体操作流程,确保文件操作的有序性和数据一致性。

  • 用户管理 API

对用户的信息进行管理,如用户注册、用户信息修改、用户权限设置等。该部分会与数据库中的文件元数据存储部分进行交互,存储和更新用户的信息,同时会考虑用户的不同角色(如普通用户、付费用户),对不同用户的操作权限进行管理。

  • 文件共享 API

实现文件的共享功能,允许用户将文件共享给其他用户,同时管理共享的权限和范围。它需要和文件元数据管理 API 协作,更新文件的元数据,反映文件的共享状态,并在用户请求下载共享文件时,协调文件传输服务完成文件的传输。

3.3 数据块服务器集群模块设计 :

  • 文件传输服务

处理文件的实际传输过程,在用户发起文件上传或下载请求时,将文件在客户端和存储集群之间进行传输。它要保证文件传输的速度和稳定性,同时可能会根据用户类型(普通用户或付费用户)进行流速控制,为付费用户提供更优质的传输服务。

  • 文件断点续传服务

与文件存储和文件传输服务协作,在文件上传或下载中断时,记录文件的传输进度,当用户恢复操作时,能从断点处继续传输文件。

它要和文件存储与管理部分紧密协作,确保存储的文件片段的完整性和可恢复性。

3.4 数据库模块 设计:

  • 结构化数据库:存储文件元数据

存储文件的各种元数据信息,包括文件所有者、文件属性、访问控制信息等。

这些元数据对于文件的管理和操作至关重要,是文件操作的基础信息源。

在存储时,要保证元数据的完整性和可查询性,同时要支持文件元数据管理 API 的各种操作,包括添加、更新、删除和查询元数据信息。

  • 非结构化数据库:存储文件内容

非结构化数据库 主要负责文件内容的存储和管理,将文件存储在专门的存储体系中。

在接收文件时,要确保文件存储的可靠性和安全性,同时在用户请求文件时,能够准确地找到并提供相应的文件内容。

它可能会使用分布式存储技术,将文件存储在多个存储节点,以实现高可用性和可扩展性。

通过这样的架构和功能模块划分,NetBoxApp 可以实现文件托管、上传、下载、共享等核心功能,并通过元数据和文件内容的分离存储、API 服务器集群和数据块服务器集群的分离管理,确保系统的安全性、高可用性和良好的用户体验。如果你还有其他需求,比如细化某个模块的功能或添加新的模块,请随时告诉我

  • 文件存储与管理

主要负责文件内容的存储和管理,将文件存储在专门的存储体系中。在接收文件时,要确保文件存储的可靠性和安全性,同时在用户请求文件时,能够准确地找到并提供相应的文件内容。它可能会使用分布式存储技术,将文件存储在多个存储节点,以实现高可用性和可扩展性。

3.5 整体模块架构图

尼恩为大家画了一个 亿级网盘的 NetBoxApp 功能 模块架构图, 大致如下:

image.png

4、亿级网盘NetBoxApp核心流程设计

Transfer-Service 服务 负责 Block 上传和管理的。客户端应用程序根据 API-Service 服务器的返回指令,将文件切分成一些 Block,然后将这些 Block 分别发送给Transfer-Service服务器,Transfer-Service服务器再 调用分布式文件存储与管理器file-server集群,将 Block 存储在file-server 存储服务器中(NetBoxApp 选择 Ceph 作为file-server )。

4.1 文件上传流程设计

在文件上传过程中,首先,客户端应用程序会向 API-Service 服务器发起请求。API-Service 服务器会向客户端应用程序返回相应的指令,客户端应用程序依据此指令将需要上传的文件分割成多个 Block。

之后,客户端会将这些切分好的 Block 逐个发送至 Transfer-Service 服务器。Transfer-Service 服务承担着 Block 的上传和管理任务。

Transfer-Service 服务器收到 Block 后,会调用分布式文件存储与管理器,即 file-server 集群。

Transfer-Service 服务器会将这些 Block 存储到 file-server 存储服务器中,从而完成文件的存储过程。

在 NetBoxApp 中,选用了 Ceph 作为 file-server 。

具体的文件上传流程如下:

客户端应用程序

  • 负责与 API-Service 服务器进行交互,发送文件上传请求。
  • 根据 API-Service 服务器返回的指令,将文件切分成 Block。 客户端应用程序收集文件元数据,包括文件名、文件内容 MD5、文件大小等等,并根据文件大小计算 Block 的数量(NetBoxApp 设定每个 block 大小 4MB),以及每个 Block 的 MD5 值, 发送到API-Service 服务器
  • 客户端连接获取 Transfer-Service 列表后,连接 Transfer-Service 服务器,发送请求上传Block的请求 ,等待 Transfer-Service 的确认
  • Transfer-Service 的确认后, 客户端切分 Block, 是将切分后的 Block 发送给 Transfer-Service 服务器。

API-Service 服务器

  • 接收客户端的文件上传请求。
  • 向客户端应用程序返回文件切分指令,指导客户端如何将文件切分成 Block。
  • API 服务器收到文件元数据后,为每个 Block 分配全局唯一的 BlockID(BlockID 为严格递增的 64 位正整数,总可记录数据大小 ,足以满足 NetBoxApp的应用场景)。API 服务器将文件元数据与 BlockID 记录在数据库中,并将 BlockID 列表和应用程序可以连接的 Transfer-Service 服务器 列表返回客户端

Transfer-Service 服务器

  • Transfer-Service 服务端接收客户端发送的文件 Block的请求。Transfer-Service 服务器连接 API 服务器进行权限和文件元数据验证。验证通过后,给客户端发送响应
  • Transfer-Service 收到 客户端上传 的 Block 数据,Transfer-Service 服务器再次验证 Block 数据的 MD5 值,确认数据完整后,调用分布式文件存储与管理器 file-server 集群的接口 存储 Block数据, 将BlockID 和 Block 数据保存到对象存储集群 file-server 中
  • 接收 file-server 存储服务器的存储确认,并将存储确认信息反馈给客户端应用程序。

file-server 存储服务器集群

  • 负责存储 Transfer-Service 服务器发送过来的文件 Block。
  • 向 Transfer-Service 服务器返回存储确认信息,表明文件 Block 已存储成功。

4.2 文件上传流程的时序图:

尼恩为大家画了一个 亿级网盘的 NetBoxApp 用户上传文件的时序图 , 大致如下:

image.png

4.3 文件下载流程设计

文件下载功能流程描述:

客户端应用程序

  • 负责与 API-Service 服务器进行交互,发送文件下载请求。请求中包含所需下载文件的元数据信息,如文件名、文件id 等信息,以便 API-Service 服务器查找文件。
  • 接收 API-Service 服务器返回的文件的 BlockID 列表和对应的 Transfer-Service 服务器列表。
  • 依据 Transfer-Service 服务器列表,向 Transfer-Service 服务器发送下载 Block 的请求,等待 Transfer-Service 服务器的响应。
  • 接收 Transfer-Service 服务器发送的 Block 数据,将其组装成完整的文件,完成文件下载。

API-Service 服务器

  • 接收客户端的文件下载请求。
  • 根据客户端提供的文件元数据信息(如文件名、文件id 等信息) ,从数据库中查找文件对应的 BlockID 列表。
  • 将 BlockID 列表和相应的 Transfer-Service 服务器列表返回给客户端应用程序。

Transfer-Service 服务器

  • 接收客户端应用程序 的文件下载请求,包括 BlockID 列表。
  • 连接 API-Service 服务器进行文件权限和文件元数据验证,确保客户端有权限下载该文件。
  • 向 file-server 存储服务器集群发送获取 Block 数据的请求。
  • 接收 file-server 存储服务器集群返回的 Block 数据,并发送给客户端应用程序。

file-server 存储服务器集群

  • 接收 Transfer-Service 服务器的请求,根据 BlockID 查找并获取相应的 Block 数据。
  • 将查找到的 Block 数据发送给 Transfer-Service 服务器。

4.4 文件下载流程的时序图:

尼恩为大家画了一个 亿级网盘的 NetBoxApp 用户下载文件的时序图 , 大致如下:

image.png

5、亿级网盘NetBoxApp详细设计

5.1 NetBoxApp 的类和对象设计图如下:

尼恩为大家画了一个 亿级网盘的 NetBoxApp 类和对象设计图 , 大致如下:

image.png

5.2 Client 类:

Client 类表示使用 NetBoxApp 的客户端,包含客户端的基本信息(clientIdusername)。

Client 类具有与文件上传、下载相关的操作方法,以及处理响应和文件块数据的方法。

Client 类通过 setTransferServiceListsetAPIService 方法,可以与传输服务和 API 服务建立关联。

5.3 FileMetadata 类:

FileMetadata 存储文件的元数据信息,如文件标识符、名称、大小、所有者和创建日期等。

FileMetadata 包含一个块标识符列表,因为文件可能会被拆分成多个块存储。

FileMetadata 类的核心属性:

  • fileId: 文件的唯一标识符。
  • fileName: 文件名。
  • fileSize: 文件大小。
  • owner: 文件所有者。
  • creationDate: 文件创建日期。
  • blockIds: 存储该文件的块的标识符列表。
  • checksum: 文件的校验和。

5.4 Block 类:

Block 类表示文件的一部分,包含块标识符、数据内容和校验和。

Block 类提供了获取块信息和计算校验和的方法。

Block 类的核心属性:

  • blockId: 块的唯一标识符。
  • data: 块的数据内容。
  • size: 块的大小。
  • checksum: 块的校验和。

5.5 APIService 类:

APIService提供文件上传和下载的处理接口,同时负责文件元数据的存储和检索操作。

APIService与数据库和传输服务交互,以完成文件操作和元数据的管理。

5.6 TransferService 类:

TransferService处理文件块的上传和下载操作,包括验证客户端访问权限和存储、检索文件块。

TransferService与文件服务器和数据库协同工作,确保文件块的存储和检索操作的完成。

5.7 FileServer 类:

FileServer 负责文件块的实际存储和检索操作,存储位置由 storagePath 属性表示。

5.8 NetBoxApp 的类和对象详细设计图:

尼恩为大家画了一个 亿级网盘的 NetBoxApp 类和对象详细设计图 , 大致如下:

image.png

6、 亿级网盘NetBoxApp面临的主要技术挑战

实现这样一个大规模网盘系统,面临以下几方面的技术挑战:

万亿GB/100PB级别的大规模存储挑战:

如何管理万亿GB/100PB级别存储海量数据,以及确保这些数据的高可用和可靠性。

高并发访问

一个亿的用户,系统需要具备高2wqps并发处理能力。

秒传与去重:

如何快速判断文件是否已存在,并避免重复存储相同的文件。

普通用户限速:

根据用户 类型等因素设置灵活的限速策略。

数据一致性与安全性:

在多副本存储和分布式环境下,确保数据的一致性和传输的安全性。

7、 挑战1:万亿GB/100PB级别的大规模存储挑战

万亿GB/100PB级别数据存储的技术选型 , hdfs、 minio、 ceph

7.1 数据存储框架1:HDFS

HDFS 采用主从架构,由一个 NameNode 作为主节点和多个 DataNode 作为从节点组成。

文件被分割成固定大小的数据块,默认情况下在 Hadoop2.x 版本中数据块大小为 128MB,这些数据块会被存储在不同的 DataNode 上,并且每个数据块会有多个副本以保证数据的冗余和容错性。

HDFS优势

  • 1 高容错性

HDFS通过数据块的冗余存储,即使部分 DataNode 出现故障,也能保证数据的完整性和可用性,适合长期存储海量数据

  • 2 高吞吐量

HDFS 优化了大文件的存储和读取,能够高效地处理 TB 级甚至 PB 级的大规模数据,适用于批量数据处理的场景,如大数据分析等

  • 3 硬件要求低:

可以运行在普通的低成本硬件设备上,无需高端存储设备,能够有效降低大规模存储的硬件成本.

HDFS的不足

  • 1 元数据管理压力

NameNode 需要将文件系统的元数据存储在内存中,当存储大量小文件时,元数据的数量会剧增,导致内存压力过大,限制了系统可存储的文件总数3.

  • 2 不适合低延迟访问

HDFS 的设计主要是为了处理大规模的批量数据,数据的读写操作存在一定延迟,不适合对实时性要求较高的应用场景, 作为文件存储服务,HDFS不适合。

  • 3 不支持文件修改

文件一旦写入 HDFS,就只能在文件末尾追加数据,不支持随机写入或修改操作,对于需要频繁更新数据的应用场景不太适用

7.2 数据存储框架2:MinIO

MinIO 是专注于对象存储的轻量级分布式文件系统,采用水平扩展的架构,所有智能处理均在软件层实现,用户可灵活选择硬件。

MinIO 将元数据和数据存储在一起,并采用原子提交技术,避免了独立元数据数据库导致的性能瓶颈, 这个正好是HDFS 的短板

MinIO 优势

  • 高性能

针对性能进行了深度优化,MinIO 使用 SIMD 指令和并行 I/O 技术,实现高吞吐量和低延迟,能够很好地处理大文件和高并发请求,纠删码技术进一步提高了存储效率的同时提供了数据保护

  • 云原生支持
    MinIO 完全兼容 Amazon S3 API,支持 Kubernetes 原生操作器,可无缝集成到现代云原生生态中,

如与 Kubernetes、Prometheus 和 Grafana 等工具配合良好,也支持主流的大数据和 AI 工具,如 Spark 和 TensorFlow 等

  • 易用性高
    MinIO 提供简单易用的安装方式,无需复杂配置即可快速部署,并且配备直观的管理控制台,降低了初期运维成本,适合快速上线和动态负载需求的场景

  • 扩展性强

MinIO 支持水平扩展,可动态添加或移除节点,无需停机,能够适应从小规模部署到大规模企业级集群的需求,其架构能够灵活应对不同规模的数据存储需求

MinIO 劣势

对而言,MinIO 主要专注于对象存储,对于一些需要复杂存储类型(如块存储、文件存储等)支持的场景可能不如 Ceph 等多功能存储系统适用

对象存储和文件存储的区别:

  • 对象存储: 以对象(Object)为单位存储数据,每个对象包含数据本身以及相关的元数据(Metadata)。对象存储通常使用扁平化的结构,没有目录树的概念。
  • 文件存储:基于文件系统,数据以文件和目录(文件夹)的形式组织。文件存储通常有树状的目录结构。

7.3 数据存储框架3:Ceph

Ceph 是一种分布式对象存储系统,其核心组件包括 RADOS、CephFS、RBD 和 RGW 等。

  • RADOS 作为底层存储层,将数据分布在多个存储设备上实现高可用性;
  • CephFS 提供统一的文件系统接口;
  • RBD 提供虚拟块设备的存储抽象,可与虚拟化平台集成;
  • RGW 则将 Ceph 对象存储系统封装成标准对象存储接口,方便与外部交互.

Ceph整体的文件存储流程,主要分四层,File->Objects->PGs->OSDs, 具体如下图:

image.png

File: 要存储和访问的文件 ,这个是面向我们用户的,是我们直观操作的对象。

Object:这个object就是Ceph底层RADOS所看到的对象,也就是在Ceph中存储的基本单位了。object的大小由RADOS限定(通常为2m或者4m)。就跟HDFS抽象一个数据块一样,这里也是为了方便底层存储的组织管理。当File过大时,需要将File切分成大小统一的objects进行存储。

PG (Placement Group):PG是一个逻辑的概念,它的用途是对object的存储进行组织和位置的映射,通过它可以更好的分配数据和定位数据。

OSD (Object Storage Device): 它就是真正负责数据存取的服务。

PG和object是一对多的关系,一个PG里面组织若干个object,但是一个object只能被映射到一个PG中。

PG和OSD是多对多的关系,一个PG会映射到多个OSD上(大于等于2,此处即为副本机制),每个OSD也会承载大量的PG。

Ceph优势

  • 高度可扩展性:

可以根据需求进行水平扩展,用户能够根据存储需求增加新节点,实现存储容量和性能的线性增长,能够轻松应对海量数据的增长和高并发访问需求

  • 高度可靠性:

通过数据复制或编码等方式保证数据的可靠性和冗余,即使部分节点发生故障,数据依然可以正常访问,确保了数据的安全性和可用性

  • 多种存储方式支持:

支持对象、块和文件存储等多种存储类型,能够满足不同应用场景下的存储需求,如企业级存储、虚拟化环境存储等

Ceph 劣势

  • 部署和维护复杂

Ceph 的部署和维护需要一定的技术能力和经验,涉及多个子系统的配置和管理,如 OSD、Monitor、MDS 等,对运维团队的专业要求较高.

  • 性能优化难度大

由于其多功能性和复杂的架构,在大规模集群中性能优化的难度相对较大,需要对系统有深入的了解和专业的调优知识

7.4 Spring Boot集成Ceph对象存储

Swift是由Rackspace开发,用来为云计算提供可扩展存储的项目。

Swift 专注于 对象存储 , 并提供一套REST风格的Api来访问, 与Ceph强一致性不同, Swift 是最终一致性。

Swift 也是优秀的 开源项目 , 并无明显优劣之分,在使用场景上有所不同, 如果是专注于对象存储, 那么可以选择swift即可满足需要, 如果还有 块存储 要求, 那么选择Ceph更为合适。

这里选择Ceph + Swift api, 因为通过Ceph 网关可以适配兼容swift api, 同时在数据访问上具有较强的扩展性。

在本教程中,我将向你展示如何在Spring Boot应用程序中集成Ceph对象存储Swift模式。这将帮助你更好地管理和存储大量数据,提高应用的性能和可扩展性。

流程概览

下面是通过 Swift api,集成 Spring Boot集成Ceph对象存储的 流程 步骤:

步骤 描述
1. 配置Ceph对象存储
2. 添加Swift模块依赖
3. 创建Ceph Swift配置类
4. 实现上传和下载功能

步骤详解

  1. 配置Ceph对象存储

首先, 需要在Ceph中创建一个Bucket,并获取Access Key和Secret Key,以便后续Spring Boot应用程序连接到Ceph对象存储。

  1. 添加Swift模块依赖

在Spring Boot项目的pom.xml文件中添加Ceph Swift模块的依赖:

<dependency>
    <groupId>org.javaswift</groupId>
    <artifactId>java-cloud-swift</artifactId>
    <version>4.0.0</version>
</dependency>

3. 创建Ceph Swift配置类

创建一个名为CephSwiftConfig的配置类,用于配置连接到Ceph Swift对象存储的相关信息:

@Configuration
public class CephSwiftConfig {
   

    @Value("${ceph.swift.authUrl}")
    private String authUrl;

    @Value("${ceph.swift.tenantName}")
    private String tenantName;

    @Value("${ceph.swift.userName}")
    private String userName;

    @Value("${ceph.swift.password}")
    private String password;

    @Bean
    public Swift getSwift() {
   
        return new Swift(authUrl, tenantName, userName, password);
    }
}

4. 实现上传和下载功能

在 Service或Controller中实现上传和下载功能的代码,如下所示:

@Autowired
private Swift swift;

public void uploadFile(String bucketName, String key, File file) {
   
    SwiftObject swiftObject = swift.newStaticObject();
    swiftObject.setTempFile(file);
    swift.uploadObject(bucketName, swiftObject);
}

public File downloadFile(String bucketName, String key) {
   
    SwiftObject swiftObject = swift.getObject(bucketName, key);
    return swiftObject.downloadObjectAsFile();
}

8、 挑战2: 2Wqps 高并发访问

NetBoxApp 设计目标 支持 1 亿用户注册使用,免费用户最大可拥有 1TB 存储空间。

预计日活用户占总用户的 20%,即 2000 W用户。

按照尼恩的3高架构理论, 吞吐量为 2Wqps。

这里的方案比较复杂, 具体可以参考尼恩的三级缓存架构视频。

9、 挑战3:如何实现秒传?

秒传功能,即快速上传文件功能, 旨在提高用户在网盘上传文件的速度,同时减轻网盘存储负载及避免用户网络带宽浪费和长时间等待。

在网盘存储中,存在大量如电影、电子书等内容重复的文件,若重复上传会产生诸多问题。

为此,NetBoxApp 在设计上对于物理相同的文件仅保存一份。当用户上传文件时,NetBoxApp 会先在客户端计算文件的 MD5 值,之后依据该 MD5 值检查文件是否已存在于存储中。

若已存在,仅需建立用户文件与该物理文件的关联,无需用户实际上传文件,由此实现秒传。

然而,此设计存在潜在风险。

因为, MD5 算法可能出现哈希冲突,不同文件计算出的 MD5 值可能相同,这会引发 NetBoxApp 误判,带来诸多不良后果, 即上传与目标文件 MD5 值相同的文件后可下载目标文件,影响系统的安全性和用户数据的完整性。

如何解决 碰撞风险呢? 可以引入SHA-256或其他方式进行更严格的文件完整性校验。

尼恩为大家画了一个 亿级网盘的 NetBoxApp 如何实现秒传设计图 , 大致如下:

image.png

9.1 通过 SHA-256 判断文件是否存在?

秒传的核心在于判定用户上传的文件是否已经存在于系统中。

在用户上传文件时,首先计算文件的SHA-256 值,因为 SHA-256 算法 能够高效地生成文件的唯一标识。后面NetBoxApp 根据上传文件的SHA-256 值,查询是否已存在同样的文件。

import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class HashCalculator {
   
    // 计算文件的 SHA-256 哈希值
    public static String calculateFileHash(String filePath) {
   
        try (FileInputStream fis = new FileInputStream(filePath)) {
   
            // 获取 SHA-256 算法的 MessageDigest 实例
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            // 定义一个字节数组作为缓冲区,用于读取文件数据,这里设置为 8192 字节,可根据需要调整大小
            byte[] buffer = new byte[8192];
            int bytesRead;
            // 循环读取文件内容,直到文件结束
            while ((bytesRead = fis.read(buffer))!= -1) {
   
                // 将读取的文件数据更新到 MessageDigest 中,每次更新一部分数据
                md.update(buffer, 0, bytesRead);
            }
            // 完成哈希计算,生成最终的哈希值,结果是字节数组
            byte[] digest = md.digest();
            StringBuilder sb = new StringBuilder();
            // 将字节数组形式的哈希结果转换为十六进制字符串表示
            for (byte b : digest) {
   
                // 将每个字节转换为两位十六进制字符串并添加到 StringBuilder 中
                sb.append(String.format("%02x", b));
            }
            // 返回十六进制字符串形式的哈希值
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
   
            // 处理不支持的算法异常,打印异常信息
            System.err.println("不支持的哈希算法: " + e.getMessage());
            return null;
        } catch (IOException e) {
   
            // 处理文件读取异常,打印异常信息
            System.err.println("文件读取异常: " + e.getMessage());
            return null;
        }
    }

    // 校验文件的完整性,比较两个文件的 SHA-256 哈希值是否相等
    public static boolean verifyFileIntegrity(String filePath1, String filePath2) {
   
        String hash1 = calculateFileHash(filePath1);
        String hash2 = calculateFileHash(filePath2);
        // 比较两个文件的哈希值是否相等
        return hash1!= null && hash2!= null && hash1.equals(hash2);
    }

    public static void main(String[] args) {
   
        // 要校验完整性的第一个文件路径,请替换为实际文件路径
        String filePath1 = "path/to/file1.txt";
        // 要校验完整性的第二个文件路径,请替换为实际文件路径
        String filePath2 = "path/to/file2.txt";
        // 调用 verifyFileIntegrity 方法校验文件完整性
        boolean isIntegral = verifyFileIntegrity(filePath1, filePath2);
        if (isIntegral) {
   
            // 输出文件完整性校验结果
            System.out.println("文件完整性校验通过");
        } else {
   
            System.out.println("文件完整性校验失败");
        }
    }
}

9.2 实现秒传 的执行流程

step1:客户端发起上传请求:

用户通过 NetBoxApp 的客户端 向 API服务发起文件上传请求。

这一步, NetBoxApp 调用 HashCalculator 组件,使用 SHA-256 算法计算文件的哈希值。

step2: 存储查询
NetBoxApp 将计算得到的哈希值发送API服务, API服务通过 DataSource 进行查询,看是否存在相同哈希值的文件。

step3:内容比对(仅在哈希值相同的情况下)

如果API服务通过 DataSource 进行查询后,查询到存在相同哈希值的文件,并且通过RPC 从 TransferService 查询部分内容,API服务 返回部分内容给 NetBoxApp

NetBoxApp 调用 ContentChecker 组件,对新文件和存储中的文件进行部分内容的比对。

API服务 可以随机选取文件的多个部分,如文件开头、中间和结尾部分进行比对,以确保文件内容一致。

step4:存储或映射建立

如果内容比对结果显示文件相同,仅建立用户文件和物理文件的映射关系,实现秒传。

如果内容不同或存储中不存在相同哈希值的文件,与TransferService服务 传输数据,TransferService服务 将文件存储到 FileServerCluster 中,并建立用户文件和新存储文件的映射关系。

9.3 实现秒传 的执行流程 uml 图

尼恩为大家画了一个 亿级网盘的 NetBoxApp 如何实现秒传详细设计图 , 大致如下:

image.png

10、 挑战4:如何 限速设计方案?

首先,NetBoxApp 需要根据用户的付费类型和使用情况对用户进行限速。

通常有以下几种用户类型:

  • 免费用户:对上传和下载速度进行严格限制,以降低系统负担。
  • 付费用户:根据付费等级提供不同的上传和下载速度。

NetBoxApp 根据用户付费类型决定用户的上传、下载速度。而要控制上传、下载速度,可以通过限制并发 Block 服务器数目,以及限制TransferService 内的线程数来实现。

具体过程是,客户端程序访问 API 服务器,请求上传、下载文件的时候,API 服务器可以根据用户类型,决定分配的 TransferService数目和TransferService内的服务线程数,以及每个线程的上传、下载速率。

TransferService会根据 API 服务器的返回值,来控制客户端能够同时上传、下载的 Block 数量以及传输速率,以此对不同用户进行限速。

10.1 实现限速 的执行流程设计

尼恩为大家画了一个 亿级网盘的 NetBoxApp 如何实现限速详细设计图 , 大致如下:

image.png

时序图总结

  • 该时序图涉及四个主要参与者:用户(User)、客户端程序(Client)、API 服务器(API_Server)和传输服务(TransferService)。
  • 首先,用户通过客户端程序发起文件的上传或下载请求。
  • 客户端程序将该请求发送给 API 服务器。
  • API 服务器会根据用户的付费类型进行判断,如区分免费用户和付费用户,对于不同类型的用户确定不同的限速策略,此策略涉及到对 TransferService 数目的分配、服务线程数以及每个线程的上传和下载速率的设定。
  • API 服务器将确定好的限速信息反馈给客户端程序。
  • 客户端程序将这些限速信息传递给传输服务。
  • 传输服务根据收到的限速信息,控制同时上传或下载的 Block 数量和传输速率。
  • 最终传输服务执行文件传输操作,完成文件传输后,将结果反馈给客户端程序,客户端程序再将结果反馈给用户。

10.2 Block服务器的并发与传输控制

TransferService接收API服务器的请求后,需要进行传输速率控制,根据用户等级和当前的网络情况来动态调整传输速率。

下面是一个参考的 带有速度限制 传输文件的方法 transferFileWithRateLimit方法。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileTransferWithSpeedLimit {
   

    // 传输文件的方法,带有速度限制
    public static void transferFileWithRateLimit(String sourcePath, String destinationPath, long speedLimitBytesPerSecond) throws IOException, InterruptedException {
   
        // 创建文件输入流,从源文件读取数据
        try (InputStream inputStream = new FileInputStream(sourcePath);
             // 创建文件输出流,将数据写入目标文件
             OutputStream outputStream = new FileOutputStream(destinationPath)) {
   

            byte[] buffer = new byte[8192]; // 定义一个 8KB 的缓冲区
            long startTime = System.currentTimeMillis(); // 记录开始时间
            int bytesRead;
            long bytesTransferred = 0; // 已传输的字节数

            while ((bytesRead = inputStream.read(buffer))!= -1) {
   
                // 将数据写入目标文件
                outputStream.write(buffer, 0, bytesRead);
                bytesTransferred += bytesRead;

                // 计算已传输的时间
                long elapsedTime = System.currentTimeMillis() - startTime;

                // 如果传输速度超过限制,暂停一段时间
                if (bytesTransferred > speedLimitBytesPerSecond * (elapsedTime / 1000)) {
   
                    long sleepTime = (bytesTransferred / speedLimitBytesPerSecond) * 1000 - elapsedTime;
                    if (sleepTime > 0) {
   
                        // 暂停线程,以实现限速
                        Thread.sleep(sleepTime);
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
   
        try {
   
            // 源文件路径
            String sourcePath = "path/to/source/file";
            // 目标文件路径
            String destinationPath = "path/to/destination/file";
            // 每秒限制传输 100KB
            long speedLimitBytesPerSecond = 102400;
            // 调用文件传输方法
            transferFileWithRateLimit(sourcePath, destinationPath, speedLimitBytesPerSecond);
        } catch (IOException | InterruptedException e) {
   
            e.printStackTrace();
        }
    }
}

11、 挑战5:5个9 高可用的要求

NetBoxApp 设计目标 可用性在 99.99% 以上,即一年最多 53 分钟不可用。

最好是 99.999% 以上,即一年最多 5 分钟不可用。

尼恩架构团队,正在制作 超高可用 99.999% 的方案和实操视频,这个非常牛逼,非常漂亮。

后面大家可以对照实操一下,然后写入简历, 这个 可以让北京、上海、深圳 的 it圈 抖三抖

12、 其他的挑战

万亿GB/100PB级别的 网盘系统的挑战,非常的多

大家在做架构的过程中,如果遇到了问题,可以 来尼恩的 架构师 社群 交流。

说在最后:有问题找老架构取经‍

回到开始的时候的面试题:招商银行的Java后端面试真题

被狠狠拷打了,问的人都懵了。 项目场景题太难了,不好好准备,真的答不出!

image.png

按照尼恩的参考答案回答,一定会 吊打面试官,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,里边有大量的大厂真题、面试难题、架构难题。

很多小伙伴刷完后, 吊打面试官, 大厂横着走。

在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

另外,如果没有面试机会,可以找尼恩来改简历、做帮扶。前段时间,刚刚指导 一个2年经验小伙,拿到 年薪60W的 天价年薪 ,3大 offer, 实现了一本 吊打 985、211

狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由” 。

尼恩技术圣经系列PDF

……完整版尼恩技术圣经PDF集群,请找尼恩领取

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》PDF,请到下面公号【技术自由圈】取↓↓↓

相关文章
|
3天前
|
弹性计算 人工智能 安全
对话 | ECS如何构筑企业上云的第一道安全防线
随着中小企业加速上云,数据泄露、网络攻击等安全威胁日益严重。阿里云推出深度访谈栏目,汇聚产品技术专家,探讨云上安全问题及应对策略。首期节目聚焦ECS安全性,提出三道防线:数据安全、网络安全和身份认证与权限管理,确保用户在云端的数据主权和业务稳定。此外,阿里云还推出了“ECS 99套餐”,以高性价比提供全面的安全保障,帮助中小企业安全上云。
对话 | ECS如何构筑企业上云的第一道安全防线
|
11天前
|
调度 云计算 芯片
云超算技术跃进,阿里云牵头制定我国首个云超算国家标准
近日,由阿里云联合中国电子技术标准化研究院主导制定的首个云超算国家标准已完成报批,不久后将正式批准发布。标准规定了云超算服务涉及的云计算基础资源、资源管理、运行和调度等方面的技术要求,为云超算服务产品的设计、实现、应用和选型提供指导,为云超算在HPC应用和用户的大范围采用奠定了基础。
179614 22
|
20天前
|
人工智能 自然语言处理 前端开发
从0开始打造一款APP:前端+搭建本机服务,定制暖冬卫衣先到先得
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。
9592 28
|
6天前
|
机器学习/深度学习 分布式计算 供应链
阿里云先知安全沙龙(上海站) ——大模型基础设施安全攻防
大模型基础设施的安全攻防体系涵盖恶意输入防御和基础设施安全,包括框架、三方库、插件、平台、模型和系统安全。关键漏洞如CVE-2023-6019(Ray框架命令注入)、CVE-2024-5480(PyTorch分布式RPC)及llama.cpp中的多个漏洞,强调了代码安全性的重要性。模型文件安全方面,需防范pickle反序列化等风险,建议使用Safetensors格式。相关实践包括构建供应链漏洞库、智能化漏洞分析和深度检测,确保全方位防护。
|
4天前
|
存储 缓存 运维
阿里云先知安全沙龙(上海站)——后渗透阶段主机关键信息自动化狩猎的实现与应用
本文介绍了在后渗透测试中使用LSTAR工具和PowerShell脚本进行RDP状态查询、端口获取及凭据收集的过程,强调了高强度实战场景下的OPSEC需求。通过MITRE ATT&CK框架的应用,详细阐述了凭证访问、发现和收集等关键技术,确保攻击者能够隐蔽、持续且高效地渗透目标系统,最终获取核心数据或控制权。文中还展示了SharpHunter等工具的自动化实现,进一步提升了操作的安全性和效率。
|
4天前
|
机器学习/深度学习 人工智能 安全
通义视觉推理大模型QVQ-72B-preview重磅上线
Qwen团队推出了新成员QVQ-72B-preview,这是一个专注于提升视觉推理能力的实验性研究模型。提升了视觉表示的效率和准确性。它在多模态评测集如MMMU、MathVista和MathVision上表现出色,尤其在数学推理任务中取得了显著进步。尽管如此,该模型仍存在一些局限性,仍在学习和完善中。
|
24天前
|
Cloud Native Apache 流计算
资料合集|Flink Forward Asia 2024 上海站
Apache Flink 年度技术盛会聚焦“回顾过去,展望未来”,涵盖流式湖仓、流批一体、Data+AI 等八大核心议题,近百家厂商参与,深入探讨前沿技术发展。小松鼠为大家整理了 FFA 2024 演讲 PPT ,可在线阅读和下载。
5185 15
资料合集|Flink Forward Asia 2024 上海站
|
1月前
|
人工智能 自动驾驶 大数据
预告 | 阿里云邀您参加2024中国生成式AI大会上海站,马上报名
大会以“智能跃进 创造无限”为主题,设置主会场峰会、分会场研讨会及展览区,聚焦大模型、AI Infra等热点议题。阿里云智算集群产品解决方案负责人丛培岩将出席并发表《高性能智算集群设计思考与实践》主题演讲。观众报名现已开放。
|
16天前
|
Docker 容器
|
5天前
|
监控 NoSQL Java
若依RuoYi项目环境搭建教程(RuoYi-Vue + RuoYi-Vue3版本)
若依(RuoYi)是一款基于Spring Boot和Vue.js的开源Java快速开发脚手架,支持OAuth2、JWT鉴权,集成多种安全框架和持久化框架。它提供了系统管理、监控管理、任务调度、代码生成等常用功能模块,适合中小型公司快速搭建Web应用。本文主要介绍若依框架的特点、版本发展、优缺点及项目部署步骤,帮助开发者快速上手并部署若依项目。
若依RuoYi项目环境搭建教程(RuoYi-Vue + RuoYi-Vue3版本)