MinIO是什么?

一种对象存储解决方案,它是一个基于

Minio 提供与亚马逊云科技 S3 兼容的 API,并支持所有核心 S3 功能, 所以也可以看做是S3的开源版本;它允许用户通过简单的 API 接口进行数据的存储和检索,同时提供高度可扩展性和强大的数据保护机制。

MinIo主要是在微服务系统中使用,非常适合于存储大容量非结构化的数据,例如 图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小

MinIO特点?

  • 高可用性:MinIO 支持分布式部署,可以在多个节点上实现数据冗余和负载均衡,从而提供高可用性和容错能力。
  • 高性能:MinIO 的设计目标是提供快速的数据访问速度。它采用了高度优化的底层存储引擎,并且支持并行读写操作,以满足大规模数据访问的需求。
  • 可扩展性:MinIO 可以根据实际需求进行水平扩展,用户可以根据数据量的增长来增加节点数量,从而实现存储容量和性能的扩展。
  • 数据保护:MinIO 提供了多种数据保护机制,包括数据加密、数据完整性校验和故障恢复等。用户可以根据需要选择适当的保护机制来保障数据的安全性和可靠性。
  • 兼容性:MinIO 兼容 Amazon S3 云存储服务(AWS Signature v2 和 v4) API,这意味着用户可以直接使用现有的 S3 工具和应用程序与 MinIO 进行集成,而无需进行修改。

MinIO系统搭建

C盘意外盘符创建MinIO文件夹,并在其中创建MinData文件夹,用来存放数据

Minio高性能分布式对象存储_Minio

MinIO官网下载MinIO服务器(Windows版本),下载文件放在MinIO文件夹

Minio高性能分布式对象存储_上传_02

配置环境变量:账号变量名MINIO_ROOT_USER 变量值:admin密码变量名MINIO_ROOT_PASSWORD 变量值:admin123

Minio高性能分布式对象存储_上传_03

启动MinIO服务器MinIO文件夹=>cmd=>minio.exe server MinData --console-address ":9001"MinData为存放数据文件夹名称

Minio高性能分布式对象存储_上传_04

使用 http://xx.xx.xx.xx:9000进入MinIO控制台页面

Minio高性能分布式对象存储_数据_05

Minio高性能分布式对象存储_上传_06

MinIO存储桶操作查看存储桶列表

Minio高性能分布式对象存储_Minio_07

创建存储桶

Minio高性能分布式对象存储_Minio_08

查看存储桶内存储列表

Minio高性能分布式对象存储_Minio_09

Minio高性能分布式对象存储_Minio_10

.net 6对接MinIO创建文件上传WebAPI,创建FileUpload控制器添加NuGet包:Minio、Newtonsoft.Json

Minio高性能分布式对象存储_数据_11

MinIO配置

Minio高性能分布式对象存储_上传_12

private readonly IMinioClient _minioClient;
private string bucketName = "sheepimages";

