[ 在项目中使用MinIO| 青训营笔记]

436 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天

对象存储MinIO的基本使用

在青训营的大项目中,需要实现视频和图片的存储与获取。最简单的方案是以文件的方式保存到本地,通过静态资源服务器或者FTP服务器来进行获取,这种方式简单直观,但是无法进行进一步的权限控制等对象管理。实际项目中的视频、图片等资源的存储一般都会采用对象存储的方式来保存。

一些基本概念

对象存储的概念最早是来源于1996年卡内基梅隆大学所提出的一个研究项目。2006年,Amazon发布了其Simple Storage Service(S3)服务,正式将对象存储引入到云计算领域,这一服务后来发展成对象存储领域的事实标准,目前通行的对象存储基本上都会兼容S3协议。

在对象存储中,一个对象由三部分组成:key,data和metadata。而对象本身保存在桶(bucket)中,没有传统的文件系统的路径等概念。

MinIO是采用Go语言编写的高性能分布式对象存储,它兼容S3协议,并且易于使用。

使用MinIO

通过docker启动

启动一个单点模式的MinIO非常简单,使用如下的docker命令即可启动一个MinIO服务

docker run -p 9000:9000 --name minio minio/minio server /data

也可以使用docker-compose来指定一个MinIO服务:

services:
  minio:
    image: minio/minio:latest
    ports:
      - 9000:9000
    environment:
      MINIO_ACCESS_KEY: "your_access_key"
      MINIO_SECRET_KEY: "your_secret_key"
    volumes:
      - minio_data:/data
    command: server /data 
volumes:
  minio_data:

其中9000是MinIO默认的API访问端口,MinIO还有网页访问端口,在这里未指定。ACCESS_KEY和SECRET_KEY相当于用户名和密码,在访问其API时需要同时提供这两项。/data则是其保存存储对象的路径,可以将其映射到一个docker卷。

创建一个客户端

首先在项目路径下引入MinIO的Go语言客户端:

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

然后:

	Cli, err = minio.New(Endpoint, &minio.Options{
		Creds:  credentials.NewStaticV4(AccessKeyID, SecretAccessKey, ""),
		Secure: false,
	})

其中的Endpoint即minio的访问地址,需要注意的是,在后续获取presignedObject时,该访问地址会参与签名,因此需要让该地址为外部可访问的地址,如果使用localhost则后续获取到存储对象的url只能在本机使用。

Secure设置为false是为了使用http,如果设置为true,则还需要为其配置https证书。

创建桶

minio的对象都保存在bucket中,在保存对象到指定的bucket前,bucket必须存在。

可以通过如下代码判断bucket是否存在并创建对应的bucket。

	ok, err := Cli.BucketExists(ctx, "test-bucket")
	if err != nil {
		log.Fatal(err)
	}
	if !ok {
		err = Cli.MakeBucket(ctx, "test-bucket", minio.MakeBucketOptions{})
		if err != nil {
			log.Fatal(err)
		}
	}

存储对象和获取对象URL

假定要存储的对象以[]byte的形式传入,则可以使用如下代码存储:

	info, err := Cli.PutObject(ctx, "test-bucket", key, bytes.NewReader(data), int64(len(data)), minio.PutObjectOptions{ContentType: "text"})

如果要上传一个磁盘上的文件,可以使用FPutObject函数,用法类似。

通过给定的key获取对象的url也很简单:

Cli.PresignedGetObject(ctx, "test-bucket", key, expired, nil)

其中,expired是返回的URL的有效时间,最短为1s,最长为7天,PresignedGetObject会返回一个预签名的URL,从而不需要额外的验证就可以访问。需要注意的是,创建Client时所使用的host必须与最终访问的host一致,否则会出现签名验证失败的错误。