MinIO快速入门指南:构建自己的云存储服务

MinIO快速入门指南:构建自己的云存储服务

今日内容介绍,预计花费18分钟

MinIO快速入门指南:构建自己的云存储服务

云存储服务在现代应用中变得越来越重要,不仅对于数据备份和恢复,还对于大数据分析、静态网站托管等应用。而MinIO是一个开源的云存储服务器,它可以帮助你快速构建自己的云存储服务,无论是私有云还是公有云

分布式文件系统(存储)方案

云服务

  • 阿里云OSS
  • 七牛云
  • 腾讯云存储
  • 华为云存储

私有化服务

  • 阿里的FastDFS
  • MinIO
私有化服务存储方式 优点 缺点
FastDFS 1.主备服务,高可用
  2.支持主从文件,支持自定义扩展名
  3.支持动态扩容
1.没有完备官方文档,近几年没有更新
 2.环境搭建较为麻烦
MinIO 1.性能高,准硬件条件下它能达到55GB/s的读、35GB/s的写速率
   2.部署自带管理界面
  3.MinIO.Inc运营的开源项目,社区活跃度高
  4.提供了所有主流开发语言的SDK
1,不支持动态增加节点

1. 什么是MinIO

MinIO基于Apache License v2.0开源协议的对象存储服务,可以为云存储的解决方案用来保存海量的图片,视频,文档。由于采用Golang实现,服务端可以工作在Windows,Linux, OS X和FreeBSD上。配置简单,基本是复制可执行程序,单行命令可以运行起来。

MinIO兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。

S3 ( Simple Storage Service简单存储服务)

MinIO基本概念

  • bucket – 类比于文件系统的目录
  • Object – 类比文件系统的文件
  • Keys – 类比文件名

1.1.MinIO特点

  • 数据保护:Minio使用Minio Erasure Code(纠删码)来防止硬件故障。即便损坏一半以上的driver,但是仍然可以从中恢复。

  • 高性能:作为高性能对象存储,在标准硬件条件下它能达到55GB/s的读、35GB/s的写速率

  • 可扩容:不同MinIO集群可以组成联邦,并形成一个全局的命名空间,并跨越多个数据中心

  • SDK支持:基于Minio轻量的特点,它得到类似Java、Python或Go等语言的sdk支持

  • 有操作页面:面向用户友好的简单操作界面,非常方便的管理Bucket及里面的文件资源

  • 功能简单:这一设计原则让MinIO不容易出错、更快启动

  • 丰富的API:支持文件资源的分享连接及分享链接的过期策略、存储桶操作、文件列表访问及文件上传下载的基本功能等。

  • 文件变化主动通知:存储桶(Bucket)如果发生改变,比如上传对象和删除对象,可以使用存储桶事件通知机制进行监控,并通过以下方式发布出去:AMQP、MQTT、Elasticsearch、Redis、NATS、MySQL、Kafka、Webhooks等。

2. Docker-Compose安装MinIO

【步骤一】:创建项目目录

mkdir -p /mydata/minio/data
mkdir -p /mydata/minio/minio
mkdir -p /mydata/minio/config

【步骤二】:配置MinIO的Docker Compose 配置文件docker-compose-minio.yml

# 可参考 https://docs.min.io/docs/minio-docker-quickstart-guide.html
version: '3'
services:
  minio:
    image: minio/minio:latest                                    # 原镜像`minio/minio:latest`
    container_name: minio                                        # 容器名为'minio'
    restart: unless-stopped                                              # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
    volumes:                                                     # 数据卷挂载路径设置,将本机目录映射到容器目录
      - "/mydata/minio/data:/data"
      - "/mydata/minio/minio:/minio"
      - "/mydata/minio/config:/root/.minio"
    environment:                                      # 设置环境变量,相当于docker run命令中的-e
      TZ: Asia/Shanghai
      LANG: en_US.UTF-8
      MINIO_PROMETHEUS_AUTH_TYPE: "public"
      MINIO_ACCESS_KEY: "root"                        # 登录账号
      MINIO_SECRET_KEY: "password"                    # 登录密码
    command: server /data  --console-address ":9001"
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
    ports:                              # 映射端口
      - "9001:9001"
      - "42330:42330"
      - "9000:9000"

