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


    运行环境

    OS和Golang版本: 

    go version go1.21.0 darwin/arm64

     

    安装

    源码安装

    • 下载最新版本的源码,地址https://github.com/minio/minio后编译
    • 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.

    祝玩的开心~

  • 相关阅读:
    Web视频
    9.23/24数电
    ES6+知识点总结
    IDEA使用技巧
    [android studio] cannot find declaration to go的解决方法
    1.C语言初学——两数相加求和
    【SQL 初级语法 6】 SQL 高级处理
    HyperLynx(十二)BoardSim和PCB板级仿真分析(三)
    TNet 中 JoinChannel 场景名可写可不写
    记一次血淋淋的MySQL崩溃修复案例
  • 原文地址:https://www.cnblogs.com/voipman/p/17774860.html