【对象存储】Minio本地运行和 golang客户端基本操作

运行环境

OS和Golang版本:

复制代码
go version go1.21.0 darwin/arm64

安装

源码安装

复制代码
cd minio
go build main.go
# 得到 116M Oct 19 15:49 main

把 main 改名为 minio

二进制安装

参考https://www.minio.org.cn/docs/minio/macos/index.html的安装步骤。

启动

复制代码
minio server --address=0.0.0.0:8877 ./data

控制台输出如下信息

复制代码
➜  minio minio server --address=0.0.0.0:8877 ./data


┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ You are running an older version of MinIO released 2 years ago ┃
┃ Update: Run `mc admin update`                                  ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

API: http://0.0.0.0:8877
RootUser: minioadmin
RootPass: minioadmin

Console: http://10.78.14.68:56056 http://192.168.255.10:56056 http://127.0.0.1:56056
RootUser: minioadmin
RootPass: minioadmin

Command-line: https://docs.min.io/docs/minio-client-quickstart-guide
   $ mc alias set myminio http://0.0.0.0:8877 minioadmin minioadmin

Documentation: https://docs.min.io

启动控制台页面

使用浏览器打开 http://127.0.0.1:56056,使用账号密码登录(minioadmin/minioadmin)

创建aksk

在左侧菜单中选择 Account,点击Create Service Account,创建得到一个 aksk

创建Bucket

mc命令

mc命令安装

参考https://min.io/docs/minio/linux/reference/minio-mc.html

mc命令运行

mc给本地的minio链接做一个别名

复制代码
➜  ~ mc alias set myminio http://0.0.0.0:8877
Enter Access Key: KLN00KFT1K5EP9I39I9N
Enter Secret Key:
Added `myminio` successfully.

mc查看 minio 节点信息

复制代码
➜  ~ mc admin info myminio
●  0.0.0.0:8877
   Uptime: 3 hours
   Version: 2021-08-05T22:01:19Z

mc 对 minio 做 ping 检查链接是否 ok

复制代码
➜  minio mc ping myminio
  1: http://0.0.0.0:8877:8877   min=9.36ms     max=9.36ms     average=9.36ms     errors=0   roundtrip=9.36ms
  2: http://0.0.0.0:8877:8877   min=0.64ms     max=9.36ms     average=5.00ms     errors=0   roundtrip=0.64ms

mc上传文件

复制代码
➜  minio mc cp ./minio-dev.yaml myminio/mybucket/3.yaml
...o-dev.yaml: 1.46 KiB / 1.46 KiB ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.36 KiB/s 0s

mc下载文件

复制代码
➜  minio mc cp myminio/mybucket/3.yaml ./3-get.yaml
...ket/3.yaml: 1.46 KiB / 1.46 KiB ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 67.56 KiB/s 0s

mc监听桶变化

复制代码
➜  minio mc watch myminio/mybucket/
[2023-10-19T07:09:05.751Z] 1.5 KiB s3:ObjectCreated:Put http://0.0.0.0:8877/mybucket/3.yaml

[2023-10-19T07:27:35.675Z]   36 B s3:ObjectCreated:Put http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T07:28:46.813Z]        s3:ObjectAccessed:Get http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T07:28:58.157Z]        s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T08:11:38.631Z]        s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.633Z]        s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.634Z]        s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.638Z]        s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.644Z]        s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.653Z]        s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/3.yaml
[2023-10-19T08:11:38.655Z]        s3:ObjectAccessed:Get http://0.0.0.0:8877/mybucket/3.yaml

mc查看桶统计信息

复制代码
➜  minio mc stat myminio/mybucket/
Name      : 2.yaml
Date      : 2023-10-19 14:59:57 CST
Size      : 1.5 KiB
ETag      : 34095c50340c4381e0fdc5fd61eecc76
Type      : file
Metadata  :
  Content-Type: text/yaml

Name      : 3.yaml
Date      : 2023-10-19 15:09:05 CST
Size      : 1.5 KiB
ETag      : 34095c50340c4381e0fdc5fd61eecc76
Type      : file
Metadata  :
  Content-Type: text/yaml

