Minio搭建文件服务器的学习

MinIO是一个高性能的开源对象存储服务器,与Amazon S3兼容。它使用Go语言编写,可以在多种操作系统上运行,如Linux、MacOS和Windows等。MinIO的分布式特性使其能够轻松扩展存储容量和处理能力,满足大规模数据存储的需求。

使用Docker搭建一个支持跨域访问的文件服务器可以有多种方式,具体选择哪一种取决于你的需求、资源以及对不同技术栈的熟悉程度。以下是几种推荐的方式:

  1. Nginx Nginx 是一个高性能的HTTP和反向代理服务器,可以很容易地配置为静态文件服务器,同时添加CORS(Cross-Origin Resource Sharing)头以支持跨域访问。你可以使用官方的Nginx Docker镜像,并编写一个Nginx配置文件来实现这一目的。

  2. Apache Tomcat 如果你已经熟悉Java生态系统,Tomcat也是一个可行的选择。Tomcat可以作为静态文件服务器,通过配置其web.xmlserver.xml文件,你能够添加必要的CORS支持。但是,Nginx通常比Tomcat更轻量级,更适合静态文件服务。

  3. FileBrowser FileBrowser是一个易于使用的文件管理系统,可以部署在Docker容器中。它提供了文件浏览、上传、下载和分享的功能,并且内置了CORS支持,非常适合管理大量的媒体文件如视频和图片。

  4. FTP服务器 如果你想要一个传统的文件传输协议服务器,可以考虑使用Docker部署像vsftpd这样的FTP服务器。然而,FTP服务器默认不支持跨域访问,你可能需要额外的配置或中间件(如Nginx或Apache)来实现CORS。

  5. S3-Compatible Storage 使用像MinIO这样的S3兼容存储系统,它可以很容易地与Docker集成,提供高性能的对象存储,同时也支持CORS配置。

为了实现跨域访问,你需要确保你的服务器响应中包含正确的CORS头部。例如,在Nginx配置中,你可以添加如下指令:

Nginx

深色版本

1location ~* \.(jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|wav|mp3|aac)$ {
2    add_header Access-Control-Allow-Origin *;
3}

如果你需要的是一个简单且成熟的解决方案,那么使用Nginx或FileBrowser会是比较好的选择。Nginx在性能和灵活性上非常出色,而FileBrowser则提供了用户友好的界面和管理功能。如果你只需要基本的文件服务,Nginx可能是更轻便的选择;如果需要更丰富的文件管理功能,那么FileBrowser会是更好的选择。

参考:使用Minio搭建文件服务器_开源的文件服务器-CSDN博客

参考:Deploy MinIO: Single-Node Single-Drive — MinIO Object Storage for Linux

参考:MinIO系列:从零开始搭建高效文件存储服务-百度开发者中心 (baidu.com)

参考:Minio搭建文件服务器_minio服务器搭建-CSDN博客

参考:分布式对象存储minio从0到高手的保姆级教程 - 知乎 (zhihu.com)

Minio是一个开源的对象存储服务器,可以用来存储和管理大规模的数据。我们可以用它来存储图片或者视频资源。

minio和阿里云(腾讯云、百度云等)oss对比
托管方式:MinIO 是一个开源的对象存储系统,可以在自己的服务器或云环境中进行部署和管理。而阿里云 OSS 是由阿里云提供的托管服务,不需要自己购买服务器或进行部署。

成本:MinIO 是一个开源项目,可以免费使用,您只需要支付服务器和网络等基础设施的费用。而阿里云 OSS 是一个收费的云服务,费用根据存储容量、数据传输和访问次数等因素而定。

功能和性能:阿里云 OSS 是一个经过大规模使用和测试的云存储服务,提供了丰富的功能和高可用性。MinIO 也提供了类似的功能,并专注于提供高性能和低延迟的对象存储服务。

数据保护和备份:阿里云 OSS 提供了多层次的数据冗余和备份机制,以确保数据的安全性和可用性。MinIO 也提供了类似的数据冗余和备份机制,但需要用户自行配置和管理。

地理位置和可用区:阿里云 OSS 在全球范围内提供了多个地理位置和可用区来存储数据,以满足用户的需求。MinIO 则需要用户自行设置多个节点并进行数据的分布式存储。

总结:如果想要免费但折腾的话,可以考虑minio;如果不介意收费的话,肯定选择专业且服务周到的云服务。(当然,minio也提供商业技术服务)。

