分享

MinIo最佳性能分片上传、断点续传方案(附带前后端Demo)

 lichwoo 2023-11-28 发布于北京

minio api 在对于大于5m的文件,自动采用了分片上传。

但它的分片上传我们无法得知上传的分片后的序号,也就是说,每上传一个分片,我们都需要自己去记录已上传分片的序号。

这将导致一个文件分片5个,那么同样还需要调用5次后端接口去记录这5个分片的信息。这无疑大大浪费了性能,且无法做到并发上传。

基于minio java api,我们可以用另外一种方案去替代。且上传流程不需要经过后端程序,直接让前端与minio服务打交道。

初步流程:
选择上传文件 -> 提取md5 -> 请求后端校验此md5的文件是否已经上传过 -> 如果有上传就返回信息告诉前端上传完成(秒传) -> 如果没有则根据此md5获取已上传的分片有哪些,未上传的分片有多少个就返回多少个上传url

如何获取已上传的分片有哪些呢?
minio api有一个生成上传url的api,这个api可以指定接下来要上传文件的文件名,也就是说,在上传步骤,我们只要保证上传的分片文件是有规则的,那么我们就可以很轻松的获取到

举个例子:上传文件的大小为10m,分片2个,md5为 abc123,则我们生成2个上传url,每个url指定的文件名为 md5/分片序号.part(分片文件要不要文件后缀都可以) 的格式,也就是 abc123/1.part;abc123/2.part

所有分片文件上传完成后,通过 listObjects 获取到 abc123 前缀开头的所有文件,即是所有分片文件的path,最后合并文件即可

为什么不所有步骤都采用前端直连Minio?毕竟官方的sdk也提供了前端的示例
这样做会直接暴露有关于minio的敏感信息,并且不管怎样,始终也需要后端去记录最终文件上传完成后的信息,所以一些敏感的操作,还是由后端程序来协助

这个流程的好处:

  1. 省掉每个分片的md5计算
  2. 省掉每上传一个分片文件就请求后端记录一次分片信息
  3. 省掉每个分片的数据库存储,合并文件后只需要删除分片文件,不需要再删除数据库数据
  4. 可以并发上传
  5. 文件上传直连于minio服务,不经过后端程序
  6. 分片文件更方便管理,比如分片文件上传到一个B桶里,合并的文件合并到A桶去
  7. 不暴露敏感信息

后端程序在整个流程里,仅仅充当了md5校验、生成url、通知minio合并文件的角色

本方案测试结果:

在这里插入图片描述
在这里插入图片描述
前后端Demo:https://download.csdn.net/download/anxyh_name/12821913


以上的方案如果在追求完美的基础上基本已经过时,最新的方案是继承MinioClient,覆写它的以下几个函数

createMultipartUpload //创建分片上传,返回uploadId
getPresignedObjectUrl //创建文件预上传地址
listParts //获取uploadId下的所有分片文件
completeMultipartUpload //合并分片文件

通过这个方案可以完成一个完全以minio为实现标准的分片上传,具体步骤:

1.前端调用后端createMultipartUpload获得uploadId(uploadId由minio生成)
2.前端计算分片数量,调用后端getPresignedObjectUrl获取相等数量的欲上传地址(前一步获取到的uploadId要绑定在这些上传地址的extraQueryParams属性里)
3.前端在所有分片上传完成后调用后端completeMultipartUpload合并文件(后端先通过listParts获取指定uploadId下所有的分片文件,然后以参数的形式调用completeMultipartUpload)

对比最上边的方案,说说这个方案解决了什么问题:
1.完全使用minio认可的分片上传方式,分片文件会被minio当临时文件存储(minio自己这么设计的),且是隐藏不可见的。(最上边的方案分片上传后,在控制台能够直接看到)
2.如果单纯只是想做分片上传,那么前端没必要去计算md5,如果要做断点续传、秒传等功能,还是需要md5,但是md5本身与minio没太大关系了,是跟你的业务有关。毕竟这需要你自己业务上去实现判断。
3.解决了评论中提到的合并文件太慢、合并文件后可能打不开、合并文件前需要自己排序分片的问题。(最上边的方案因为没有uploadId去关联分片文件,调用completeMultipartUpload时minio不会认为是你要合并的分片其实是一个大文件,所以采用的其他办法进行合并,比较慢)
4.解决了分片如果一直没有上传完成或者用户不上传了,需要自己想办法去手动清理分片的问题。这个方案minio自己会去处理。

之前有人告诉我,我之前写的demo被人拿去咸鱼卖钱了,所以这里就不贴demo了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多