Name      : minio-dev.yaml
Date      : 2023-10-19 14:54:23 CST
Size      : 1.5 KiB
ETag      : 34095c50340c4381e0fdc5fd61eecc76
Type      : file
Metadata  :
  Content-Type: text/yaml

Name      : test/
Date      : 2023-10-19 16:13:06 CST
Type      : folder

这个etag 是怎么计算的呢?其实就是文件的 md5值

复制代码
➜  minio md5 3-get.yaml
MD5 (3-get.yaml) = 34095c50340c4381e0fdc5fd61eecc76

mc列出桶中的文件

复制代码
➜  minio mc ls myminio/mybucket/
[2023-10-19 14:59:57 CST] 1.5KiB STANDARD 2.yaml
[2023-10-19 15:09:05 CST] 1.5KiB STANDARD 3.yaml
[2023-10-19 14:54:23 CST] 1.5KiB STANDARD minio-dev.yaml
[2023-10-19 16:18:25 CST]     0B test/

服务端文件存储

启动时,将minio 的工作目录设置到 data 下,在 data 目录下主要有两个目录

  • .minio.sys 是minio系统信息
    • 包括桶定义和桶中的文件索引目录 ./.minio.sys/buckets/mybucket
    • 账号信息和iam信息 ./.minio.sys/config/iam/service-accounts/KLN00KFT1K5EP9I39I9N
  • mybucket 是创建的一个桶名称
复制代码
➜  data find .
.
./.minio.sys
./.minio.sys/buckets
./.minio.sys/buckets/.usage-cache.bin
./.minio.sys/buckets/.minio.sys
./.minio.sys/buckets/.minio.sys/buckets
./.minio.sys/buckets/.minio.sys/buckets/.usage-cache.bin
./.minio.sys/buckets/.minio.sys/buckets/.usage-cache.bin/fs.json
./.minio.sys/buckets/.minio.sys/buckets/.bloomcycle.bin
./.minio.sys/buckets/.minio.sys/buckets/.bloomcycle.bin/fs.json
./.minio.sys/buckets/.minio.sys/buckets/mybucket
./.minio.sys/buckets/.minio.sys/buckets/mybucket/.usage-cache.bin
./.minio.sys/buckets/.minio.sys/buckets/mybucket/.usage-cache.bin/fs.json
./.minio.sys/buckets/.minio.sys/buckets/.usage.json
./.minio.sys/buckets/.minio.sys/buckets/.usage.json/fs.json
./.minio.sys/buckets/.bloomcycle.bin
./.minio.sys/buckets/mybucket
./.minio.sys/buckets/mybucket/.usage-cache.bin
./.minio.sys/buckets/mybucket/test
./.minio.sys/buckets/mybucket/test/1.txt
./.minio.sys/buckets/mybucket/test/1.txt/fs.json
./.minio.sys/buckets/mybucket/minio-dev.yaml
./.minio.sys/buckets/mybucket/minio-dev.yaml/fs.json
./.minio.sys/buckets/mybucket/3.yaml
./.minio.sys/buckets/mybucket/3.yaml/fs.json
./.minio.sys/buckets/mybucket/2.yaml
./.minio.sys/buckets/mybucket/2.yaml/fs.json
./.minio.sys/buckets/mybucket/.metadata.bin
./.minio.sys/buckets/.tracker.bin
./.minio.sys/buckets/.usage.json
./.minio.sys/config
./.minio.sys/config/config.json
./.minio.sys/config/iam
./.minio.sys/config/iam/service-accounts
./.minio.sys/config/iam/service-accounts/KLN00KFT1K5EP9I39I9N
./.minio.sys/config/iam/service-accounts/KLN00KFT1K5EP9I39I9N/identity.json
./.minio.sys/config/iam/policydb
./.minio.sys/config/iam/policydb/sts-users
./.minio.sys/config/iam/policydb/sts-users/P1Y2O1AO30UYBE2UODBY.json
./.minio.sys/config/iam/policydb/users
./.minio.sys/config/iam/policydb/users/ak00123456789.json
./.minio.sys/config/iam/users
./.minio.sys/config/iam/users/ak00123456789
./.minio.sys/config/iam/users/ak00123456789/identity.json
./.minio.sys/config/iam/format.json
./.minio.sys/config/iam/sts
./.minio.sys/config/iam/sts/P1Y2O1AO30UYBE2UODBY
./.minio.sys/config/iam/sts/P1Y2O1AO30UYBE2UODBY/identity.json
./.minio.sys/multipart
./.minio.sys/format.json
./.minio.sys/tmp
./.minio.sys/tmp/07c1ffc6-ae6f-4a99-a57e-cb5e55530603
./mybucket
./mybucket/test
./mybucket/test/1.txt
./mybucket/minio-dev.yaml
./mybucket/3.yaml
./mybucket/2.yaml

