Minio分布式对象存储的部署与使用

Posted 言成言成啊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Minio分布式对象存储的部署与使用相关的知识,希望对你有一定的参考价值。

一、部署

下载Minio直接Github搜索即可,minio/minio: Multi-Cloud Object Storage

1.1 单机部署

单机部署命令,指定静态端口9001。

一般会占用两个端口,9000和指定的9001,实际访问是9001。

mkdir data
# 授予执行权限
chmod +x minio
# 启动命令
MINIO_ROOT_USER=minioadmin MINIO_ROOT_PASSWORD=minioadmin nohup ./minio server data/ --console-address=:9001 >log 2>&1 &

建议将启动命令创建成bash脚本,方便执行

我的本机ip是10.0.0.10,所以直接访问10.0.0.10:9000即可,会自动跳转到9001。

1.2 集群部署

集群部署,多台机器使用同一套启动命令即可。

硬性要求:至少4个driver,此处我就理解成分区。

至少4个driver,是由于分布式Minio启用了纠删码算法来保证数据的安全,这个算法保证了,只要不超过N/2块分区坏掉,数据就不会丢失。

部署集群,我可以选用2个节点,每节点2个driver,或者4个节点,每节点1个driver

我采用的方式是后者。

准备4台服务器

10.0.0.10
10.0.0.11
10.0.0.12
10.0.0.13

每台机器执行下面的命令。

# 创建minio数据存储目录
mkdir /minio
# 查看所有分区情况
fdisk -l
# 带*的为主分区,我的是/dev/sda1,将数据存储目录挂载到主分区
mount /dev/sda1 /minio
# 临时的环境变量,配置root的用户名密码
export MINIO_ROOT_USER=xiangwan 
export MINIO_ROOT_PASSWORD=xiangwan
# 启动集群
nohup /root/minio server http://10.0.0.10/minio http://10.0.0.11/minio http://10.0.0.12/minio http://10.0.0.13/minio --console-address=:9001 >log 2>&1 &

四台机器都执行后,可通过cat log 查看日志,如下图。

任意访问其中一台即可,我就直接访问10.0.0.10:9000,可以查看节点监控信息

二、使用官方SDK

示例demo是纯maven项目,meethigher/minio-usage: 对象存储minio使用

2.1 基础配置

pom.xml

<?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>top.meethigher</groupId>
    <artifactId>minio-usage</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>7.1.0</version>
        </dependency>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

创建配置文件application.properties

endpoint=http://10.0.0.10:9000
accessKey=xiangwan
secretKey=xiangwan

创建配置类MinioConfig

package top.meethigher.config;

import java.io.IOException;
import java.util.Properties;

/**
 * minio配置
 *
 * @author chenchuancheng
 * @since 2022/7/8 14:41
 */
public class MinioConfig 
    //连接url
    public static String endpoint;
    //公钥
    public static String accessKey;
    //私钥
    public static String secretKey;

    static 
        Properties prop = new Properties();
        try 
            prop.load(MinioConfig.class.getClassLoader().getResourceAsStream("application.properties"));
            endpoint=prop.getProperty("endpoint");
            accessKey=prop.getProperty("accessKey");
            secretKey=prop.getProperty("secretKey");
         catch (IOException e) 
            e.printStackTrace();
        
    

创建MinioClientBuilder

package top.meethigher.utils;

import io.minio.MinioClient;
import top.meethigher.config.MinioConfig;

/**
 * 获取MinioClientBuilder
 *
 * @author chenchuancheng
 * @since 2022/7/8 14:42
 */
public class MinioClientBuilder 

    private static MinioClient minioClient = null;

    private MinioClientBuilder() 
        minioClient = MinioClient.builder()
                .endpoint(MinioConfig.endpoint)
                .credentials(MinioConfig.accessKey, MinioConfig.secretKey)
                .build();
    

    private static final class MinioClientBuilderHolder 
        static final MinioClientBuilder minioClientBuilder = new MinioClientBuilder();
    

    public static MinioClient build() 
        MinioClientBuilder minioClientBuilder = MinioClientBuilderHolder.minioClientBuilder;
        return minioClientBuilder.getMinioClient();
    

    private MinioClient getMinioClient() 
        return minioClient;
    

2.2 api使用

上传功能

MinioClient minioClient = MinioClientBuilder.build();
UploadObjectArgs args = UploadObjectArgs.builder()
        .bucket("xiangwan")
        .object("wuhuang.jpg")
        //创建并上传到test文件夹
        //.object("test/wuhuang.jpg")
        .filename("C:\\\\Users\\\\14251\\\\Desktop\\\\吾皇.png")
        .build();
minioClient.uploadObject(args);

下载功能

MinioClient minioClient = MinioClientBuilder.build();
GetObjectArgs args = GetObjectArgs.builder()
        .bucket("xiangwan")
        .object("wuhuang.jpg")
        .build();
