minio简单使用

文章目录

  • 简介
  • 官方地址
  • Linux下载安装
    • 安装服务
    • 启动
    • 关闭
    • 帮助命令
  • java开发minio
    • 依赖包
    • 新建项目
      • pom
      • 配置文件
      • 配置类
      • Service
      • 测试类
      • 运行测试
    • Api使用前言
    • 针对桶的操作
      • 查看某个桶是否存在
      • 创建一个桶
      • 返回桶列表
      • 删除一个桶
    • 针对文件的操作
      • 上传文件到桶中(本地文件上传)
      • 上传文件到桶中(基于io流上传)
      • Controller上传文件到minio
      • 检查某文件的状态
      • 生成文件访问的URL
      • 从指定的桶中下载文件
      • 列出桶中所有文件
      • 删除指定桶中的文件
  • 纠删码模式单机部署
    • 纠删码介绍
    • 单机多磁盘部署准备
    • 纠删码模式启动

简介

MinIO 是使用 Go (Golang) 开发的一个高性能的开源对象存储服务,专为处理海量非结构化数据(如图片、视频、日志文件、备份等)而设计,且兼容 Amazon S3 的 API。这使得它可以与现有的 S3 客户端、工具和应用程序集成。以下是 MinIO 的详细介绍:

MinIO 的主要特点

  • S3 兼容:MinIO 完全兼容 Amazon S3 API,任何支持 S3 的客户端和应用都可以无缝切换到 MinIO。
  • 高性能:MinIO 可以处理大规模的对象存储需求,能够提供非常高的吞吐量。它使用高效的内存管理和网络层,适合数据密集型应用程序,如大数据、AI/ML、日志分析等。
  • 轻量级设计:MinIO 的二进制文件仅几十 MB,且非常轻量级。它可以在本地计算机、虚拟机、容器和 Kubernetes 等多种环境中轻松部署和运行。
  • 分布式架构:MinIO 支持分布式存储,可以将多个服务器或节点组成集群,实现数据的冗余、容错和高可用性。
  • 企业级功能
    • 多租户:MinIO 支持多租户架构,可将一个集群拆分为多个租户,满足复杂的权限管理和隔离需求。
    • 对象锁定:支持对象的不可变性设置,适合合规性存储需求,如金融和医疗等领域的数据存档。
    • 数据加密:支持静态和传输中数据的加密,确保数据安全。
    • 纠删码:MinIO 使用纠删码技术来分散和保护数据,提供高度的容错能力,同时减少存储开销。

架构与技术细节

  • 单节点与多节点模式:MinIO 可以在单节点部署,也支持多节点、分布式部署模式。在分布式模式下,数据会自动跨多个节点进行复制或通过纠删码保护,保证系统的高可用性。
  • 高扩展性:MinIO 的分布式模式使得它能够在大规模对象存储中处理数十亿个对象。它的设计能够动态扩展,并且提供了线性扩展能力。
  • 对象锁定与生命周期管理:MinIO 支持对象的生命周期策略和锁定机制,允许定义数据存储的保留期和删除策略,适用于日志、备份等长期存储需求。

MinIO 的典型应用场景

  • 私有云存储:许多企业使用 MinIO 构建内部的私有云对象存储,替代昂贵的公共云存储解决方案。
  • 大数据分析和机器学习:MinIO 高性能的数据传输能力非常适合需要处理大量数据的分析平台和 AI/ML 项目。
  • 备份和恢复:由于其高度可靠的存储和高效的数据保护功能,MinIO 常用于备份、归档和恢复数据的解决方案。
  • 混合云与多云架构:MinIO 的轻量级和兼容性使它能够轻松部署在多个云环境中,支持多云架构。

MinIO 的部署方式

  • 容器化部署:MinIO 可通过 Docker 容器部署,简单且快速。
  • Kubernetes 集成:MinIO 可以与 Kubernetes 集成,支持动态存储卷、持久化存储和自动扩展。

使用 MinIO 的好处

  • 简化存储管理:MinIO 的 S3 API 兼容性和简单的架构设计使得它能够快速集成到现有的基础设施中,减少管理复杂度。
  • 降低存储成本:作为开源软件,MinIO 没有许可费用,且其轻量和高效的特性可以减少基础设施开销。
  • 灵活性:MinIO 支持多种部署方式,用户可以根据需要灵活选择在本地、私有云或多云环境中部署。

MinIO发布了以下软件开发工具包(SDK), 用于通过Api操作minio

  • Go
  • Python
  • Java
  • .NET
  • JavaScript
  • Haskell
  • C++

官方地址

官网地址

英文:https://min.io/
中文:https://www.minio.org.cn/

下载地址

https://min.io/download?license=agpl&platform=docker

image-20240918100548227


Linux下载安装

Centos7下载安装minio

访问下载地址

https://min.io/download?license=agpl&platform=linux

先下载Server,再下载客户端


安装服务

linux版本下载方法如下图,使用Binary或RPM的命令下载即可:

dba3172cde6786542e267d07547d103

这里演示使用Binary二进制,执行上图命令中的wget安装命令:

wget https://dl.min.io/server/minio/release/linux-amd64/minio

后面两条命令分别为修改权限启动minio服务:

chmod +x minio
MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password ./minio server /mnt/data --console-address ":9001"

开始执行安装下载

创建新目录

[root@Centos7 ~]# mkdir /home/minio

下载