aws-s3操作文件

aws-s3的 sdk 代码简单包装

go.mod

复制代码
module minio-demo

go 1.18

require (
    github.com/aws/aws-sdk-go v1.43.21
)

aws_s3.go

复制代码
package minio

import (
    "bytes"
    "io"
    "time"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

const (
    //token暂时为空
    DefaultToken = ""
    //测试用的regin,调用方需自行配置
    DefaultRegion = "us-east-1"
)

// AwsS3 aws s3服务应用层客户端
type AwsS3 struct {
    SecretId  string
    SecretKey string
    Region    string
    Bucket    string
    Endpoint  string
    Token     string
    Client    *s3.S3
}

// NewAwsS3 创建aws s3实例
func NewAwsS3(secretId, secretKey, region, bucket, endpoint, token string) *AwsS3 {
    var awsS3Instance AwsS3
    awsS3Instance.SecretId = secretId
    awsS3Instance.SecretKey = secretKey
    awsS3Instance.Region = region
    awsS3Instance.Bucket = bucket
    awsS3Instance.Endpoint = endpoint
    awsS3Instance.Token = token
    config := &aws.Config{
        Credentials: credentials.NewStaticCredentials(secretId, secretKey, token),
        Region:      aws.String(region),
        Endpoint:    aws.String(endpoint),
        //DisableSSL:       aws.Bool(true),
        S3ForcePathStyle: aws.Bool(true),
    }
    sess := session.Must(session.NewSession(config))
    awsS3Instance.Client = s3.New(sess)
    return &awsS3Instance
}

// PutObject 根据内容上传文件对象
func (a *AwsS3) PutObject(awsPath string, content []byte) (string, error) {
    putObjectInput := &s3.PutObjectInput{
        Bucket: aws.String(a.Bucket),
        Key:    aws.String(awsPath),
        Body:   aws.ReadSeekCloser(bytes.NewReader(content)),
    }
    resp, err := a.Client.PutObject(putObjectInput)
    if err != nil {
        return "", err
    }
    return *(resp.ETag), nil
}

// GetObject 下载文件对象内容
func (a *AwsS3) GetObject(awsPath string) ([]byte, string, error) {
    getObjectInput := &s3.GetObjectInput{
        Bucket: aws.String(a.Bucket),
        Key:    aws.String(awsPath),
    }
    resp, err := a.Client.GetObject(getObjectInput)
    if err != nil {
        return nil, "", err
    }
    content, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, "", err
    }
    return content, *(resp.ETag), nil
}

// DeleteObject 删除文件对象
func (a *AwsS3) DeleteObject(awsPath string) error {
    deleteObject := &s3.DeleteObjectInput{
        Bucket: aws.String(a.Bucket),
        Key:    aws.String(awsPath),
    }
    _, err := a.Client.DeleteObject(deleteObject)
    if err != nil {
        return err
    }
    return nil
}

// HeadObject 获取对象元数据信息,包括md5和上次修改时间
func (a *AwsS3) HeadObject(awsPath string) (string, *time.Time, error) {
    headObject := &s3.HeadObjectInput{
        Bucket: aws.String(a.Bucket),
        Key:    aws.String(awsPath),
    }
    resp, err := a.Client.HeadObject(headObject)
    if err != nil {
        return "", nil, err
    }
    return *(resp.ETag), resp.LastModified, nil
}

minio_test.go

复制代码
package minio

import (
    "os"
    "testing"
)

// minio测试配置
var (
    SecretId  = "KLN00KFT1K5EP9I39I9N"
    SecretKey = "k******j"
    Region    = DefaultRegion
    Bucket    = "mybucket"
    Token     = DefaultToken
    Endpoint  = "http://127.0.0.1:8877"
)

