MinIO 分片上传

news2024/12/24 2:31:28

文章目录

  • 1.MinIO 简介
  • 2.为什么要分片上传?
  • 3.实现思路
  • 4.具体实现
    • 初始化客户端
    • 获取分片上传的预签名 URL
    • 合并分片
    • 中止合并
  • 5.FAQ
    • 端口错误
    • 协议错误
  • 参考文献

1.MinIO 简介

MinIO 是适用于 AI 的高性能对象存储系统。

MinIO 简单易用。简单性是 EB 级数据基础设施的基础 - 无论是在技术上还是在操作上。MinIO 使用和部署非常简单,没有其他对象存储可以让您在最快的时间内实现下载到生产环境的部署。

MinIO 提供高性能、与 AWS S3 兼容的对象存储系统,让你自己能够构建自己的云储存服务。

MinIO 原生支持 Kubernetes,它可用于每个独立的公共云、每个 Kubernetes 发行版、私有云和边缘的对象存储套件。

MinIO 是软件定义的,不需要购买其他任何硬件,在 GNU AGPL v3 下是 100% 开源的。

2.为什么要分片上传?

如果一个待上传的对象非常大,直接上传大文件会面临如下问题:

  • 单线程上传速度慢,效率低。
  • 如果发生网络抖动、程序崩溃等异常情况,导致上传过程中断,那么需要从头开始上传。
  • 无法暂停,因为一旦中止,需要从头开始上传。

将大文件分片,然后逐片上传,可以进行多线程并发上传,提高吞吐量。

如果因为某些异常情况导致部分分片上传失败,那么其他已经上的传分片则无须重复上传,可以做到断点续传。

使用分片上传,可以暂停和恢复对象上传。

所以在上传大文件对象时,我们应该使用分片上传。

3.实现思路

实现大文件分片上传时,大体思路如下:

  1. 数据库中存放文件路径,所有文件保存在 MinIO 中,文件名即是文件的 MD5。
  2. 当用户上传文件时,首先判断该文件信息是否存在数据库中,如果存在则直接显示上传成功,若不存在则执行上传操作。
  3. 文件在真正上传之前先判断文件大小,太小的不需要创建分片上传任务,一次性上传即可。
  4. 后台调用 MinIO 的 API 创建分片上传任务(得到一个上传 ID ),并为该任务生成分片上传的预签名链接(上传地址列表)后返回给客户端,客户端将对应分片按照到对应的连接传递到 MinIO 中。
  5. 分片上传成功后更新进度信息。
  6. 所有分片上传结束后,通知后台,调用 MinIO 的 API 将当前任务的分片合并形成完整文件。

先不考虑小文件一次性上传的情况。对于大文件分片上传,三个关键步骤是:

  1. 创建分片上传任务,获取上传 ID。
  2. 生成分片上传预签名链接。
  3. 合并分片。

这三个操作均是由后台服务与 MinIO 交互。

分片上传则是客户端拿到分片上传预签名链接后,由客户端通过预签名链接与 MinIO 交互,将分片上传至 MinIO。

具体的上传交互方式如下图所示:

在这里插入图片描述

这里说一下上传 ID 与预签名链接的作用。

上传 ID 是分片上传的唯一标识符。无论您何时上传分段、列出分段、完成上传或停止上传,都必须包括此上传 ID。

默认情况下,所有对象和桶都是私有的。但是,我们可以使用预签名 URL 选择性地共享对象,或者允许用户通过预签名 URL 将对象上传到桶,而无需安全凭证或权限。考虑到安全性,一般情况下,预签名 URL 有有效期,在达到过期时间后会过期失效。

4.具体实现

这里以 MinIO 的 Go Client SDK minio-go 为例,介绍分片上传,后台服务需要完成的相关操作。

初始化客户端

首先下载 minio-go。

go get github.com/minio/minio-go/v7