public FileController()
{
    _minioClient = new MinioClient()
                    .WithEndpoint("10.31.60.18:900")
                    .WithCredentials("admin", "admin123")
                    .WithSSL(false);    
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
MinIO查看桶列表

Minio高性能分布式对象存储_上传_13

public async Task<IActionResult> ListBuckets()
{
    ListAllMyBucketsResult? buckets = await _minioClient.ListBucketsAsync().ConfigureAwait(false);
    return Ok(buckets);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

封装检查存储桶是否存在方法,因为都要用到

Minio高性能分布式对象存储_上传_14

/// <summary>
/// 检查存储桶是否存在,如果不存在则创建该存储桶。
/// </summary>
/// <param name="bucketName">要检查或创建的存储桶名称。</param>
/// <returns>Task</returns>
private async Task EnsureBucketExists(string bucketName)
{
    BucketExistsArgs beArgs = new BucketExistsArgs().WithBucket(bucketName);
    bool found = await _minioClient.BucketExistsAsync(beArgs).ConfigureAwait(false);

    if (!found)
    {
        MakeBucketArgs mbArgs = new MakeBucketArgs().WithBucket(bucketName);
        await _minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
MinIO上传单个文件

Minio高性能分布式对象存储_Minio_15

/// <summary>
/// 上传单个文件到指定的存储桶。如果存储桶不存在,将自动创建该存储桶。
/// </summary>
/// <param name="file">要上传的文件,该参数是一个 IFormFile 类型,表示从 HTTP 请求中上传的文件。</param>
/// <returns>返回一个 IActionResult,包含上传后文件的预签名 URL。</returns>
[HttpPost]
public async Task<IActionResult> UploadFile(IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return BadRequest("上传的文件不能为空。"); // 检查文件是否有效
    }

    try
    {
        // 确保存储桶存在
        await EnsureBucketExists(bucketName);

        // 为避免文件名冲突,生成唯一的对象名称
        string objectName = Guid.NewGuid().ToString() + "_" + file.FileName;

        // 创建上传对象的参数
        PutObjectArgs poArgs = new PutObjectArgs()
                                .WithBucket(bucketName)
                                .WithObject(objectName)
                                .WithStreamData(file.OpenReadStream())
                                .WithContentType(file.ContentType)
                                .WithObjectSize(file.Length);

        // 上传文件到 MinIO
        await _minioClient.PutObjectAsync(poArgs).ConfigureAwait(false);

        // 创建预签名 URL,设置有效期为7200秒(2小时)
        PresignedGetObjectArgs getArgs = new PresignedGetObjectArgs()
                                .WithBucket(bucketName)
                                .WithObject(objectName)
                                .WithExpiry(7200);

        // 生成预签名 URL
        string url = await _minioClient.PresignedGetObjectAsync(getArgs).ConfigureAwait(false);

        // 返回包含预签名 URL 的 JSON 对象
        return Ok(new { url });
    }
    catch (Exception ex)
    {
        // 处理异常,返回错误信息
        return StatusCode(500, $"文件上传失败: {ex.Message}");
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
MinIO上传多个文件

Minio高性能分布式对象存储_数据_16

/// <summary>
/// 批量上传文件到指定的存储桶。如果存储桶不存在,将自动创建该存储桶。
/// </summary>
/// <param name="formFiles">要上传的文件集合,该参数是 IFormFileCollection 类型,表示多个从 HTTP 请求中上传的文件。</param>
/// <returns>返回一个 IActionResult,包含上传后文件的名称列表或错误信息。</returns>
[HttpPost] // 改为 POST 方法
public async Task<IActionResult> UploadFiles(IFormFileCollection formFiles)
{
    if (formFiles == null || formFiles.Count == 0)
    {
        return BadRequest("没有上传任何文件。"); // 检查是否上传了文件
    }

    try
    {
        // 确保存储桶存在
        await EnsureBucketExists(bucketName);

        List<string>? formFileList = new List<string>();

        // 遍历所有上传的文件
        foreach (IFormFile formFile in formFiles)
        {
            // 打开文件的读取流
            using Stream? stream = formFile.OpenReadStream();

            // 为避免文件名冲突,生成唯一的对象名称
            string? objectName = Guid.NewGuid().ToString() + "_" + formFile.FileName;

            // 将文件名称添加到文件列表中
            formFileList.Add(objectName);

            // 创建上传对象的参数
            PutObjectArgs? putArgs = new PutObjectArgs()
                                    .WithBucket(bucketName)
                                    .WithObject(objectName)
                                    .WithStreamData(stream)
                                    .WithContentType(formFile.ContentType)
                                    .WithObjectSize(formFile.Length);

            // 上传文件到 MinIO
            await _minioClient.PutObjectAsync(putArgs).ConfigureAwait(false);
        }

        // 返回上传成功后的文件名称列表
        return Ok(formFileList);
    }
    catch (Exception ex)
    {
        // 处理异常,返回错误信息
        return StatusCode(500, $"文件上传失败: {ex.Message}");
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.