MinIO 存储分片文件
- 极致的高性能,适配大文件分片的高并发读写,MinIO 采用单机多线程 + 分布式横向扩展架构,底层基于 Go 语言开发(无 GC 瓶颈)
- 原生支持 S3 协议,完美适配分片上传的标准流程,分片上传的核心流程(初始化分片→并行上传分片→校验分片→合并分片→断点续传)是对象存储的标准能力,而 MinIO100% 兼容 S3 协议,原生提供分片上传的全量 API,原生能力可以直接覆盖业务需求。
- 其他存储公有云对象存储 阿里云 OSS / 腾讯云 COS
- 查询 MinIO 中分片是否存在,这个查询部分最后返回来一个 StatObiectResponse 对象,如果不存在就返回报错。
// 用于与 MinIO 服务器交互
@Autowired
private MinioClient minioClient;
storagePath = "chunks/" + fileMd5 + "/" + chunkIndex;
//查询「uploads 存储桶」中「指定路径(storagePath)」的对象是否存在,并获取该对象的全量元数据(大小、修改时间、类型等)
StatObjectResponse stat = minioClient.statObject( //statObject:MinIO 客户端提供的核心方法,方法名直译是「统计对象」功能就是查询对象的状态 / 元数据
//是 MinIO SDK 中用于对象存在性检查、元数据获取的常用方法
StatObjectArgs.builder() //这是 MinIO SDK 采用的建造者模式(Builder Pattern) 实现
.bucket("uploads") //设置操作的存储桶名称为uploads,这是statObject的必选参数
.object(storagePath) //设置要查询的对象路径 / 名称为变量storagePath的值,这也是statObject的必选参数;
.build() //建造者模式的收尾方法
);
PutObjectArgs putObjectArgs = PutObjectArgs.builder()
.bucket("uploads")
.object(storagePath)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(file.getContentType())
.build();
minioClient.putObject(putObjectArgs);
MinIO 文件合并
合并流程
- 根据 userId 和 fileMd5 检查改合并请求是否有权限,也就是在 file_upload 表中是否有该记录,还有一层显示检查 userId ,双层检查
- 检查分片是否上传完整:要在 controller 先判断 是否分块 上传数量 < 实际数量,然后在 service 层检测是否 上传数量 == 预期数量。双层检测
- 合并文件
- 发送任务到 Kafka
- 流程:检查分片数量是否与预期一致 ,检查每个分片是否存在,合并分片,检查合并后的文件,清理分片文件,删除 Redis 中的分片状态记录,更新文件状态,生成预签名 URL(有效期为 1 小时)
- 检查分片数量:首先在主表 file_upload 中找到文件的大小,然后每个分块 5MB 计算应该有多少块,再从数据库 chunk_info 中根据 userId 和 file_MD5 查询成功上传了多少个分块