MinIO 客户端需要指定以下 4 个参数才能接入 Amazon S3 兼容的对象存储。

// MinIO 地址。
endpoint := "play.min.io"
// 用户 ID。
keyID := "Q3AM3UQ867SPQQA43P2F"
// 用户密码。
accessKey := "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG"
// 是否使用 HTTPS。
useSSL := true

下面是一个初始化示例:

import "github.com/minio/minio-go/v7"

var MinIOClt *minio.Core

func init() {
	endpoint := "10.0.0.1:9000"
	keyID := "admin"
	accessKey := "admin"
	useSSL := false // 不使用 HTTPS

	// Initialize minio client object.
	var err error
	MinIOClt, err = minio.NewCore(endpoint, &minio.Options{
		Creds:  credentials.NewStaticV4(keyID, accessKey, ""),
		Secure: useSSL,
	})
	if err != nil {
		log.Fatalln(err)
	}
	log.Printf("%#v\n", MinIOClt) // minioClient is now set up
}

这里没有使用 minio.Client 而是使用了 minio.Core。因为 minio.Core 暴露了更加底层的 S3 API,而这些 API 刚好是分片上传需要的。

获取分片上传的预签名 URL

后台需要根据客户端欲上传文件的总大小和分片大小计算出总的分片数,然后向 MinIO 获取每个分片上传的预签名 URL。

这里要注意,关于分片大小的确定,MinIO 规定分片大小范围是 5 MiB to 5 GiB,这也是 S3 API 的限制。详见 Thresholds and Limits。

在获取分片上传的预签名 URL 之前,需要创建一个 upload ID。在 minio-go 中,利用 minio.Core 的方法 NewMultipartUpload 可以创建 upload ID。

// NewMultipartUpload - Initiates new multipart upload and returns the new uploadID.
func (c Core) NewMultipartUpload(ctx context.Context, bucket, object string, opts PutObjectOptions) (uploadID string, err error)

在拿到 upload ID 后,需要为每个分片生成上传的预签名 URL,使用 minio.Client 方法 Presign 完成。

// Presign - returns a presigned URL for any http method of your choice along
// with custom request params and extra signed headers. URL can have a maximum
// expiry of upto 7days or a minimum of 1sec.
func (c *Client) Presign(ctx context.Context, method string, bucketName string, objectName string, expires time.Duration, reqParams url.Values) (u *url.URL, err error)

每个预签名链接的 Query,需要携带 upload ID 和 part Number。

part Number 是每个分片的唯一编号,取值范围是 1 至 10,000。part Number 可以不连续,但要唯一。

params := url.Values{
			"uploadId":   []string{uploadID},
			"partNumber": []string{strconv.Itoa(partNum)},
		}

合并分片

当客户端完通过预签名 URL 将所有分片上传完成后,通知后台服务。然后后台再调用 MinIO 的 API Core.CompleteMultipartUpload,将分片合并成最终的对象。

// CompleteMultipartUpload - Concatenate uploaded parts and commit to an object.
func (c Core) CompleteMultipartUpload(ctx context.Context, bucket, object, uploadID string, parts []CompletePart, opts PutObjectOptions) (UploadInfo, error) 

注意,传入所有分片的 part Number 时,需要对其进行升序排序,不然会报 InvalidPartOrder 错误。详见 S3 CompleteMultipartUpload。

中止合并

如果想中途取消对象的上传,那么需要通知 MinIO 将分片进行清理。

使用到的 API 是 Core.AbortMultipartUpload 方法。

// AbortMultipartUpload - Abort an incomplete upload.
func (c Core) AbortMultipartUpload(ctx context.Context, bucket, object, uploadID string) error

5.FAQ

端口错误

访问 MinIO API 报了如下错误。

S3 API Request made to Console port. S3 Requests should be sent to API port.