注:Minio 完全兼容AWS S3协议。这意味着你可以使用Minio API来访问和操作AWS S3服务;同时,你也可以使用S3API来访问Minio服务器。

 

Minio优点

  • 部署简单: 一个single二进制文件即是一切,还可支持各种平台。
  • minio支持海量存储,可按zone扩展(原zone不受任何影响),支持单个对象最大5TB;
  • 兼容Amazon S3接口,充分考虑开发人员的需求和体验;
  • 低冗余且磁盘损坏高容忍,标准且最高的数据冗余系数为2(即存储一个1M的数据对象,实际占用磁盘空间为2M)。但在任意n/2块disk损坏的情况下依然可以读出数据(n为一个纠删码集合(Erasure Coding Set)中的disk数量)。并且这种损坏恢复是基于单个对象的,而不是基于整个存储卷的。
  • 读写性能优异

1.2 MinIO的基础概念

  • Object:存储到 Minio 的基本对象,如文件、字节流,Anything...
  • Bucket:用来存储 Object 的逻辑空间。每个 Bucket 之间的数据是相互隔离的。对于客户端而言,就相当于一个存放文件的顶层文件夹。
  • Drive:即存储数据的磁盘,在 MinIO 启动时,以参数的方式传入。Minio 中所有的对象数据都会存储在 Drive 里。
  • Set :即一组 Drive 的集合,分布式部署根据集群规模自动划分一个或多个 Set ,每个 Set 中的Drive 分布在不同位置。一个对象存储在一个 Set 上。(For example: {1...64} is divided into 4 sets each of size 16.)
    • 一个对象存储在一个Set上
    • 一个集群划分为多个Set
    • 一个Set包含的Drive数量是固定的,默认由系统根据集群规模自动计算得出
    • 一个SET中的Drive尽可能分布在不同的节点上

1.3 纠删码EC(Erasure Code)

MinIO 使用纠删码机制来保证高可靠性,使用 highwayhash 来处理数据损坏( Bit Rot Protection )。

关于纠删码,简单来说就是可以通过数学计算,把丢失的数据进行还原,它可以将n份原始数据,增加m份数据,并能通过n+m份中的任意n份数据,还原为原始数据。即如果有任意小于等于m份的数据失效,仍然能通过剩下的数据还原出来。

1.4 存储形式

文件对象上传到 MinIO ,会在对应的数据存储磁盘中,以 Bucket 名称为目录,文件名称为下一级目录,文件名下是 part.1 和 xl.meta(老版本,最新版本如下图),前者是编码数据块及检验块,后者是元数据文件。

linux 在指定目录下执行 tree 命令(yum install tree 先安装下)

1.5 存储方案

2.0 官方推荐

磁盘文件格式

官方文档推荐磁盘文件格式使用 xfs

多磁盘

磁盘需要保持一致

  1. 文件格式一致
  2. 容量一致
  3. 每个区使用偶数数量的磁盘,便于纠删码模式
  4. 每个区的磁盘数量需要一致,所以扩展后新的区和原始区的磁盘的数量、容量、格式都是一致的

     

参考:扩展一个分布式MinIO部署 — MinIO中文文档 | MinIO Linux中文文档

2.1 单机部署

minio server的standalone模式,即要管理的磁盘都在host本地。该启动模式一般仅用于实验环境、测试环境的验证和学习使用。在standalone模式下,还可以分为non-erasure code mode和erasure code mode。

non-erasure code mode

在此启动模式下,对于每一份对象数据,minio直接在data下面存储这份数据,不会建立副本,也不会启用纠删码机制。因此,这种模式无论是服务实例还是磁盘都是“单点”,无任何高可用保障,磁盘损坏就表示数据丢失。

erasure code mode

此模式为minio server实例传入多个本地磁盘参数。一旦遇到多于一个磁盘参数,minio server会自动启用erasure code mode。erasure code对磁盘的个数是有要求的,如不满足要求,实例启动将失败。 erasure code启用后,要求传给minio server的endpoint(standalone模式下,即本地磁盘上的目录)至少为4个。

基于 centos

参考docker的安装方式

单节点多硬盘部署MinIO — MinIO中文文档 | MinIO Container中文文档

Linux下使用Docker安装

//拉取镜像
docker pull minio/minio   下载不了

docker pull quay.io/minio/minio   可以下载

// 创建数据存储目录
mkdir home/minio-data

// 创建minio
 docker run \