[root@Centos7 ~]# cd /home/minio
[root@Centos7 minio]# wget https://dl.min.io/server/minio/release/linux-amd64/minio
--2024-09-18 13:58:35--  https://dl.min.io/server/minio/release/linux-amd64/minio
正在解析主机 dl.min.io (dl.min.io)... 178.128.69.202, 138.68.11.125
正在连接 dl.min.io (dl.min.io)|178.128.69.202|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:103944344 (99M) [application/octet-stream]
正在保存至: “minio”100%[=========================================================================================================================================>] 103,944,344  195KB/s 用时 4m 13s 2024-09-18 14:02:49 (401 KB/s) - 已保存 “minio” [103944344/103944344])

改权限并查看

[root@Centos7 minio]# chmod +x minio
[root@Centos7 minio]# ll
总用量 131008
-rwxr-xr-x. 1 root root 103944344 914 20:53 minio

启动

启动minio服务命令解释

MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password ./minio server /mnt/data --console-address ":9001" --address ":9000" &

或者

./minio server /mnt/data --console-address ":9001" --address ":9000" &

MINIO_ROOT_USER:指定访问minio的用户名

MINIO_ROOT_PASSWORD:指定访问minio的密码

./minio server:启动minio服务,./代表当前处于存放minio的目录位置,如果在其他目录执行启动,则使用minio存放目录/minio server即可

/mnt/data:指定minio服务器用于存储数据的目录

--console-address ":9001":指定minio控制台的监听地址和端口,冒号不能去掉,它相当于省略了ip,即可以使用任何ip访问minio服务

--address ":9000":指定用于数据API服务的端口,比如java连接minio进行操作时使用此端口

&:后台启动

执行启动

157832b0ccff68249649ffc70227a64

出现黄色信息时,按下回车即可出现[root@Centos7 minio]# ,并且不会停止minio服务。然后记得开放防火墙的9000与9001端口:

  • firewall-cmd --zone=public --add-port=9000/tcp --permanent:开放9000端口
  • firewall-cmd --reload:重启防火墙
[root@Centos7 minio]# firewall-cmd --zone=public --add-port=9000/tcp --permanent
success
[root@Centos7 minio]# firewall-cmd --reload
success
[root@Centos7 minio]# 

开放防火墙端口后后访问上面图片信息中的WebUI来访问控制台页面(API地址用于客户端调用访问,比如java操作minio):

http://192.168.137.200:9001

0b6a2f787b6a20d676f1f069ef2f135

使用命令中的用户名密码adminpassword登录:

asdf123


关闭

关闭minio服务

先查minio服务状态:ps -ef|grep minio,如下信息即为minio服务正在运行

[root@Centos7 minio]# ps -ef|grep minio
root      44109  44055  0 14:47 pts/0    00:00:00 ./minio server /mnt/data --console-address :9001
root      44810  44055  0 14:54 pts/0    00:00:00 grep --color=auto minio

关闭minio服务,只需要kill杀掉上面的进程即可,进程号使用第一行第一个端口号:

[root@Centos7 minio]# kill 44109
INFO: Exiting on signal: TERMINATED
[1]+  完成                  MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password ./minio server /mnt/data --console-address ":9001"

再查看,minio已关闭:

[root@Centos7 minio]# ps -ef|grep minio
root      45035  44055  0 14:56 pts/0    00:00:00 grep --color=auto minio

帮助命令

执行./minio,查看启动帮助命令:

[root@Centos7 ~]# ./minio
NAME:minio - High Performance Object StorageDESCRIPTION:Build high performance data infrastructure for machine learning, analytics and application data workloads with MinIOUSAGE:minio [FLAGS] COMMAND [ARGS...]COMMANDS:server  start object storage serverFLAGS:--certs-dir value, -S value  path to certs directory (default: "/root/.minio/certs")--quiet                      disable startup and info messages--anonymous                  hide sensitive information from logging--json                       output logs in JSON format--help, -h                   show help--version, -v                print the versionVERSION:RELEASE.2024-09-13T20-26-02Z

如上,启动命令格式为:minio [FLAGS] COMMAND [ARGS...],其中FLAGSARGS为可选,可不填

USAGE,使用的启动命令格式

格式为:minio [FLAGS] COMMAND [ARGS...],其中FLAGSARGS为可选,可不填

COMMANDS,对应minio [FLAGS] COMMAND [ARGS...]中的COMMAND

只有一个server,代表启动对象存储服务

FLAGS可用的命令如下

对应上面的命令输出:

--certs-dir value, -S value  path to certs directory (default: "/root/.minio/certs")
--quiet                      disable startup and info messages
--anonymous                  hide sensitive information from logging
--json                       output logs in JSON format
--help, -h                   show help
--version, -v                print the version


java开发minio

依赖包

在官网文档出找到SDK–>java快速指南,可以找到maven依赖

b10d35aa7bb785e8996b9aecda1489e

370ec3806a8e36e6ba0208c88080c56

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.12</version>
</dependency>

新建项目

建立一个springboot的项目

项目结构

85e7268a257588e9f5a7e3612a19185


pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>minio-demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.10</version></parent><dependencies><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.12</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

配置文件

application.yaml

server:port: 8080#设置文件上传大小
spring:servlet:multipart:max-file-size: 10MBmax-request-size: 10MB#自定义minio配置
minio:endpoint: http://192.168.137.200:9000 #你的minio地址accessKey: adminsecretKey: password

配置类

读取yaml的MinioProperties

package com.minio.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "minio")
@Data
public class MinioProperties {private String endpoint;private String accessKey;private String secretKey;}

配置minio客户端