原因是使用了错误的 API 端口。提示内容是将 API 的请求发送到了控制台端口。检查一了一下,我确实在初始化 SQLite client 时,使用了控制台 Web UI 的端口。MinIO 的 API 端口缺省是 9000,一般换成 9000 即可。

协议错误

访问 MinIO API 报了如下错误。

Get XXX: http: server gave HTTP response to HTTPS client

其中 XXX 为 URL 表示的资源。

MinIO 部署默认以 HTTP 方式对外提供服务,如果在初始化客户端时使用了 HTTPS,那么就会报上面的错误。将初始化客户端传入的参数 minio.Options 的 Secure 字段置为 false 即可。


参考文献

MinIO
github.com/minio/minio-go
Uploading and copying objects using multipart upload - AmazonS3 userguide
Using presigned URLs - AmazonS3 userguide
Minio入门系列【19】断点续传和断点下载实现方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/617228.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宝塔配置MySQL队列调度 | ModStart

执行以下操作前提前进入网站根目录,如 cd /www/wwwroot/xxx.com执行 artisan 命令前请参照 开发教程 → 开发使用常见问题 → 如何运行 /www/server/php/xxx/bin/php artisan xxx 命令 ① 生成数据库队列表迁移文件 在执行该步骤前,请先检查迁移文件 da…

【CSS 05】文本颜色 文本对齐 文字装饰 文本转换 文字间距 文本阴影 字体 字体样式 字体大小 谷歌字体

CSS 说在前面文本 text文本对齐 text-align文字装饰 text-decoration文本转换 text-transform文字间距 text_spacing文本阴影 text-shadow字体 font字体样式 font-style字体大小 font-size谷歌字体简写属性 shorthand 说在前面 事实证明,Zoro只要出现在标题就会被识…

go-GUI开发:fyne解决中文乱码+注册windows服务

go-GUI框架:fyne教程及解决中文乱码等常见bug 1 fyne教程 fyne教程地址: https://www.topgoer.cn/docs/goday/goday-1crdp17nj4v6phttps://pkg.go.dev/fyne.io/fyne/v2#section-readme 1.1 介绍 简单易用,fyne提供了简单直观的API&#xff…

iOS编译提效插件cocoapods-jxedt方案详解

1. 前言 本篇文章是cocoapods-jxedt插件实现方案的详解,主要从以下几个方面阐述了一下插件的实现方案和历程。 插件文件目录介绍插件的工作流程介绍插件实现过程中的问题和解决方案记录 如果你对插件的使用还不了解,建议先读一下cocoapods-jxedt使用介…

CVE漏洞复现-CVE-2023-32233 NetFilter权限提升

CVE-2023-32233 NetFilter权限提升 Netfilter是Linux 内核中的网络数据包处理框架(iptables)通过各种规则和过滤器,基于数据包的来源、目标地址、协议类型、端口号等信息,控制网络流量和数据包的转发和处理具体,详情请…

使用贝叶斯网络预测糖尿病:从理论到实践

2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 引言 在现实世界中,许多变量之间存在着复杂的概率关系,例如天气、交通、健康等方面的因素都会相互影响。为了更好地理解…

音频基本概念

1.音频信号 音频信号是一种连续变化的模拟信号,但计算机只能处理和记录二进制的数字信号,由自然音源得到的音频信号必须经过一定的变换,成为数字音频信号之后,才能送到计算机中作进一步的处理。 数字音频系统通过将声波的波型转换…

调用腾讯云API实现英文识别

目录 1. 作者介绍2. 腾讯云英文识别API介绍2.1 英文识别原理—OCR技术2.2 腾讯云英文识别API 3. 实验过程3.1获得API3.2申请调用接口3.3调试接口3.4实验代码3.5实验结果3.6 问题分析 4. 参考连接 1. 作者介绍 乔奕婕,女,西安工程大学电子信息学院&#…

nginx系列第六篇:结合nginx梳理linux中信号的使用