【步骤三】:通过docker-compose启动minio

docker-compose -f docker-compose-minio.yml -p minio up -d

注意:该命令和docker-compose-minio.yml在同级目录

【步骤四】:访问管理控制台

我们设置的对外访问端口是9001,在浏览器输入ip:9001进行访问

http://192.168.150.102:9001

我们设置的账户密码 为  root/passwordMinIO快速入门指南:构建自己的云存储服务

【步骤五】:创建一个桶

MinIO快速入门指南:构建自己的云存储服务

【步骤六】:设置bucket (桶)访问权限

将同的私有权限改为public

MinIO快速入门指南:构建自己的云存储服务
MinIO快速入门指南:构建自己的云存储服务
MinIO快速入门指南:构建自己的云存储服务

【步骤七】:点击进去可以上传文件

MinIO快速入门指南:构建自己的云存储服务

【步骤八】:访问上传文件

上传完成后可以通过地址+桶名+文件名访问注意:端口不是9001而是9000

http://192.168.150.102:9000/zbbmeta/test.jpg
MinIO快速入门指南:构建自己的云存储服务

3. SpringBoot快速入门Minio

【步骤一】创建项目

创建minio-learn,并导入对应依赖到pom.xml

  • 完整项目结果
MinIO快速入门指南:构建自己的云存储服务
  • 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>

    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.7.15</version>
    </parent>

    <groupId>com.zbbmeta</groupId>
    <artifactId>minio-learn</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
    </dependencies>

</project>

【步骤一】创建项目引导类

在java目录下创建com.zbbmeta.minio包,在其包下创建MinIOApplication引导类

package com.zbbmeta.minio;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author springboot葵花宝典
 * @description: TODO
 */

@SpringBootApplication
public class MinIOApplication {
    public static void main(String[] args) {
        SpringApplication.run(MinIOApplication.classargs);
    }
}

【步骤二】配置文件

resources目录下创建application.yml文件,内容如下

server:
  port: 8001
minio:
  endpoint: http://192.168.150.102:9000
  accessKey: root
  secretKey: password
  bucketName: zbbmeta  # 你的是什么 这里就写什么

【步骤三】 配置读取类

com.zbbmeta.minio.property包下创建MinIOProperties类,用于读取minio信息

package com.zbbmeta.minio.property;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author springboot葵花宝典
 * @description: TODO
 */

@Data
@ConfigurationProperties(prefix = "minio")
public class MinIOProperties {
    private String endpoint;
    private String accessKey;
    private String secretKey;
    private String bucketName;
}

【步骤四】 配置MinioClient类

package com.zbbmeta.minio.config;

import com.zbbmeta.minio.property.MinIOProperties;
import io.minio.MinioClient;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author springboot葵花宝典
 * @description: TODO
 */

@Configuration
@EnableConfigurationProperties(MinIOProperties.class)
public class MinIOConfig 
{

    @Bean
    public MinioClient minioClient(MinIOProperties minIOProperties){
        MinioClient minioClient = MinioClient.builder()
                        .endpoint(minIOProperties.getEndpoint())
                        .credentials(minIOProperties.getAccessKey(), minIOProperties.getSecretKey())
                        .build();
        return minioClient;
    }
}

【步骤五】 创建Minio的Service服务类

com.zbbmeta.minio.service包下创建MinIOService

package com.zbbmeta.minio.service;

import com.zbbmeta.minio.property.MinIOProperties;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.UUID;

/**
 * @author springboot葵花宝典
 * @description: TODO
 */

@Service
public class MinIOService {
    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinIOProperties properties;

    /**
     * 上传文件
     * @param file
     * @return
     */