--name minio \
-p 9000:9000  \
-p 9090:9090  \
-d \
-e "MINIO_ROOT_USER=minio" \
-e "MINIO_ROOT_PASSWORD=minio123" \
-v /home/minio-data:/data \
-v /usr/local/minio-config:/root/.minio \
minio/minio server  /data --console-address ":9090" --address ":9000"

docker run --name minio -p 9000:9000  -p 9090:9090  -d -e "MINIO_ROOT_USER=minio" -e "MINIO_ROOT_PASSWORD=minio123" -v /home/minio-data:/data -v /usr/local/minio-config:/root/.minio minio/minio server  /data --console-address ":9090" --address ":9000"

下面的待测试 多磁盘的

docker run -dt                                  \
  -p 9000:9000 -p 9001:9001                     \
  -v PATH1:/data-1                              \
  -v PATH2:/data-2                              \
  -v PATH3:/data-3                              \
  -v PATH4:/data-4                              \
  -v /etc/default/minio:/etc/config.env         \
  -e "MINIO_CONFIG_ENV_FILE=/etc/config.env"    \
  --name "minio_local"                          \
  minio server --console-address ":9001"

基于docker-compose 的 分布式对象存储minio从0到高手的保姆级教程 - 知乎 (zhihu.com)

参考:Minio搭建文件服务器_minio服务器搭建-CSDN博客

MinIO Consoleicon-default.png?t=N7T8http://192.168.1.247:9090/login

其初始用户名为minio,初始密码为minio123

访问服务器9090端口

此处访问控制台的端口为9090,后面文件上传用的端口是9000

1.3 Minio入门

Java相关 Java Quickstart Guide — MinIO Object Storage for Linux

具体步骤:

1、创建Bucket

1、依赖包

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.5.11</version>
</dependency>
<!--hutool工具包-->
<dependency>
     <groupId>cn.hutool</groupId>
     <artifactId>hutool-all</artifactId>
     <version>5.8.20</version>
</dependency>

2、配置文件

3、MinioConfiguration 

@Configuration
public class MinioConfiguration {


    @Value("${minio.config.endpointUrl}")
    private String endpointUrl;

    @Value("${minio.config.accessKey}")
    private String accessKey;

    @Value("${minio.config.secretKey}")
    private String secretKey;

    @Value("${minio.config.bucketName}")
    private String bucketName;


    @Bean
    @Scope("singleton")
    public MinioClient minioClient() { // 方法名应该更具描述性,比如 minioClient
        MinioClient minioClient = MinioClient.builder()
                .endpoint(endpointUrl)
                .credentials(accessKey, secretKey)
                .build();
        return minioClient;
    }

}

 4、MinioService
 

@Service
@Slf4j
public class MinioService {

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.config.bucketName}")
    private String bucketName; // 这里注入 bucketName

    @Value("${minio.config.endpointUrl}")
    private String endpointUrl;

    /**
     * 上传文件
     * @param multipartFile
     * @return
     */
    public String fileUpload(MultipartFile multipartFile, String contentType) {

        try {
            String dateDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String uuid = UUID.randomUUID().toString().replace("-", "");
            String fileName = dateDir + "/" + uuid + multipartFile.getOriginalFilename();

            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!found) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            try (InputStream inputStream = multipartFile.getInputStream()) {
                PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .stream(inputStream, multipartFile.getSize(), -1)
                        .contentType(contentType)
                        .build();

                minioClient.putObject(putObjectArgs);
                log.info("File uploaded successfully to MinIO: {}", endpointUrl + "/" + bucketName + "/" + fileName);
                return endpointUrl + "/" + bucketName + "/" + fileName;
            }
        } catch (Exception e) {
            log.error("Error uploading file to MinIO", e);
            throw new RuntimeException("Failed to upload file to MinIO", e);
        }
    }

}

5、单元测试调用
 

