怎么简单设计一个文件上传系统?

关于文件上传系统有几个最主要的核心点需要解决:

  1. 如何支持超大文件上传

  2. 避免重复文件存储,节省空间

  3. 限流问题

大文件上传

假设有个 10 G 的文件需要上传,正常情况下是将文件转成流传到后端,如果不做任何处理,前端直传,后端存储这些流直到传递完成,后端非常容易内存溢出,多来几个人,后端的内存至少需要几十个 G ,一般的后端服务都没有这么大的内存。

并且一旦出现网络抖动或者其他情况,前端传输失败,前面传的都白费了。所以必须需要将大文件进行切割传输,即切块传输。

后端分别存储切割的小视频,不需要等待所有文件传输完成后合并存储,只需需下载的时候分块转成流给前端就好了

总结一下: 大文件需要前端分块传输给后端,后端分块存储,后面下载的时候,后端按序将分块文件给予前端即可。

避免存储重复文件

对于这点,很多同学都会想到用文件名判重,文件名相同的被识别为一个文件,这对于文件系统来他也上传了图片命说明显是不合理的,我拍个照命名为吴彦祖.png,假设吴彦祖也用我们的系统,名为吴彦祖.png。怎么说?彦祖上传后下载一看,照片上的人是我,不是他,哈哈哈。

那应该用什么方式呢?

有个叫哈希摘要的东西,也就是计算文件的 md5(或者其他 hash 算法),得到摘要,对比两个文件的摘要,如何摘要一致就可以认为是同一份文件。

摘要在文件场景非常常见,例如 jdk 的下载就会附上摘要,用来判别我们下载的文件是否被篡改,摘要一致则文件没有被篡改过。

限流问题

文件上传需要占用的资源挺多,内存、磁盘、带宽等等,所以需要做一定的限制。比如限制文件的最大值,防止恶意超大文件上传。

限制每天用户上传的次数、上传的频次间隔、上传的总文件大小量。

利用令牌桶或其他限流算法,限制同一时刻的上传用户数,防止后端压力过大和内存溢出问题监控后端内存,内存超过一定阈值后报警通知,灵活配置限流,保护后端系统安全。

切块以及存储简要流程

可以将文件每块切成 2m ,分块文件存储至服务器,分块记录存储到 redis 中

key 的设置可以是 userid + uuid( 标明这次的文件 )+ filename + seq( 顺序 )

之所以利用 redis 是因为性能高,其次可以设置过期时间,因为大文件上传存在传一半用户觉得太慢,取消上传,这时候之前上传的切块文件都应该被清理。

而 redis 可以自动过期 key ,后续监听到在这个 key 没了,就可以清理之前上传的无用切块文件节省空间。

每次切块上传,都可以利用md.update更新 md5 摘要( 固定大小不会因为大文件挤爆内存 ),等上传完毕就可以利用md.diqest 获取文件摘要,此时将 redis 的分块记录、切块文件数量、总大小、摘要等一切信息都落库即可。

上传文件的时候,前端将文件摘要信息传递至后端,后端从数据库查找是否有一致摘要,如果有则说明文件已存在,直接保存相关的信息,然后返回前端上传成功即可。

大致方案如何,面试中还是需要具体情况具体分析,每个面试官询问的角度都不同,如果你有实力,则投其所好,如果你有些地方比较强,则引导面试官询问你擅长的方向。

相关推荐
hqxstudying2 分钟前
Java异常处理
java·开发语言·安全·异常
我命由我123453 小时前
Kotlin 数据容器 - List(List 概述、创建 List、List 核心特性、List 元素访问、List 遍历)
java·开发语言·jvm·windows·java-ee·kotlin·list
武子康5 小时前
Java-80 深入浅出 RPC Dubbo 动态服务降级:从雪崩防护到配置中心秒级生效
java·分布式·后端·spring·微服务·rpc·dubbo
YuTaoShao8 小时前
【LeetCode 热题 100】131. 分割回文串——回溯
java·算法·leetcode·深度优先
源码_V_saaskw8 小时前
JAVA图文短视频交友+自营商城系统源码支持小程序+Android+IOS+H5
java·微信小程序·小程序·uni-app·音视频·交友
超浪的晨8 小时前
Java UDP 通信详解:从基础到实战,彻底掌握无连接网络编程
java·开发语言·后端·学习·个人开发
双力臂4049 小时前
Spring Boot 单元测试进阶:JUnit5 + Mock测试与切片测试实战及覆盖率报告生成
java·spring boot·后端·单元测试
Edingbrugh.南空9 小时前
Aerospike与Redis深度对比:从架构到性能的全方位解析
java·开发语言·spring
QQ_43766431410 小时前
C++11 右值引用 Lambda 表达式
java·开发语言·c++
永卿00110 小时前
设计模式-迭代器模式
java·设计模式·迭代器模式