    public String upload(MultipartFile file) {
        // 原文件名
        String originalFilename = file.getOriginalFilename();
        // 获取文件的后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        // 构造新的文件名,名字不重复
        String objectName = UUID.randomUUID().toString() + suffix;
        // 上传文件
        try {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .contentType(file.getContentType())
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .bucket(properties.getBucketName())
                    .object(objectName)
                    .build();
            minioClient.putObject(putObjectArgs);
        } catch (Exception e) {
            throw new RuntimeException("上传文件失败: " + e.getMessage());
        }
        return properties.getEndpoint() + "/" + properties.getBucketName() + "/" + objectName;
    }
    /**
     * 上传文件
     * @param name
     * @param inputStream
     * @param contentType
     * @return
     */

    public String upload(String name,InputStream inputStream,String contentType){
        // 上传文件
        try {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .contentType(contentType)
                    .stream(inputStream, inputStream.available(), -1)
                    .bucket(properties.getBucketName())
                    .object(name)
                    .build();
            minioClient.putObject(putObjectArgs);
        } catch (Exception e) {
            throw new RuntimeException("上传文件失败: " + e.getMessage());
        }
        return properties.getEndpoint() + "/" + properties.getBucketName() + "/" + name;
    }
    /**
     * 删除文件
     * @param url
     */

    public void delete(String url){
        String objectName = url.replace(properties.getEndpoint()+"/","")
                .replace(properties.getBucketName()+"/","");
        RemoveObjectArgs args = RemoveObjectArgs.builder()
                .bucket(properties.getBucketName())
                .object(objectName)
                .build();
        try {
            minioClient.removeObject(args);
        } catch (Exception e) {
            throw new RuntimeException("删除文件失败: " + e.getMessage());
        }
    }
    /**
     * 下载文件
     * @param url
     * @return
     */

    public InputStream download(String url){
        String objectName = url.replace(properties.getEndpoint()+"/","")
                .replace(properties.getBucketName()+"/","");
        GetObjectArgs args = GetObjectArgs.builder()
                .bucket(properties.getBucketName())
                .object(objectName)
                .build();
        InputStream inputStream = null;
        try {
            inputStream = minioClient.getObject(args);
        } catch (Exception e) {
            throw new RuntimeException("下载文件失败: " + e.getMessage());
        }
        return inputStream;
    }
}

【步骤六】 创建Minio的FileController接口类

com.zbbmeta.minio.controller包下创建FileController接口类

package com.zbbmeta.minio.controller;

import com.zbbmeta.minio.service.MinIOService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author springboot葵花宝典
 * @description: TODO
 */

@RestController
@RequestMapping("/minio/file")
public class FileController {
    @Autowired
    private MinIOService minIOService;

    @PostMapping("/upload")
    public ResponseEntity<String> upload(MultipartFile file) {
        String url = minIOService.upload(file);
        return ResponseEntity.ok(url);
    }

    @DeleteMapping
    public ResponseEntity delete(String url) {
        minIOService.delete(url);
        return ResponseEntity.ok("删除成功");
    }
}

【步骤七】 使用postman测试

  • 上传测试
MinIO快速入门指南:构建自己的云存储服务
  • 删除测试
MinIO快速入门指南:构建自己的云存储服务

4. minio 上传文件失败报错

如果报以下错误:

 The difference between the request time and the server‘s time is too large.

原因:linux服务器时区的问题(因为虚拟机挂起后,时间也就停了)

解决方案


    1. 查看系统时间、硬件时间
# date // 查看系统时间
#hwclock // 查看硬件时间
  • 2.时间服务器上的时间同步的方法 安装ntpdate工具
# yum -y install ntp ntpdate
  • 3.设置系统时间与网络时间同步
# ntpdate cn.pool.ntp.org
  • 4.将系统时间写入硬件时间
hwclock --systohc


原文始发于微信公众号(springboot葵花宝典):MinIO快速入门指南:构建自己的云存储服务

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/182696.html

(1)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!