运行环境

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.

祝玩的开心~

【对象存储】Minio本地运行和 golang客户端基本操作的更多相关文章

  1. 数据湖Hudi与对象存储Minio及Hive\Spark\Flink的集成

    本文主要记录对象存储组件Minio.数据湖组件Hudi及查询引擎Hive\Spark之间的兼容性配置及测试情况,Spark及Hive无需多言,这里简单介绍下Minio及Hudi. MinIO 是在 G ...

  2. rclone挂载对象存储到本地

    一.原理图 二.挂载步骤 1.申请对象存储资源 (略) 2.下载rclone https://rclone.org/downloads/ 3.上传服务器,解压并安装 sudo unzip rclone ...

  3. Github 29K Star的开源对象存储方案——Minio入门宝典

    对象存储不是什么新技术了,但是从来都没有被替代掉.为什么?在这个大数据发展迅速地时代,数据已经不单单是简单的文本数据了,每天有大量的图片,视频数据产生,在短视频火爆的今天,这个数量还在增加.有数据表明 ...

  4. 对象存储服务-Minio

    Mino 目录 Mino 对象存储服务 Minio 参考 Minio 架构 为什么要用 Minio 存储机制 纠删码 MinIO概念 部署 单机部署: Docker 部署Minio 分布式Minio ...

  5. Minio对象存储

    目录 Minio对象存储 1.概述 2.功能特性 3.2.多节点 3.3.分布式 4.分布式minio集群搭建 4.1.集群规划 4.3.编写集群启动脚本(所有节点) 4.4.编写服务脚本(所有节点) ...

  6. Amazon S3 对象存储Java API操作记录(Minio与S3 SDK两种实现)

    缘起 今年(2023年) 2月的时候做了个适配Amazon S3对象存储接口的需求,由于4月份自学考试临近,一直在备考就拖着没总结记录下,开发联调过程中也出现过一些奇葩的问题,最近人刚从考试缓过来顺手 ...

  7. 轻量对象存储服务——minio

    minio Minio是一个非常轻量的对象存储服务. Github: minio 它本身不支持文件的版本管理.如果有这个需求,可以用 s3git 搭配使用. Github: s3git 安装 mini ...

  8. Golang 调用 aws-sdk 操作 S3对象存储

    Golang 调用 aws-sdk 操作 S3对象存储 前言 因为业务问题,要写一个S3对象存储管理代码,由于一直写Go,所以这次采用了Go,Go嘛,快,自带多线程,这种好处就不用多说了吧. 基础的功 ...

  9. s3fs-fuse 把 s3-like 对象存储挂载到本地

    s3fs-fuse 是一个采用 c++

  10. 对象存储服务MinIO安装部署分布式及Spring Boot项目实现文件上传下载

    目录 一.MinIO快速入门 1. MinIO简介 2. CentOS7更换成阿里云镜像 3. 安装 3.1 下载 3.2 运行测试 4. 配置脚本执行文件 4.1 创建配置执行文件 4.2 执行 二 ...

随机推荐

  1. 搭载ChatGPT之后的表格插件又有哪些新的改变——Function calling增强

    摘要:本文由葡萄城技术团队于博客园原创并首发.葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 在<大火的ChatGPT与SpreadJS结合会有哪些意想不到的效果>一文中提 ...

  2. Lifecycle解决了什么问题,以及它的基本用法

    1.为何要引入Lifecycle? 我首先来举个大家都比较常见的例子:我们在android开发的时候,经常需要在页面的onCreate()方法中对组件进行初始化,在onPause()方法中停止组件,而 ...

  3. CF1580C Train Maintenance题解

    我们以 \(\sqrt m\) 为分界点来进行平衡. 设当前在进行第 \(k\) 次操作,询问 \(i\). 对于 \(x_i + y_i \leq \sqrt m\),可以在 \(last_{x_i ...

  4. 【Docker】部署Tomcat

    搜索镜像 $ docker search 镜像名称:镜像TAG # 如: 没有加TAG,表示默认搜索的是最新版本的tomcat镜像 $ docker search tomcat # 如:搜索 tomc ...

  5. Hexo博客Next主题相册搭建

    参考文章,小红鸡 参考文章,主题美化 效果展示:相册 在blog文件夹/source下创建photos文件夹,在photos文件夹创建index.md文件,编辑index.md文件,写入以下代码: & ...

  6. 使用mybatis-generator 能生成 但是实际使用时抛出异常Invalid bound statement (not found)

    好多好多好多红 但是重点是一句org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): {}.d ...

  7. Appium新版本引发的一个问题

    Appium新版本引发的一个问题 准备工作 测试代码 from appium import webdriver des_cap = {'platformName': 'android'} driver ...

  8. Java 调用gdal API(二)——栅格裁剪

    gdal可以说是GIS数据处理比较好的工具之一,虽然也提供了Java API,但是官方文档确实太过简单,用起来确实太难受,每次都需要去参考对应的C++api,然后在对应使用. 因此小编决定从这篇文章开 ...

  9. Avalonia中用FluentAvalonia+DialogHost.Avalonia实现界面弹窗和对话框

    Avalonia中用FluentAvalonia+DialogHost.Avalonia实现界面弹窗和对话框 本文是项目中关于 弹窗界面 设计的技术分享,通过 FluentAvalonia+Dialo ...

  10. 数据库是要拿来用的,不是用来PK先进性的

    周五参加了WAIC后又和一家上海本地的数据库厂商交流了一下午.等我要买高铁票回南京的时候已经买不到票了.好不容易刷到一张到苏州北的高铁票,我就上了车.上车后突然想起还不如就回苏州老家住一晚算了.到家后 ...