InputStream is = minioClient.getObject(args);
FileOutputStream fos = new FileOutputStream("xiangwan.jpg");
int len;
byte[] b=new byte[1024];
while((len=is.read(b))!=-1) 
    fos.write(b,0,len);

fos.close();
is.close();

查询功能

MinioClient minioClient = MinioClientBuilder.build();
ListObjectsArgs args= ListObjectsArgs.builder()
        .bucket("xiangwan")
        //指定文件夹
        //.prefix("test/")
        .build();
Iterable<Result<Item>> results = minioClient.listObjects(args);
for (Result<Item> next : results) 
    Item item = next.get();
    boolean dir = item.isDir();
    if (dir) 
        System.out.printf("文件名:%s,文件修改时间:0,文件大小:0,文件类型:%s\\n", item.objectName(),
                item.isDir());
     else 
        System.out.printf("文件名:%s,文件修改时间:%s-%s-%s %s:%s:%s,文件大小:%s,文件类型:%s\\n", URLDecoder.decode(item.objectName(), "utf-8"),
                item.lastModified().getYear(), item.lastModified().getMonthValue(), item.lastModified().getDayOfMonth(),
                item.lastModified().getHour(), item.lastModified().getMinute(), item.lastModified().getSecond(),
                item.size(),
                item.isDir());
    

运行结果如图

删除功能

MinioClient minioClient = MinioClientBuilder.build();
//删除单个
RemoveObjectArgs args= RemoveObjectArgs.builder()
        .bucket("xiangwan")
        .object("log")
        .build();
minioClient.removeObject(args);
        
//删除多个
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder()
        .bucket("xiangwan")
        .prefix("test/")
        .build());
List<DeleteObject> deleteObjects=new LinkedList<>();
for (Result<Item> result : results) 
    Item item = result.get();
    deleteObjects.add(new DeleteObject(URLDecoder.decode(item.objectName(),"utf-8")));

RemoveObjectsArgs argss= RemoveObjectsArgs.builder()
        .bucket("xiangwan")
        .objects(deleteObjects)
        .build();
//该方法是懒加载,类似于Feature,需要拿到返回值执行
Iterable<Result<DeleteError>> removeObjects = minioClient.removeObjects(argss);
for (Result<DeleteError> removeObject : removeObjects) 
    DeleteError error = removeObject.get();
    System.out.printf("minio删除错误->bucketName=%s,objectName=%s,message=%s\\n", error.bucketName(), error.objectName(), error.message());

删除文件夹没有提供直接方式

如有需求就走删除多个对象

三、配置权限

3.1 用户和组

直接创建用户或者组即可,最终用户的权限=用户权限+组权限。

3.2 密钥

具体参照MinIO多用户快速入门指南 | Minio中文文档


	"Version": "2012-10-17",
	"Statement": [

		
			"Effect": "Allow",
			"Action": [
				"s3:GetObject",
				"s3:ListAllMyBuckets",
				"s3:ListBucket",
				"s3:PutObject",
				"s3:DeleteObject",
				"s3:GetBucketLocation"
			],
			"Resource": [
				"arn:aws:s3:::*"
			]
		
	]

比如我授权一个token,只能调用删除。只需要添加动作DeleteObject即可。

会发现,只能删除,连查询都做不了。

3.3 通过桶名和文件名访问

配置资源可以通过ip:端口/桶名/资源路径访问单个资源。

就如桶管理,找到Access Rules。

放行所有,都有readOnly权限即可。

通过ip:端口/桶名/资源路径即可访问。

四、参考致谢

MinIO Quickstart Guide| Minio中文文档

Issues · minio/minio

Minio(一) | 搭建Minio服务器(单节点)_Ruby丶彬的博客-CSDN博客_minio单节点

Minio(二) | Minio多用户权限控制_Ruby丶彬的博客-CSDN博客_minio权限控制

Minio(三) | Minio分布式集群搭建_Ruby丶彬的博客-CSDN博客_minio集群搭建

搭建minio分布式测试环境_wdtmn的博客-CSDN博客

文档服务器minio 可通过文件路径进行访问_领风者的博客-CSDN博客_minio 文件访问路径

Minio 批量删除文件失效的问题分析 (Java SDK) - 简书

MinIO关闭公开桶的列表展示_李硕硕的博客-CSDN博客_minio 数据泄露

Linux中挂载到底什么意思!!!为你解答_404~的博客-CSDN博客_linux挂载是什么意思

以上是关于Minio分布式对象存储的部署与使用的主要内容,如果未能解决你的问题,请参考以下文章

Minio分布式对象存储部署!

Minio分布式对象存储部署!

Minio分布式对象存储部署!

MinIO 的分布式部署

通过K8S部署对象存储MinIO

高可用对象存储实战使用Python操作Minio存储桶