这是我参与「第五届青训营 」伴学笔记创作活动的第 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一致,否则会出现签名验证失败的错误。