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

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

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

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

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

相关推荐
青云交2 小时前
Java 大视界 -- 基于 Java 的大数据机器学习模型在图像识别中的迁移学习与模型优化
java·大数据·迁移学习·图像识别·模型优化·deeplearning4j·机器学习模型
2501_909800812 小时前
Java 集合框架之 Set 接口
java·set接口
断剑zou天涯2 小时前
【算法笔记】暴力递归尝试
java·笔记·算法
Nobody_Cares3 小时前
JWT令牌
java
沐浴露z3 小时前
Kafka入门:基础架构讲解,安装与使用
java·分布式·kafka
神秘的土鸡3 小时前
从数据仓库到数据中台再到数据飞轮:我的数据技术成长之路
java·服务器·aigc·数据库架构·1024程序员节
vir023 小时前
P1928 外星密码(dfs)
java·数据结构·算法·深度优先·1024程序员节
摇滚侠4 小时前
全面掌握PostgreSQL关系型数据库,备份和恢复,笔记46和笔记47
java·数据库·笔记·postgresql·1024程序员节
eguid_15 小时前
【开源项目分享】JNSM1.2.0,支持批量管理的jar包安装成Windows服务可视化工具,基于Java实现的支持批量管理已经安装服务的可视化工具
java·开源·jar·1024程序员节·windows服务·jar包安装成服务·exe安装成服务
杯莫停丶5 小时前
设计模式之:享元模式
java·设计模式·享元模式