var awsS3Instance = NewAwsS3(SecretId, SecretKey, Region, Bucket, Endpoint, Token)

上传文件 Put http://0.0.0.0:8877/mybucket/test/1.txt

复制代码
func TestPutObject(t *testing.T) {
    // 测试时修改本地路径
    localFilePath := "./testdata/1.txt"
    t.Logf("local file path %s", localFilePath)
    fileContent, err := os.ReadFile(localFilePath)
    if err != nil {
        t.Fatalf("read file error: %s!", err.Error())
        return
    }
    // 测试时修改aws路径
    awsPath := "/test/1.txt"
    _, err = awsS3Instance.PutObject(awsPath, fileContent)
    if err != nil {
        t.Fatalf("put object error: %s", err.Error())
    }
    t.Logf("put object success")
}

下载文件 Get http://0.0.0.0:8877/mybucket/test/1.txt

复制代码
func TestGetObject(t *testing.T) {
    // 测试时修改aws路径
    awsPath := "/test/1.txt"
    contentBytes, _, err := awsS3Instance.GetObject(awsPath)
    if err != nil {
        t.Fatalf("get object error: %s", err.Error())
    }

    //获取当前系统根目录
    if err != nil {
        t.Fatalf("get home dir error: %s!", err.Error())
        return
    }
    // 测试时修改本地路径
    localFilePath := "./testdata/1-get.txt"
    err = os.WriteFile(localFilePath, contentBytes, 0644)
    if err != nil {
        t.Fatal("write error")
        return
    }
    t.Logf("get object success")
}

Head文件 Head http://0.0.0.0:8877/mybucket/test/1.txt

复制代码
func TestHeadObject(t *testing.T) {
    // 测试时修改aws路径
    awsPath := "/test/1.txt"
    eTag, lastModifyTime, err := awsS3Instance.HeadObject(awsPath)
    if err != nil {
        t.Fatalf("head object error: %s", err.Error())
    }
    t.Logf("head object success,eTag : %s, lastModifyTime : %v", eTag, lastModifyTime)
}

删除文件 Delete http://0.0.0.0:8877/mybucket/test/1.txt

复制代码
func TestDeleteObject(t *testing.T) {
    // 测试时修改aws路径
    awsPath := "/test/1.txt"
    err := awsS3Instance.DeleteObject(awsPath)
    if err != nil {
        t.Fatalf("delete object error: %s", err.Error())
    }
    t.Logf("delete object success")
}

mc 监听桶 mybucket 的变化,可以看出

复制代码
➜  minio mc watch myminio/mybucket/

[2023-10-19T07:27:35.675Z]   36 B s3:ObjectCreated:Put http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T07:28:46.813Z]        s3:ObjectAccessed:Get http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T07:28:58.157Z]        s3:ObjectAccessed:Head http://0.0.0.0:8877/mybucket/test/1.txt
[2023-10-19T08:42:23.065Z]        s3:ObjectRemoved:Delete http://0.0.0.0:8877/mybucket/test/1.txt

minio控制台页面统计信息

详细文档参考

https://min.io/docs/minio/kubernetes/upstream/index.html?ref=docs-redirect\&ref=con

done.

祝玩的开心~

相关推荐
__AtYou__4 小时前
Golang | Leetcode Golang题解之第563题二叉树的坡度
leetcode·golang·题解
凡人的AI工具箱11 小时前
15分钟学 Go 第 49 天 :复杂项目开发
开发语言·人工智能·后端·算法·golang
杜杜的man13 小时前
【go从零单排】Random Numbers、Number Parsing
开发语言·python·golang
aiee14 小时前
Golang时间函数
开发语言·后端·golang
还是转转15 小时前
Go开发指南- Goroutine
开发语言·golang
蜗牛沐雨15 小时前
Go语言中的`io.Pipe`:实现进程间通信的利器
开发语言·后端·golang·进程通信·pipe
杜杜的man15 小时前
【go从零单排】泛型(Generics)、链表
开发语言·链表·golang
杜杜的man15 小时前
【go从零单排】JSON序列化和反序列化
golang·json
wuh233315 小时前
golang-基础知识(函数)
开发语言·后端·golang
杜杜的man16 小时前
【go从零单排】XML序列化和反序列化
xml·开发语言·golang