这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
Minio是一个开源的分布式文件存储系统,它基于 Golang 编写,虽然轻量,却拥有着不错的高性能,可以将图片、视频、音乐、pdf这些文件存储到多个主机,可以存储到多个Linux,或者多个Windows,或者多个Mac,Minio中存储最大文件可以达到5TB。任何类型的文件都是支持的,主要应用在微服务系统中。
站点复制
站点复制扩展了存储桶复制的功能,以包括所有站点上相同的 IAM、安全令牌、访问密钥和存储桶功能。
站点复制将多个 MinIO 部署链接在一起,并使存储桶、对象和身份和访问管理 (IAM) 设置在所有连接的站点之间保持同步。
- 存储桶和对象的创建、修改和删除
- 创建和删除 IAM 用户、组、策略以及到用户或组的策略映射(对于 LDAP 用户或组)
root可从本地凭据验证的会话令牌创建安全令牌服务 (STS)凭据- 创建和删除访问密钥用户拥有的除外
root)
使用Minio的背景
我们先回顾下,平时我们做文件存储是普遍如何操作的,简单描述下步骤和时序,例如我们在添加用户信息&上传照片这个业务中,首先客户端发起文件上传操作到API,服务将文件存储到服务器本地文件夹中,生成返回一个文件摘要,摘要包括路径,文件ID等一些基本信息,然后将这些摘要信息和用户业务数据组装程一个DTO,最终存储到数据库中。
此时我们只是一个单系统的上传文件操作,无论是业务逻辑还是技术都比较简单,但是如果是一些分布式高并发和高访问量的电商网站面临此类业务应该怎么做呢?一般电商类都是几十上百个微服务组成,如果按照单体系统的思路去实现,如果有100个微服务,那就存储在100个地方,后期的维护量岂不是令人非常头疼,加上事情做多错多,为了降低维护量,提升访问效率,我们需要将文件统一存储,基于MinIO高性能和可用性,我们选择使用
MinIO来作为我们的文件管理中间件,用它承载系统文件上传下载。
1.从 Github 下载
go get github.com/minio/minio-go/v7
2.本地启动服务
在终端,使用minio server启动一个本地minio实例,
Start minio server on "/home/shared" directory.
$ minio server /home/shared
3.快速入门示例 - 文件上传器
这个示例程序连接到一个对象存储服务器,创建一个桶并将文件上传到桶中。 在此示例中,我们将使用在play.min.io上运行的 MinIO 服务器。请随意使用此服务进行测试和开发。此示例中显示的访问凭据向公众开放。
文件上传器.go
package main
import (
"context"
"log"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func main() {
ctx := context.Background()
endpoint := "127.0.0.1:9000"
accessKeyID := "minioadmin"
secretAccessKey := "minioadmin"
useSSL := false
// Initialize minio client object.
minioClient, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
Secure: useSSL,
})
if err != nil {
log.Fatalln(err)
}
// Make a new bucket called mymusic.
bucketName := "mymusic"
location := "us-east-1"
err = minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: location})
if err != nil {
//fmt.Println("1")
// Check to see if we already own this bucket (which happens if you run this twice)
exists, errBucketExists := minioClient.BucketExists(ctx, bucketName)
if errBucketExists == nil && exists {
log.Printf("We already own %s\n", bucketName)
} else {
log.Fatalln(err)
}
} else {
//fmt.Println("2")
log.Printf("Successfully created %s\n", bucketName)
}
// Upload the zip file
objectName := "test.mp4"
filePath := "/Users/taowei/Desktop/go/tiktok-main/pkg/minio/client/test.mp4"
contentType := "application/zip"
// Upload the zip file with FPutObject
info, err := minioClient.FPutObject(ctx, bucketName, objectName, filePath, minio.PutObjectOptions{ContentType: contentType})
if err != nil {
log.Fatalln(err)
}
log.Printf("Successfully uploaded %s of size %d\n", objectName, info.Size)
}