nginx中master进程来管理整个nginx工作的全过程,运行时其通过接收外部信号输入的方式来对内部进行相关调整。本文对照nginx来梳理一下linux中信号常用API的使用。 目录 1.函数sigaction和signal 2.关于信号集sigset_t 2.1 测试程序1 2.2 测试程序1 3.信号屏蔽…

宝塔安装ModStart常见问题

Q:环境提示PHP未禁用危险函数 安装系统时通常会需要解禁 system,exec,passthru,shell_exec,popen,proc_open 等危险函数。部分集成环境会提示危险函数风险,通常可以如下方式解决: 该函数在通常只是在系统 系统安装/系统升级/模块安装/模块升…

【SpinalHDL快速入门】4.3、基本类型之UInt/SInt

文章目录 1.1、描述1.2、声明1.3、运算符1.3.1、逻辑运算(Logic)1.3.2、算术运算(Arithmetic)1.3.3、比较(Comparison)1.3.4、类型转换(Type Cast)1.3.5、部分赋值/提取操作符&#…

第一章:数据库概述

第一章:数据库概述 1.1:为什么要使用数据库 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以"固化"&a…

低代码平台简单分享

低代码平台简单分享 文章目录 低代码平台简单分享1、什么是低代码?什么是低代码平台?2、低代码平台的前世今生**一、低代码的起源**二、低代码的分类三、低代码的能力四、低代码开发的特点 3、目前主流的低代码平台有哪些?优缺点?…

常用模拟低通滤波器的设计——契比雪夫II型滤波器

常用模拟低通滤波器的设计——契比雪夫II型滤波器 切比雪夫 II 型滤波器的振幅平方函数为: 式中,为有效带通截止频率, 是与通带波纹有关的参量, 大,波纹大,; 为 N 阶契比雪夫多项式。 在 Matl…

几种常见数据库的表和列信息查询

文章目录 前言1. oracle数据库1.1 表信息和注释信息1.2 表的列信息 2. mysql数据库2.1 常用的几个命令2.2 使用desc查看表结构2.3 表结构信息主要存在information_schema数据库2.4 主要表是columns,tables,schemata2.4.1 schemata 数据库信息2.4.2 table…

三、opengles画三角形

第一部分Java端 1&#xff09;界面 <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.andro…

数据中台浅析——概念、架构以及未来

数据中台浅析 1. 引言 在当今的数字化时代&#xff0c;数据被誉为"新的石油"&#xff0c;越来越多的企业和组织开始深度挖掘数据的价值。在这个过程中&#xff0c;数据中台逐渐成为了数据管理和分析的核心架构&#xff0c;让我们来深入了解一下它。 1.1 数据中台…

算法复杂度分析(一)

求第n个斐波那契数列 斐波那契数 0 1 1 2 3 5 数列默认从0开始 public static int fib1(int n) {if(n < 1) return n;return fib1(n-1) fib1(n-2);}public static int fib2(int n) {if(n < 1) return n;int first 0;int secend 1;for (int i 0; i < n-1; i) {int…

七、帧缓冲离屏渲染

第一部分基础概念 1)两种帧缓冲的由来 首先opengl能够显示到屏幕&#xff0c;也是有一个默认的framebuffer由窗口系统创建并管理的&#xff0c;将数据放到默认framebuffer 中就可以显示到屏幕上。但是应用程序也想创建额外的非可显示的framebuffer。 应用程序自己创建FBO也是…

【2023RT-Thread全球技术峰会】一套全新的物联网多应用框架xiotman,助你解决多应用的难题

写在前面 就在上周&#xff0c;我作为讲师参与了2023RT-Thread全球技术峰会的主题演讲&#xff0c;我给大家带来了一套全新的解决物联网终端应用多样化的软件架构解决方案&#xff0c;在这里我再次以图文的形式介绍一下给社区的小伙伴&#xff0c;希望借此机会找到更多的同频小…