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
    }
}

相关推荐

  1. 文件服务器

    2024-07-15 15:56:06       58 阅读
  2. CentOS7.x中用DockerMinio服务器

    2024-07-15 15:56:06       33 阅读
  3. DockerMinIO

    2024-07-15 15:56:06       40 阅读
  4. 开源项目_对象存储服务MinIO

    2024-07-15 15:56:06       36 阅读
  5. 华纳云:如何一个简易文件服务器?

    2024-07-15 15:56:06       46 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-15 15:56:06       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-15 15:56:06       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-15 15:56:06       58 阅读
  4. Python语言-面向对象

    2024-07-15 15:56:06       69 阅读

热门阅读

  1. 如何rpmbuild打包GLIBC二进制库文件?

    2024-07-15 15:56:06       19 阅读
  2. 认知偏差知识手册

    2024-07-15 15:56:06       20 阅读
  3. Python 实现技术指标邮件告警通知

    2024-07-15 15:56:06       19 阅读
  4. ESP-01S + STM32物联网

    2024-07-15 15:56:06       20 阅读
  5. Spring Cloud微服务开发框架

    2024-07-15 15:56:06       20 阅读
  6. 关于c语言在内存中的分配管理

    2024-07-15 15:56:06       19 阅读
  7. Scala之基础面向对象编程

    2024-07-15 15:56:06       19 阅读
  8. Linux入侵排查

    2024-07-15 15:56:06       19 阅读
  9. 短剧app系统开发

    2024-07-15 15:56:06       23 阅读
  10. Vue响应式源码解析

    2024-07-15 15:56:06       18 阅读
  11. qt 创建一个左侧边线,可以向左侧拖拽的矩形

    2024-07-15 15:56:06       24 阅读
  12. 关于vue环境变量的使用

    2024-07-15 15:56:06       14 阅读
  13. 软件测试中Bug分析的艺术:方法与实践

    2024-07-15 15:56:06       20 阅读