package com.minio.config;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MinioConfig {@Autowiredprivate MinioProperties minioProperties;//单例下的 MinioClient 是线程安全的,可以多个请求使用同一个客户端来调用@Beanpublic MinioClient minioClient(){return MinioClient.builder().endpoint(minioProperties.getEndpoint()) //地址.credentials(minioProperties.getAccessKey(),minioProperties.getSecretKey()) //用户名密码.build();}}

Service

package com.minio.service;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MinioService {@Autowiredprivate MinioClient minioClient;public void testMinio(){System.out.println(minioClient);}}

测试类

package com.minio;import com.minio.service.MinioService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;/*** 要与上面的主启动类处于同名包内** */
@SpringBootTest
public class MinioTest {@Autowiredprivate MinioService minioService;@Testpublic void testOne(){minioService.testMinio();}
}

运行测试

运行测试方法testOne,输出MinioClient:

io.minio.MinioClient@26c89563


Api使用前言

先介绍minio中的BucketObject,代码中主要操作的就是二者

Bucket:桶,是存储Object的逻辑空间,每个Bucket之间的数据是相互隔离的,对用户而言,相当于存放文件的顶层文件夹

Object:对象,是存放到minio的基本对象,对用户而言,相当于文件

可能遇到的问题

如果出现报错:

error occurred
ErrorResponse(code = RequestTimeTooSkewed, message = The difference between the request time and the server's time is too large.

原因是因为客户端与minio所在服务器时间差距过大导致。服务端linux同步北京时间的方法,安装ntpdate

yum -y install ntp ntpdate

安装后执行同步命令:

ntpdate cn.pool.ntp.org

执行后用date查看当前时间:

[root@Centos7 minio]# ntpdate cn.pool.ntp.org
19 Sep 10:31:39 ntpdate[24198]: step time server 84.16.73.33 offset -0.534266 sec
[root@Centos7 minio]# date
2024年 09月 19日 星期四 10:31:42 CST

其他注意点

重复上传到一个桶的文件会被覆盖,即将同名文件多次上传到同一个桶中,会将原来的文件覆盖


针对桶的操作

查看某个桶是否存在

MinioClient的bucketExists()方法,用于查看某个桶是否存在,返回布尔值:true-存在,false-不存在

示例代码:

package com.minio;import io.minio.BucketExistsArgs;
import io.minio.MinioClient;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;/*** 要与上面的主启动类处于同名包内** */
@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;// bucketExists方法,判断某个桶是否存在@Testpublic void testBucketExists() throws Exception {boolean exists = Client.bucketExists(BucketExistsArgs.builder().bucket("mybucket") //参数为桶的名字,需要小写,可包含数字.build());System.out.println(exists);}}

如果你没有建立过名为mybucket的桶,则输出结果为false。这里注意桶名字英文要小写,.bucket("mybucket")内部有正则表达式进行了判断,不符合规则会报错


创建一个桶

makeBucket(): 创建一个新的存储桶

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;// makeBucket(): 创建一个的存储桶@Testpublic void testMakeBucket() throws Exception {boolean exists = Client.bucketExists(BucketExistsArgs.builder().bucket("mybucket").build());//如果mybucket不存在则创建if(!exists){Client.makeBucket(MakeBucketArgs.builder().bucket("mybucket")//参数为创建的桶的名字.build());}else{System.out.println("名为mybucket的存储桶已经存在!");}}}

执行前

bd3bfcad796cf49b6f20523b88400c9

执行后

023ad4088017dc9e29db4e023d83d8c


返回桶列表

listBuckets():用于列出用户有权访问的所有存储桶,返回存储桶的列表

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;// 列出所有的存储桶@Testpublic void testListBuckets() throws Exception {List<Bucket> buckets = Client.listBuckets();buckets.forEach(bucket -> System.out.println(bucket.name()));}}

打印结果:

mybucket

删除一个桶

removeBucket():用于删除一个已存在的桶,删除失败会抛出异常

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;// 删除一个存储桶@Testpublic void testRemoveBucket() throws Exception {//指定删除名为mybucket的桶Client.removeBucket(RemoveBucketArgs.builder().bucket("mybucket").build());List<Bucket> buckets = Client.listBuckets();//因为目前只有一个桶mybucket,所以idea控制台无输出buckets.forEach(bucket -> System.out.println(bucket.name()));}}

管理页面执行删除前:

qwerrrrr

执行后:

057d2b44e9173760f7d82e3aa3c35f4



针对文件的操作

文件需要上传到桶中,文件在minio中即为Object,也就是对象

上传文件到桶中(本地文件上传)

uploadObject():直接选择上传文件到桶

// 向桶中上传文件
@Test
public void testPutObject() throws Exception {ObjectWriteResponse mybucket = Client.uploadObject(UploadObjectArgs.builder().bucket("mybucket").object("test002.png").filename("C:\\home\\minio\\test001.png").build());System.out.println(mybucket);
}

控制台输出结果:

io.minio.ObjectWriteResponse@1abebef3

查看管理界面:

Buckets中:

37b2c968cdc2c0faafe9ba647949624

Object Browser中:

1ec5a05abcbc48f69eca897163c8978

点击Object Browser中的mybucket:

24b9777777asdf


上传文件到桶中(基于io流上传)

putObject()

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;// 向桶中上传文件@Testpublic void testPutObject() throws Exception {File file = new File("C:\\home\\minio\\test001.png");Client.putObject(PutObjectArgs.builder().bucket("mybucket") //将文件上传到哪个桶.object("test001.png") //上传到桶后该文件的名字.stream(new FileInputStream(file),file.length(),-1) //构建一个流用于上传文件.build());}}

关于上面的stream方法

stream(InputStream stream, long objectSize, long partSize) 方法的主要目的是设置要上传的数据流,以及处理上传时的块大小和对象的总大小。这个方法主要用于大文件的分块上传,如在 AWS S3 或 Minio 中上传文件时使用的多部分上传模式。

参数解释:

  1. InputStream stream:要上传的输入流,通常是文件、网络流或其他形式的数据流。

    • 输入流可以是任意类型,但代码会使用 BufferedInputStream 包装它以提高效率。
  2. long objectSize:上传对象的总大小。

    • 如果对象大小未知(如无法提前知道文件大小),可以传递 -1,表示未知大小。
    • 如果知道对象的大小,可以指定具体大小,这有助于优化上传。
  • 上传文件的最大大小不能超过5TB
  1. long partSize:分块上传时,每一部分的大小。
    • 如果不希望手动指定分块大小,可以传递 -1,自动根据对象大小选择合适的块大小。
    • 如果你知道需要特定大小的块上传(为了控制内存使用或上传效率),可以指定该大小。
    • 如果 partSize 大于 objectSize,那么直接将 objectSize 作为 partSize
    • 合规的 partSize 大小应该设置在5M5G之间

源码:

/*** Sets stream to upload. Two ways to provide object/part sizes.** <ul>*   <li>If object size is unknown, pass -1 to objectSize and pass valid partSize.*   <li>If object size is known, pass -1 to partSize for auto detect; else pass valid partSize*       to control memory usage and no. of parts in upload.*   <li>If partSize is greater than objectSize, objectSize is used as partSize.* </ul>** <p>A valid part size is between 5MiB to 5GiB (both limits inclusive).*/public Builder stream(InputStream stream, long objectSize, long partSize) {validateNotNull(stream, "stream");long[] partinfo = getPartInfo(objectSize, partSize);long pSize = partinfo[0];int pCount = (int) partinfo[1];final BufferedInputStream bis =(stream instanceof BufferedInputStream)? (BufferedInputStream) stream: new BufferedInputStream(stream);return setStream(bis, objectSize, pSize, pCount);}

执行方法结果(执行成功后会由延迟,可稍后查看)

Buckets页签中:

4de8ee9d2972300d8b849ebde0e8921

Object Browser页签中,点击mybucket

effca42a114bd626859db8258044fb5



Controller上传文件到minio

Controller代码,使用基于流的方式上传,接收前端的文件并从后端传到minio中

在项目中添加如下Controller

import io.minio.MinioClient;
import io.minio.ObjectWriteResponse;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;@RequestMapping("upload")
@RestController
public class MinioController {@Autowiredprivate MinioClient Client;@PostMapping("test")public String uploadFile(@RequestPart("file") MultipartFile file) {ObjectWriteResponse mybucket = null;//try-catch-resource方式,可以自动关闭流try (InputStream  inputStream = file.getInputStream()) {mybucket = Client.putObject(PutObjectArgs.builder().bucket("mybucket") //将文件上传到哪个桶.object(file.getOriginalFilename()) //上传到桶后该文件的名字.stream(inputStream, file.getSize(), -1) //构建一个流用于上传文件.build());}catch (Exception e) {e.printStackTrace();}System.out.println(mybucket);return mybucket.toString();}}

postman测试

f6a17f078eb3d2f68ea7cf372b85073

注意测试时的类型是表单,一般都是自动带出不需要改动

06fd8d971872752046cdddfecab1975

测试结果,查看minio管理页面

5451b2f5c452770200394549dddc050



检查某文件的状态

statObject():检查某个桶中的某个文件的状态,也可以用来检测其是否存在

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;@Testpublic void testStatObject() throws Exception {StatObjectResponse mybucket =Client.statObject(StatObjectArgs.builder().bucket("mybucket").object("test002.png").build());System.out.println(mybucket);}}

输出结果:

ObjectStat{bucket=mybucket, object=test002.png, last-modified=2024-09-19T08:16:55Z, size=716272}

如果文件不存在,会报错:

error occurred
ErrorResponse(code = NoSuchKey, message = Object does not exist
, bucketName = mybucket, objectName = test008.png, resource = /mybucket/test008.png, requestId = 17F69873D6323309, hostId = dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8)
request={method=HEAD, url=http://192.168.137.200:9000/mybucket/test008.png, headers=Host: 192.168.137.200:9000
Accept-Encoding: identity
User-Agent: MinIO (Windows 10; amd64) minio-java/8.5.12
Content-MD5: 1B2M2Y8AsgTpgAmY7PhCfg==
x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date: 20240919T083850Z
Authorization: ██
}
response={code=404, headers=Accept-Ranges: bytes
Content-Length: 0
Server: MinIO
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Origin
Vary: Accept-Encoding
X-Amz-Id-2: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8
X-Amz-Request-Id: 17F69873D6323309
X-Content-Type-Options: nosniff
X-Minio-Error-Code: NoSuchKey
X-Minio-Error-Desc: "The specified key does not exist."
X-Ratelimit-Limit: 1632
X-Ratelimit-Remaining: 1632
X-Xss-Protection: 1; mode=block
Date: Thu, 19 Sep 2024 08:38:50 GMT
}at io.minio.S3Base$1.onResponse(S3Base.java:775)at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:750)Process finished with exit code -1


生成文件访问的URL

getPresignedObjectUrl():用于生成一个对象(文件)的签名URL,以便于使用http地址来直接访问该文件

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;// 返回某个桶中某个文件的http访问地址,地址中带有签名字符串@Testpublic void testPresignedObjectUrl() throws Exception {String url = Client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket("mybucket").object("test002.png")//.expiry(3, TimeUnit.MINUTES) //指定有效期为3分钟,地址生成3分钟后即失效无法在访问文件.method(Method.GET) //设置访问文件url的请求方式为get.build());System.out.println(url);}}

输出结果:

http://192.168.137.200:9000/mybucket/test002.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20240919%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240919T085803Z&X-Amz-Expires=180&X-Amz-SignedHeaders=host&X-Amz-Signature=b3d2d9fa782739e698b46b8a8193a60a49ac8741da472c118061b735c9b887d1

访问签名地址

浏览器访问,可以直接预览该图片:

767b041a405b5cf15d9a111e692b78f

如果不加签名串,直接访问地址

http://192.168.137.200:9000/mybucket/test002.png

则会变为如下页面:

cb85107a6883469a110fecbce1794cd

如果想要不带签名串访问,需要做其他配置

第一种,需要在管理界面修改桶的访问策略

首先点击桶

f752e3736a39449e21b8d779078e53d

点击后进入如下界面,修改红框处的访问策略:

77dd2cc2d4f84a956a83754a2a972dd

将访问策略由private改为public,然后点击set保存:

557a42665ab538542993671aa32b3c2

再次使用

http://192.168.137.200:9000/mybucket/test002.png

进行访问:

7cbd47d948f1e21c8e425f1ebf895de

改变访问策略为公有后可以不带签名字符串直接访问,但是此种做法相当于谁都可以访问桶中的文件,并不安全。


第二种,Api方式,使用MinioClientsetBucketPolicy()方法

创建桶mybucket01,并为其指定文件访问策略:

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;@Testpublic void testBucketPolicy() throws Exception {boolean exists = Client.bucketExists(BucketExistsArgs.builder().bucket("mybucket01").build());if(!exists){Client.makeBucket(MakeBucketArgs.builder().bucket("mybucket01")//参数为创建的桶的名字.build());}else{System.out.println("名为mybucket01的存储桶已经存在!");}//策略字符串String policyJson = "{\n" +"  \"Version\": \"2012-10-17\",\n" +"  \"Statement\": [\n" +"    {\n" +"      \"Effect\": \"Allow\",\n" +"      \"Principal\": {\n" +"        \"AWS\": [\"*\"]\n" +"      },\n" +"      \"Action\": [\"s3:GetObject\"],\n" +"      \"Resource\": [\"arn:aws:s3:::mybucket01/*\"]\n" +"    }\n" +"  ]\n" +"}\n";//为上面创建的桶设置文件访问策略,访问策略为public,即公开读取Client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket("mybucket01").config(policyJson).build());}}

上面的json串解释:

{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"AWS": ["*"]},"Action": ["s3:GetObject"],"Resource": ["arn:aws:s3:::mybucket01/*"]}]
}
  • Version:指定策略的版本。
  • Effect:设为 Allow,表示允许操作。
  • Principal"*" 表示允许任何用户(即公开访问)。
  • Actions3:GetObject 允许对象的读取操作。
  • Resource:指定桶中所有对象的 ARN(arn:aws:s3:::mybucket01/*),最后的冒号后面是桶的名字。

运行成功后访问管理页面:

43f449518854091915dd731f1628b4c

进入新建的桶mybucket01中,发现策略为custom自定义策略,虽然为自定义策略,但是根据config的参数,桶中文件是公开读的

e52108b6638bc4d48cbd59a84b0ef6a

执行上传代码进行测试:

// 向桶中上传文件
@Test
public void testPutObject() throws Exception {ObjectWriteResponse mybucket = Client.uploadObject(UploadObjectArgs.builder().bucket("mybucket01").object("test001.png").filename("C:\\home\\minio\\test001.png").build());System.out.println(mybucket);
}

直接通过ip:port/桶名/文件名来访问:

http://192.168.137.200:9000/mybucket01/test001.png

3622b6dd5eb856dbb513165a1aba001

设置成功。

最后,还可以通过手写json串的方式来实现自己想要的任何文件访问策略

2815270de4d0d2cfbd8b538f7b41bcd

在json串的Statement内编写策略,最后set保存即可:

ad0eda452d457b2e14ece7637ce8690



从指定的桶中下载文件

getObject():用于从指定的存储桶中下载文件

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;@Testpublic void testGetObject() throws Exception {GetObjectResponse mybucket01 = Client.getObject(GetObjectArgs.builder().bucket("mybucket01").object("test001.png").build());// 文件保存路径String filePath = "C:\\home\\minio\\test\\test001.png";// 将文件内容从流中读取并写入文件try (InputStream inputStream = mybucket01;  // GetObjectResponse 是一个流,可以直接使用OutputStream outputStream = new FileOutputStream(filePath)) {byte[] buffer = new byte[8192];  // 每次读取8KBint bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}} catch (Exception e) {e.printStackTrace();}}}

执行结果

会将mybucket01桶中的test001.png下载到C:\home\minio\test文件夹中:

03aef68788ad10b9f880bda5aa3c26a

05621613be8bbf5b46becf4b4b9f9c8


列出桶中所有文件

listObjects():用于列出指定存储桶中的所有对象(文件)

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;@Testpublic void testListObjects() {//获取mybucket01桶中的所有对象(文件)Iterable<Result<Item>> results = Client.listObjects(ListObjectsArgs.builder().bucket("mybucket01").build());//循环输出文件名results.forEach(r -> {try {Item item = r.get();System.out.println(item.objectName());} catch (Exception e) {e.printStackTrace();}});}}

输出结果:

test001.png

删除指定桶中的文件

removeObject():用于删除指定存储桶中的对象,需要指定存储桶名称和对象键。如果抛出异常则代表删除失败

@SpringBootTest
public class MinioTestDemo {@Autowiredprivate MinioClient Client;// 删除mybucket01桶中的test001.png文件@Testpublic void testRemoveObject() throws  Exception {//无返回值方法,如果异常则删除失败Client.removeObject(RemoveObjectArgs.builder().bucket("mybucket01").object("test001.png").build());}}

执行前

22deaceaa7747b0c67062c888f400c2

执行后

12a98073644ac344017fbed1deedd29



纠删码模式单机部署

纠删码介绍

  • 纠删码(Erasure Code)简称EC,是一种数据保护方法,也是一种算法;
  • MinlO对纠删码模式的算法进行了实现,采用Reed-Solomon code(简称RScode)纠错码将对象拆分成N/2数据块和N/2奇偶校验块,Reed Solomon利用范德蒙矩阵(Vandermonde matrix)、柯西矩阵(Cauchy matrix)的特性来实现;
  • 即将数据拆分为多个数据块和多个校验块,分散存储在不同的磁盘上,即使在部分磁盘损坏或丢失的情况下,也可以通过剩余的数据块和校验块恢复出原始数据;
  • 举个例子,现在有12块磁盘,一个对象数据会被分成6个数据块、6个奇偶校验块,你可以损坏或丢失任意6块磁盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的磁盘中恢复数据;

单机多磁盘部署准备

纠删码模式 单机多磁盘部署前需要添加磁盘,这里以虚拟机为例演示,按如下步骤执行:

  1. 执行命令:lsblk

    lsblk是Linux中的一个命令,用于列出所有可用的块设备(数据存储设备,如硬盘、闪存驱动器)的信息,如设备名称、大小、挂载点等;

    [root@Centos7 minio]# lsblk
    NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda               8:0    0   50G  0 disk 
    ├─sda1            8:1    0    1G  0 part /boot
    ├─sda2            8:2    0   19G  0 part 
    │ ├─centos-root 253:0    0   41G  0 lvm  /
    │ └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
    └─sda3            8:3    0   30G  0 part └─centos-root 253:0    0   41G  0 lvm  /
    sr0              11:0    1  4.4G  0 rom  /run/media/root/CentOS 7 x86_64
    

    sda即为现有磁盘,大小为50GB

  2. 添加一块磁盘:

    关闭虚拟机,右键设置,添加磁盘:

    0cc8b34132f325c6803f81f164c4263

    选中硬盘下一步后选择硬盘类型为推荐的SCSI即可,再下一步选创建新虚拟磁盘,继续下一步出现如下磁盘分配页面,分配自定义大小,然后下一步:

    736e8fb46bbba59a5baca22673b2313

    出现如下页面点击完成即可:

    a62d24c97a81f6be0f49bdfc45ec199

    最后虚拟机信息如下,然后重新开机:

    4a60dc4044588d5fe228412c24c45e1

    重新开机后再次执行lsblk,发现多了一个1GB的sdb磁盘:

    [root@Centos7 ~]# lsblk
    NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda               8:0    0   50G  0 disk 
    ├─sda1            8:1    0    1G  0 part /boot
    ├─sda2            8:2    0   19G  0 part 
    │ ├─centos-root 253:0    0   41G  0 lvm  /
    │ └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
    └─sda3            8:3    0   30G  0 part └─centos-root 253:0    0   41G  0 lvm  /
    sdb               8:16   0    1G  0 disk 
    sr0              11:0    1  4.4G  0 rom  /run/media/root/CentOS 7 x86_64
    
  3. 将添加的磁盘格式化为xfs格式,以进行挂载: 执行命令mkfs.xfs /dev/sdb

    [root@Centos7 ~]# mkfs.xfs /dev/sdb
    meta-data=/dev/sdb               isize=512    agcount=4, agsize=65536 blks=                       sectsz=512   attr=2, projid32bit=1=                       crc=1        finobt=0, sparse=0
    data     =                       bsize=4096   blocks=262144, imaxpct=25=                       sunit=0      swidth=0 blks
    naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
    log      =internal log           bsize=4096   blocks=2560, version=2=                       sectsz=512   sunit=0 blks, lazy-count=1
    realtime =none 
    
  4. 将磁盘挂载到minio的存储目录: 执行命令mount /dev/sdb /opt/minio/data,然后再lsblk查看:

    如果提示挂载点 /opt/minio/data 不存在,则需要在根目录opt文件夹中去建立minio/data

    [root@Centos7 ~]# mount /dev/sdb /opt/minio/data
    [root@Centos7 ~]# lsblk
    NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda               8:0    0   50G  0 disk 
    ├─sda1            8:1    0    1G  0 part /boot
    ├─sda2            8:2    0   19G  0 part 
    │ ├─centos-root 253:0    0   41G  0 lvm  /
    │ └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
    └─sda3            8:3    0   30G  0 part └─centos-root 253:0    0   41G  0 lvm  /
    sdb               8:16   0    1G  0 disk /opt/minio/data
    sr0              11:0    1  4.4G  0 rom  /run/media/root/CentOS 7 x86_64
    

    sdb后出现 /opt/minio/data 挂载点


纠删码模式启动

使用纠删码模式进行后台启动,命令:

MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password nohup ./minio server  --console-address ":9001" --address ":9000" /opt/minio/data/data{1...12} > /opt/minio/data/minio.log 2>&1 &
  • nohup:这是一个Unix命令,用于运行另一个命令在后台,并且忽略挂起(HUP)信号,也就是即使你退出了终端或关闭了会话,该命令也会继续运行;
  • /opt/minio/data/minio.log:这部分是将标准输出(stdout)重定向到 /opt/minio/data/minio.log 文件,这意味着MinIO 服务器的所有正常输出(如启动信息、状态更新等)都会被写入到这个日志文件中;
  • 2>&1:这部分是将标准错误输出(stderr)重定向到标准输出(stdout),即输出到 /opt/minio/data/minio.log 文件,这样,无论是标准输出还是错误输出,都会被写入到同一个日志文件中;
  • &:这个符号是在命令的末尾,用于将命令放到后台执行,也就是即使你启动了 MinIO 服务器,你的终端或 shell 会话也不会被阻塞,你可以继续执行其他命令;

进入minio所在目录,执行命令

[root@Centos7 ~]# cd /home/minio
[root@Centos7 minio]# MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password nohup ./minio server  --console-address ":9001" --address ":9000" /opt/minio/data/data{1...12} > /opt/minio/data/minio.log 2>&1 &
[1] 6958
[root@Centos7 minio]# ps -ef|grep minio
root       6958   3011  8 14:41 pts/0    00:00:00 ./minio server --console-address :9001 --address :9000 /opt/minio/data/data{1...12}
root       6985   3011  0 14:41 pts/0    00:00:00 grep --color=auto minio

访问管理页面

虚拟机ip加9001端口访问:

00968f02655cc53ce9c01299adb2a72

进入/opt/minio/data目录查看,多出了12个minio存储的目录以及一个日志文件

[root@Centos7 minio]# cd /opt/minio/data
[root@Centos7 data]# ll
总用量 4
drwxr-xr-x. 3 root root  24 921 14:41 data1
drwxr-xr-x. 3 root root  24 921 14:41 data10
drwxr-xr-x. 3 root root  24 921 14:41 data11
drwxr-xr-x. 3 root root  24 921 14:41 data12
drwxr-xr-x. 3 root root  24 921 14:41 data2
drwxr-xr-x. 3 root root  24 921 14:41 data3
drwxr-xr-x. 3 root root  24 921 14:41 data4
drwxr-xr-x. 3 root root  24 921 14:41 data5
drwxr-xr-x. 3 root root  24 921 14:41 data6
drwxr-xr-x. 3 root root  24 921 14:41 data7
drwxr-xr-x. 3 root root  24 921 14:41 data8
drwxr-xr-x. 3 root root  24 921 14:41 data9
-rw-r--r--. 1 root root 789 921 14:41 minio.log

此时,12个存储目录中都是空的,从管理控制台上传文件:

Buckets页签下创建桶:

ddcc824739261a96992207b96c56e26

输入桶名字后点击创建,注意名字要符合规则:

b2538af06c66f26ec0a7f87e91d8912

创建完成后如下:

061598489cfdca474e345db7d2bda8b

Object Browser页签下点击上传文件:

84af4bb80b7e6747fd0231351c80652

上传一个图片,如下:

11f1bf03a6b60e956590af3b083d3cc

完成后可以发现每一个存储目录下都会出现此图片的元数据文件:

cfbdff463f4f7fb205fea40be80d208
至此完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1558973.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C++标准模板库STL之容器--string

STL简介 STL&#xff08;standard template libaray - 标准模板库&#xff09;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;还是一个包罗了数据结构与算法的软件框架。 STL的六大组件及相关函数 仿函数greater、less……算法find、swap、reverse、…

2020年华为杯数学建模竞赛D题论文和代码

无人机集群协同对抗 摘 要&#xff1a; 本文针对非线性约束条件下红蓝双方无人机集群协同对抗的最优规划问题&#xff0c;结合贪婪队形、非线性规划、内点法、蒙特卡洛方法和全联立正交配置有限元法&#xff0c;构建了无人机集群协同对抗推演模型。 针对问题一&#…

OBOO鸥柏全户外液晶广告机室外触控一体机技术标参数公布

整机参数技术公布&#xff1a; OBOO鸥柏智能43寸/49寸/55寸/65寸/75寸/86寸/98寸/110寸全户外LCD液晶安卓系统网络广告屏/室外触摸屏查询一体机投标参数投标标准款。 1、液晶屏具工业级液晶面板&#xff0c;亮度为2000cd/㎡&#xff0c;并且具备自动感光亮度调节&#xff0c;…

工业网关的主要功能-天拓四方

引言&#xff1a; 在当今工业自动化的浪潮中&#xff0c;工业网关作为一种重要的网络连接设备&#xff0c;扮演着不可或缺的角色。其强大的功能使得工业设备能够无缝接入网络&#xff0c;实现远程监控、控制、数据采集和协议转换等&#xff0c;极大地提升了工业生产的效率和智…

算法专题五: 位运算

目录 常见位运算总结1. 位1的个数2. 比特位计数3. 汉明距离4. 只出现一次的数字5. 只出现一次的数字Ⅲ6. 判定字符是否唯一7. 丢失的数字8. 两正数之和9. 只出现一次的数字Ⅲ10. 消失的两个数字 常见位运算总结 重点 : 1. 位1的个数 算法思路: 这道题就用到了我们总结的那个第…

图解 微信开发者工具 小程序源码 调试、断点标记方法 , 微信小程序调试器,真机调试断点调试方法,小程序网络API请求调试方法 总结

在我们使用微信开发者工具进行微信小程序开发的时候&#xff0c;在这个微信开发者工具的代码编辑框里面我们是无法像使用vscode, idea等IDE工具时那样直接对代码打断点进行调试&#xff0c; 原因是小程序实际上他就是一个web浏览器应用的包装, 在其内部使用的还是类似chrome的…

C/C++程序员为什么要了解汇编?了解汇编有哪些好处?如何学习汇编?

目录 1、概述 2、从汇编的角度去理解问题的若干实例说明 2.1、使用空指针去访问类的数据成员或调用类的虚函数为什么会引发崩溃&#xff1f; 2.2、从汇编代码的角度去理解多线程的执行细节&#xff0c;去理解多线程在访问共享资源时为什么要加锁 2.3、使用Windbg静态分析d…

Canal 扩展篇(阿里开源用于数据同步备份,监控表和表字段(日志))

1.Canal介绍 Canal把自己伪装成从数据库&#xff0c;获取mysql主数据库的日志&#xff08;binlog&#xff09;信息&#xff0c;所以要想使用canal就得先开启数据库日志 https://github.com/alibaba/canal Canal 主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量…

Spring Boot2.x教程:(五)日志分割

日志分割 1、概述2、为什么选择Logback2.1、创建配置文件2.2、配置说明2.3、修改应用程序配置2.4、启动应用程序 3、总结 大家好&#xff0c;我是欧阳方超&#xff0c;可以扫描下方二维码关注我的公众号“欧阳方超”&#xff0c;后续内容将在公众号首发。 1、概述 在现代应用程…

ubuntu18.04系统中图形化界面

一、Ubuntu 18.04 中&#xff0c;使用 GDM 作为默认的图形用户界面&#xff08;GUI&#xff09;管理器。GDM 是 GNOME Display Manager 的缩写&#xff0c;它是用于 Ubuntu 的显示管理器&#xff0c;负责处理登录和会话管理。 通过命令行重启 Ubuntu 18.04 上的图形界面服务&am…

技术路线图用什么画?用这个在线工具轻松完成绘制!

在当今快速发展的技术世界中&#xff0c;技术路线图已成为企业和团队不可或缺的战略规划工具。它不仅能够清晰地展示技术发展方向&#xff0c;还能帮助团队成员、利益相关者和投资者更好地理解和参与技术战略的制定过程。但不可否认的是&#xff0c;创建一个有效的技术路线图并…

付费计量系统实体和接口(6)

13.7.3 Sub-classification of the Metering functions计量功能的子分级 The Metering function primarily deals with the measurement of the quantity of delivered electrical energy to the consumer. These measurements are made available for use by other functions …

qt 3D编程

Qt 3D是一个用于构建交互式3D图形应用的库&#xff0c;它是Qt库的一 部分。Qt 3D提供了一组C和QMLAPI&#xff0c;帮助开发者快速构 建3D应用程序。 一、核心模块 Qt3DCore 功能&#xff1a;提供3D场景中的基本概念&#xff0c;如实体&#xff08;Entity&#xff09;、组件&…

R语言运行地理探测器模型

地理探测器&#xff08;GeoDetector&#xff09;是一种用于空间分析的统计模型&#xff0c;它能够探测空间分异性以及揭示其背后驱动力的一组方法。它的核心思想是基于这样的假设&#xff1a;如果某个自变量对某个因变量有重要影响&#xff0c;那么自变量和因变量的空间分布应该…

java的LinkedList

java的LinkedList 什么是LinkedListLinkedList的模拟实现LinkedList的使用ArrayList和LinkedList的区别 什么是LinkedList LinkedList的官方文档 LinkedList的底层是双向链表结构&#xff0c;由于链表没有将元素存储在连续的空间中&#xff0c;元素存储在单独的结点中&#xf…

【Redis】Set类型的常用命令与应用场景

目录 1.命令小结 2.命令解析 3.编码方式与应用场景 1.命令小结 &#xff08;1&#xff09;set的特点 1&#xff09;set中存放的数据也都是String类型 2&#xff09;set集合中的元素是无须的 3&#xff09;set集合中的元素是唯一的&#xff0c;不可重复 &#xff08;2&a…

MySql 之 Binglog 复制

复制是一种将数据从一个 MySQL 数据库服务器异步复制到另一个的技术。使用 MySQL 复制选项&#xff0c;您可以复制所有数据库、选定的数据库甚至选定的表&#xff0c;具体取决于您的使用情况。 前提条件 确保在源服务器上启用了二进制日志记录。确保复制配置中的所有服务器都有…

uniapp——h5的控制台调试、h5调试

介绍 小程序在调试的时候可以打开调试模式&#xff0c;可以看到console.log的打印情况。 但是H5运行到手机上没有默认的调试的模式&#xff0c;但是可以人为手动加一个。 如何实现 1、main.js文件 import Vconsole from ‘vconsole’ /** 关闭正式环境打印日志&#xff…

Centos7.5 安装和配置jdk17

目录 一、下载JDK17包 二、将安装包放入服务器 三、解压jdk包到/usr/lib/jvm 四、修改JDK环境配置 1、打开配置文件 2、最后一行插入 3、立即生效 4、检查版本 一、下载JDK17包 访问网址:Java Downloads | Oraclehttps://www.oracle.com/java/technologies/downloads…

音频功放工作原理:【B类】

上一节我们讲了A类音频功放的工作原理&#xff0c;也知道了它的优缺点&#xff1a; A类功放优点&#xff1a;高增益&#xff0c;低失真&#xff0c;音质好 A类功放缺点&#xff1a;热量高&#xff0c;效率低&#xff0c;功率小 为了解决A类功放的缺点&#xff0c;业界又引入…