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

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

  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 的分块记录、切块文件数量、总大小、摘要等一切信息都落库即可。

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

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

相关推荐
JAVA面经实录9175 小时前
Java企业级工程化·终极完整版背诵手册(无遗漏、全覆盖、面试+落地通用)
java·开发语言·面试
许彰午7 小时前
CacheSQL(二):主从复制——OpLog 环形缓冲区与故障自动恢复
java·数据库·缓存
Bat U8 小时前
JavaEE|多线程初阶(七)
java·开发语言
掌心向暖RPA自动化10 小时前
如何获取网页某个元素在屏幕可见部分的中心坐标影刀RPA懒加载坐标定位技巧
java·javascript·自动化·rpa·影刀rpa
日取其半万世不竭10 小时前
Minecraft Java版社区服务器搭建教程(Linux,适合新手)
java·linux·服务器
TeamDev11 小时前
JxBrowser 9.0.0 版本发布啦!
java·前端·混合应用·jxbrowser·浏览器控件·跨平台渲染·原声输入
AI人工智能+电脑小能手11 小时前
【大白话说Java面试题】【Java基础篇】第24题:Java面向对象有哪些特征
java·开发语言·后端·面试
AI人工智能+电脑小能手12 小时前
【大白话说Java面试题】【Java基础篇】第25题:JDK1.8的新特性有哪些
java·开发语言·后端·面试
likerhood12 小时前
SLF4J: Failed to load class “StaticLoggerBinder“ 解决
java·log4j·maven
早日退休!!!12 小时前
大模型推理瓶颈七层分析模型
java·服务器·数据库