@SpringBootTest(classes = {DataChatgptApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MinioFileUploadTest {

    @Autowired
    private MinioService minioService;

    @Test
    void testFilesUploadToMinio() {
        try {
            Path directory = Paths.get("src/main/resources/data/video/");
            Files.walk(directory)
                    .filter(path -> path.toFile().isFile())
                    .forEach(path -> uploadFileToMinio(path));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void uploadFileToMinio(Path filePath) {
        try {
            File file = filePath.toFile();
            String contentType = getContentType(file);
            MultipartFile multipartFile = new MockMultipartFile(
                    file.getName(),
                    file.getName(),
                    contentType,
                    new FileSystemResource(file).getInputStream());

            String fileName = minioService.fileUpload(multipartFile, contentType);
            System.out.println("File uploaded successfully to MinIO: " + fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String getContentType(File file) {
        String extension = getExtension(file).toLowerCase();
        switch (extension) {
            case "mp4":
                return "video/mp4";
            // 如果有其他文件类型,添加更多的 case
            default:
                return "application/octet-stream"; // 通用的二进制文件类型
        }
    }

    public static String getExtension(File file) {
        String fileName = file.getName();
        int lastIndexOfDot = fileName.lastIndexOf('.');
        if (lastIndexOfDot > 0) {
            return fileName.substring(lastIndexOfDot + 1);
        }
        return ""; // No extension found
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

你也想做一个Element-ui吧!!!——Blueの前端路(一)

目录 前言&#xff1a; 父子组件 button组件 使用vue脚手架初始化一个项目 如何封装&#xff0c;注册和使用一个组件 main.js中将组件设置为全局 使用 此组件我们所需实现的内容 type 父组件组件传递type属性 子组件接收负组件传递的数据 通过绑定类名的方法动态控制…

北汽蓝谷:预期能否兑现

天天提热搜&#xff0c;公司却一路亏损&#xff0c;股价却一路走高&#xff0c;今天说说——北汽蓝谷 问最近车圈谁最热&#xff0c;北汽蓝谷少不了。先是享界S9上市定档&#xff0c;华为余承东“在线带货”。 后有百度无人驾驶萝卜快跑引发全网热议&#xff0c;所用车型便来自…

TF/SD卡开发驱动(SPI)

TF与SD卡本质上来说都是flash类型的存储器 可以理解为TF卡是SD卡的升级版&#xff0c;体积小功能强大&#xff0c;SD卡是传统意义上的存储卡&#xff0c;适用范围比较广&#xff0c;而SD卡的驱动方式有两种 SDIO 和 SPI&#xff0c;同理TF卡也是一样 &#xff08;在资源足够…

2024黑马AI+若依框架项目开发 个人心得、踩坑和bug记录 全网最快最全 基础功能认识篇

2024黑马AI若依框架项目开发 个人心得、踩坑和bug记录 全网最快最全 基础功能认识篇 你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到…

[web]-图片上传、文件包含-图片上传

题目内容提示&#xff1a;上传图片试试吧&#xff0c;注意统一时区问题 打开页面如图&#xff0c;源码没有过滤&#xff0c;随便输入&#xff0c;进入上传目录 根据链接可以看到是文件包含&#xff0c;可以利用编码读取源码&#xff0c;这里只列出有用页面的编码&#xff08;?…

初识C++|类和对象(中)——类的默认成员函数

&#x1f36c; mooridy-CSDN博客 &#x1f9c1;C专栏&#xff08;更新中&#xff01;&#xff09; &#x1f379;初始C|类与对象&#xff08;上&#xff09;-CSDN博客 4. 类的默认成员函数 默认成员函数就是⽤⼾没有显式实现&#xff0c;编译器会⾃动⽣成的成员函数称为默认成…

测试开发面经总结(三)

TCP三次握手 TCP 是面向连接的协议&#xff0c;所以使用 TCP 前必须先建立连接&#xff0c;而建立连接是通过三次握手来进行的。 一开始&#xff0c;客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口&#xff0c;处于 LISTEN 状态 客户端会随机初始化序号&…

简单了解线程池

线程池 线程池的概念线程池的优势 线程池属性介绍线程池的使用简单实现线程池总结 线程池的概念 线程池(ThreadPoolExecutor) 顾名思义&#xff0c;在一个“池”中存放多个线程。 与常量池、数据库连接池等思想是一样的&#xff0c;为的都是提高效率。 我们已经领教了多线程的…

python关于excel常用函数(pandas篇)

iterrows函数&#xff1a; Pandas的基础数据结构可以分为两种&#xff1a;DataFrame和Series。不同于Series的是&#xff0c;Dataframe不仅有行索引还有列索引 。df.iterrows( )函数&#xff1a;可以返回所有的行索引&#xff0c;以及该行的所有内容。 pd.read_excel&#xf…

印尼语翻译通:AI驱动的智能翻译与语言学习助手

在这个多元文化交织的世界中&#xff0c;语言是连接我们的桥梁。印尼语翻译通&#xff0c;一款专为打破语言障碍而生的智能翻译软件&#xff0c;让您与印尼语的世界轻松接轨。无论是商务出差、学术研究&#xff0c;还是探索印尼丰富的文化遗产&#xff0c;印尼语翻译通都是您的…

材料学本科毕业6年自学Python转行AI行业,真的值得吗?

一转眼&#xff0c;步入中年。回头看看&#xff0c;这六年多的时间变化实在是太大了。换专业&#xff0c;换赛道&#xff0c;从基层做到总监&#xff0c;最终放弃管理岗位投身技术&#xff0c;这一切都与学生时代的规划相去甚远。 从大学入学到2018年转行之前&#xff0c;我的…

springboot老年慢性病药物管理系统-计算机毕业设计源码70568

目录 摘要 Abstract 第一章 绪论 1.1 选题背景及意义 1.2 国内外研究现状 1.3 研究方法 第二章 相关技术介绍 2.1 MySQL简介 2.2 Java编程语言 2.3 B/S模式 2.4 springboot框架 第三章 老年慢性病药物管理系统 系统分析 3.1 系统目标 3.2 系统可行性分析 3.2.1 技…

SIP消息结构详解

SIP协议的消息由三部分构成&#xff0c;分别是起始行&#xff08;请求行状态行)、消息头和消息体&#xff08;正文&#xff09; 一&#xff0e;起始行 1. 请求消息起始行 起始行&#xff1a;由方法名、请求URI和协议版本组成&#xff0c;自身内部用逗号分割&#xff0c;三者之…

小试牛刀-Telebot区块链游戏机器人

目录 1.编写目的 2.实现功能 2.1 Wallet功能 2.2 游戏功能 2.3 提出功能 2.4 辅助功能 3.功能实现详解 3.1 wallet功能 3.2 游戏功能 3.3 提出功能 3.4 辅助功能 4.测试视频 Welcome to Code Blocks blog 本篇文章主要介绍了 [Telebot区块链游戏机器人] ❤博主…

Vue3 前置知识

1. Vue3 简介 2020年9月18日&#xff0c;Vue.js发布版3.8版本&#xff0c;代号&#xff1a;one Piece(海贼王)经历了&#xff1a;4800次提交、40个RFC、600次PR、300贡献者官方发版地址&#xff1a;Release v3.0.0 One Piecevuejs/,core截止2023年10月&#xff0c;最新的公开版…

nginx基本概念和安装

一. 简介 1.1 是什么 nginx是一个高性能的HTTP和反向代理web服务器&#xff0c;是一款轻量级的Web服务器/反向代理服务器/电子邮件(IMAP/POP3)代理服务器&#xff0c;在BSD-like协议下发行&#xff0c;特点是占有内存少&#xff0c;并发能力强。ngnix专为性能优化而开发&#…

【TES807】 基于XCKU115 FPGA的双FMC接口万兆光纤传输信号处理平台

板卡概述 TES807是一款基于千兆或者万兆以太网传输的双FMC接口信号处理平台。该平台采用XILINX的Kintex UltraSacle系列FPGA&#xff1a;XCKU115-2FLVF1924I作为主处理器&#xff0c;FPGA外挂两组72位DDR4 SDRAM&#xff0c;用来实现超大容量数据缓存&#xff0c;DDR4的最高数据…

【软件测试】编写测试用例篇

前面部分主要是编写测试用例的方法和方向&#xff0c;后面一部分是编写出具体的测试用例 目录 什么是测试用例 1.设计测试用例的万能公式 1.1.从思维出发 1.2.万能公式 1.3.弱网测试 1.4.安装与卸载测试 2.设计测试用例的方法 2.1.基于需求的设计方法 2.2.等价类 2.3…

【Git分支管理】分支合并冲突及其解决

目录 0.合并冲突 1.创建和切换dev1 ​2.dev1 bbb on dev branch ​3.master ccc on dev branch 4.dev1和master合并冲突 5.合并冲突解决 ​6.git log查看合并流程图 先提交再合并 0.合并冲突 在使用git进行合并操作的时候&#xff0c;在合并两个分支的时候就有可能出…

【EXCELL技巧篇】使用Excel公式,获取当前 Excel的Sheet页的名字

【通知】&#xff1a; 正式跟大家说个难过的消息&#xff0c;本来在「中国朝代史」结束后&#xff0c;开启的下一个专栏「中国近代史」前面几期做的还好好的&#xff0c;可是今天起正式通知审核不过&#xff0c;因为一些原因。 其实我对于历史这一块我还是很感兴趣的&#xff0…