Minio基本使用与原理

本文详细介绍了MinIo的核心概念,包括其作为分布式文件系统在微服务中的应用,项目落地实战步骤,文件高可用性配置,文件监听机制以及多租户部署。涵盖了文件上传、下载、删除、复制,以及如何利用纠删码确保数据安全和使用文件监听功能。

一、MinIo 核心概念

  • 概念
    分布式文件系统,简称为OSS对象存储【文件,图片…】。
    如图:
    在这里插入图片描述

二、MinIo 应用场景

  • 应用场景
    主要是在微服务系统中使用。
    如图:
    在这里插入图片描述

三、MinIo 项目落地

  • 条件
    • Demo项目
    • MinIO
      下载地址:
      链接:https://pan.baidu.com/s/1x-xETi3hkmxbniJEFJkFyg
      提取码:tbz9
  • 步骤
    • Demo项目
      • 步骤
        • 添加Nuget包

          //添加 Nuget包
           Minio
          
        • 建立MinIo客户端连接

              MinioClient minioClient = new MinioClient("Ip地址:端口号","用户名","密码");
          
        • 创建文件桶

              // 判断是否有文件桶
              if(!minioClient.BucketExistsAsync("文件桶名称").Result)
              {
                  minioClient.MakeBucketAsync("文件桶名称");
              }
          
        • 上传对象

              minioClient.PutObjectAsync("文件桶名称",上传的文件名称,文件流,文件长度).Wait();  
              minioClient.PutObjectAsync("文件桶名称","上传的文件名称","文件路径【D://...路径到文件名称.后缀】").Wait(); 
              //生成上传文件链接,返回一个生成文件的路径,需要后端系统中新建一个Access Key和Secret Key,才能使用,
              //将客户端连接的用户名和密码改为Access Key和Secret Key,并设置读和写的权限
              minioClient.PresignedPutObjectAsync("文件桶名称",上传的文件名称,过期时间【单位:秒】).Result;
          

          如图:
          在这里插入图片描述
          在这里插入图片描述

        • 下载对象

           minioClient.GetObjectAsync("文件桶名称",文件名称,输出流地址).Wait();
           minioClient.GetObjectAsync("文件桶名称",文件名称,从什么地方开始【0】,下载的长度,输出流地址).Wait();//分段下载对象
          
        • 刪除对象

          • 单个删除
              minioClient.RemoveObjectAsync("文件桶名称", 对象名称.后缀);
            
          • 多个删除
             minioClient.RemoveObjectAsync("文件桶名称", 对象名称.后缀集合).Wait();
            
        • 对象拷贝

           minioClient.CopyObjectAsync("原文件桶名称", 源文件名称.后缀, "目的地文件桶名称", 新文件名称.后缀).Wait();
          
      • 整体代码如下
        • 文件上传

             //文件上传
             public  IActionResult Upload(IFormFile fromFile)
             {
                //建立MinIo客户端连接
                MinioClient minioClient = new MinioClient("127.0.0.1:9000","minioadmin","minioadmin");
                // 判断是否有文件桶
                if(!minioClient.BucketExistsAsync("test").Result)
                {
                  minioClient.MakeBucketAsync("test");
                }
                //上传文件
                minioClient.PutObjectAsync("test",fromFile.FileName,fromFile.OpenReadStream,fromFile.Length).Wait();
                return Ok ("文件上传成功!");
             }
          
        • 文件上传链接生成【网站服务端不建议使用】
          目的:MinIo 支持上传5TB的对象,但是网站不支持上传5TB对象,所以采用生成文件上传链接方式来解决,不建议使用网站服务端的方式来实现【网站服务端没有设置key和签名的api方法】,建议使用js直接连接MinIo客户端的方式来实现上传大文件。
          新建Access Key 和Secret Key,并设置读和写的权限,如图:
          在这里插入图片描述
          在这里插入图片描述

          代码如下:

             //文件上传
             public  IActionResult UploadBigFile(IFormFile fromFile)
             {
                //建立MinIo客户端连接
                MinioClient minioClient = new MinioClient("127.0.0.1:9000","Access Key","Secret Key");
                // 判断是否有文件桶
                if(!minioClient.BucketExistsAsync("test").Result)
                {
                  minioClient.MakeBucketAsync("test");
                }
                //生成大文件上传链接,返回一个文件上传路径
                string Url = minioClient.PresignedPutObjectAsync("test",fromFile.FileName,60*60*24).Result;
                return Ok ("文件路径生成成功!");
             }
          
        • 批量文件上传

               public IActionResult Upload(IFormFile[] formFiles)
               {
                  foreach (var formFile in formFiles)
                  {
                      //建立MinIo客户端连接
                      MinioClient minioClient = new MinioClient("127.0.0.1:9000", "minioadmin", "minioadmin");
                      // 判断是否有文件桶
                      if (!minioClient.BucketExistsAsync("test").Result)
                      {
                          minioClient.MakeBucketAsync("test");
                      }
                      //生成大文件上传链接,返回一个文件上传路径
                      minioClient.PutObjectAsync("test", formFile.FileName, formFile.OpenReadStream(), formFile.Length);
                  } 
                  return Ok("文件上传成功!");
               }
          
        • 文件下载

          • 单文件下载
               //文件下载
             public  IActionResult DownLoad(string  fileName)
             {
               FileStreamResult fileStreamResult = null;
               try
               {
                 //建立MinIo客户端连接
                 MinioClient minioClient = new MinioClient("127.0.0.1:9000","minioadmin","minioadmin");
                 var imaStream =  new MemortStream()
                 //下载文件
                 minioClient.GetObjectAsync("test",fileName,stream=>{stream.CopyTo(imaStream)}).Wait();
                 imaStream.Position = 0;
                 //指定对象类型 
                 fileStreamResult = new FileStreamResult(imaStream,"img/jpg");
                }
               catch(Exception ex)
               {
                        
               }
               return Ok ("文件下载成功!");
             }
            
          • 分段文件下载
              //文件下载
            public  IActionResult DownLoadShard(string  fileName)
            {
              FileStreamResult fileStreamResult = null;
              try
              {
                //建立MinIo客户端连接
                MinioClient minioClient = new MinioClient("127.0.0.1:9000","minioadmin","minioadmin");
                var imaStream =  new MemortStream()
                //分段下载文件  注意: 数字是字节单位
                minioClient.GetObjectAsync("test",fileName,0,100,stream=>{stream.CopyTo(imaStream)}).Wait();
                minioClient.GetObjectAsync("test",fileName,101,1000,stream=>{stream.CopyTo(imaStream)}).Wait();
                imaStream.Position = 0;
                //指定对象类型 
                fileStreamResult = new FileStreamResult(imaStream,"img/jpg");
               }
              catch(Exception ex)
              {
                       
              }
              return Ok ("文件下载成功!");
            }
            
          • 删除文件
              /// <summary>
              /// 删除文件
              /// </summary>
              /// <param name="fileName"></param>
              /// <returns></returns>
              [HttpDelete("{fileName}")]
              public IActionResult DeleteFile(string fileName)
              {
                  //建立MinIo客户端连接
                  MinioClient minioClient = new MinioClient("127.0.0.1:9000", "minioadmin", "minioadmin");
                  // 判断是否有文件桶
                  if (!minioClient.BucketExistsAsync("test").Result)
                  {
                      minioClient.MakeBucketAsync("test");
                  }
                  //生成大文件上传链接,返回一个文件上传路径
                  minioClient.RemoveObjectAsync("test", fileName);
                  return Ok("删除成功!");
              }
            
          • 批量删除文件
              /// <summary>
              /// 删除文件
              /// </summary>
              /// <param name="fileName"></param>
              /// <returns></returns>
              [HttpDelete("DeleteBatchFile")]
              public IActionResult DeleteBatchFile(string[] fileNames)
              {
                  //建立MinIo客户端连接
                  MinioClient minioClient = new MinioClient("127.0.0.1:9000", "minioadmin", "minioadmin");
                  // 判断是否有文件桶
                  if (!minioClient.BucketExistsAsync("test").Result)
                  {
                      minioClient.MakeBucketAsync("test");
                  }
                  //生成大文件上传链接,返回一个文件上传路径
                  minioClient.RemoveObjectAsync("test", fileNames.ToList()).Wait();
                  return Ok("删除成功!");
              }
            
          • 拷贝文件
              /// <summary>
              /// 复制文件
              /// </summary>
              /// <param name="fileName">原始文件名称</param>
              /// <param name="destFileName">复制的文件名称</param>
              /// <returns></returns>
              [HttpPost("FileCopy")]
              public IActionResult FileCopy(string fileName,string destFileName) 
              {
                  MinioClient minioClient = new MinioClient("127.0.0.1:9000", "minioadmin", "minioadmin");
                  if (!minioClient.BucketExistsAsync("testnew").Result)
                  {
                      minioClient.MakeBucketAsync("testnew");
                  }
                  minioClient.CopyObjectAsync("test", fileName, "testnew", destFileName).Wait();
                  return Ok("复制成功!");
              }
            
    • 启动MinIO
      • 运行命令

         #在根目录下执行命令启动 
         #minio.exe :服务启动命令
         #server:是以服务端的方式启动
         #--console-address ":9001":将动态端口改为静态端口
         #D:\MinIo\data:数据目录 
         minio.exe server --console-address ":9001" D:\MinIo\data  
        

        执行结果如下:
        在这里插入图片描述

      • 验证是否启动成功
        访问 http://10.1.57.35:9001,如图:
        在这里插入图片描述

四、MinIo 文件高可用

  • 场景

    • 如果文件误删后,如何实现文件的高可用性
      • 步骤
        使用多个数据目录来存储。
        新建4个数据目录。
        • 命令
            minio.exe server  --console-address  ":9001"  D:/Assembly/MinIo/data1  D:/Assembly/MinIo/data2 D:/Assembly/MinIo/data3 D:/Assembly/MinIo/data4
          
          运行结果如图:
          在这里插入图片描述
  • 纠删码

    • 概念
      纠删码是一种数据保护方法,它将数据分割成片段,把冗余数据块扩展、编码,并将其存储在不同的位置,比如磁盘、存储节点或者其它地理位置,通俗的说就是一个数据编码而已。
      可以理解为将对象文件进行拆分,然后进行编码,防止任意两份数据丢失。

    • 实现过程
      先将对象文件拆分成多份,进行编码(2种编码:数据编码和扩展编码)。

    • 目的
      降低对象文件的存储空间。

    • 纠删码如何保证对象文件的恢复
      如图:
      在这里插入图片描述

      假如有一个文件对象,在minIO中会拆分成A1和A2两份相同的数据,再将数据存储为 X1、X2、X3、X4 数据文件中,让其分别等于 A1,A2,A1,A2;这样假设数据X1和X2数据丢失了,那么数据可以从X3和X4中恢复。但是这样存储会出现问题:如果数据X1 和 X3 数据丢失了,那么原先的数据A1就彻底找回来了;但是可以使用下面的一种存储方式X1和X2还是不变,X3 = A1+A2;X4=A1+2*A2,这样任意两份数据丢失,都可以恢复A1和A2了,如图:
      在这里插入图片描述

    • MinIo使用纠删码
      MinIo的数据目录至少有四个,并且是偶数目录数。

      • 规则
        四个数据目录中必须有一半数据目录数据不丢失才能恢复。
      • 纠删码的特征
        可以恢复任何的损坏的数据,比如:误删除,磁盘损坏,磁盘中毒等。

五、MinIo 文件监听

  • 工具

    • Mysql 数据库
    • MinIo
  • 步骤
    1、打开 MinIo 后台管理系统
    2、点击Setting 目录
    3、点击 Notification 目录
    4、点击 Add Notification Target 按钮
    5、选择Mysql数据库或者其他数据库(前提是手动建好数据库),然后输入:数据库的IP地址,数据库名称,数据库端口号,数据库用户名和密码,数据库表名(可以不用手动新建);
    6、再点击保存
    7、再次重新启动MinIo
    8、关联文件桶并往队列中发送消息
    命令:

      #在MinIo根目录下执行
      #建立连接
      mc.exe alias set 连接地址别名【随意起】 http://10.1.57.35:9000 minioadmin minioadmin
      #监听单个关联文件桶
      mc event add --event  "put,delete" 连接地址别名/文件桶名称 arn:minio:sqs::_:mysql
    

    如图:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 实现原理
    在MinIo内部会有一个内存队列,通过队列发给数据库;Mino相当于生产者—>MinIo内部队列<—监听–Mysql 数据库(消费者)

六、MinIo 多租户

  • 多个服务对应多个MinIO
    就是使用不同的端口,并且数据目录是不一样的才可以;
        #在MinIo根目录下执行
        #9002 Minio API连接端口号
        #9003 MinIo后台管理系统端口号
        #Window 环境中
         minio.exe server --address :9002  --console-address  ":9003"  数据目录  数据目录1
        #Linux 环境中  
        #注意:在Linux系统中创建数据目录,有几个数据目录就得有几个磁盘才行
         minio.exe server --address :9002  --console-address  ":9003"  数据目录{1..4}
    
### MinIO 工作原理分布式对象存储架构设计 MinIO 是一种高性能的对象存储解决方案,其核心设计理念围绕着分布式系统的高效性和可扩展性展开。以下是关于 MinIO 的工作原理及其分布式对象存储架构设计的关键点: #### 1. **MinIO基本组成** MinIO 提供了一种轻量级的服务器端实现,支持通过 RESTful API 或者兼容 Amazon S3 的接口访问数据[^2]。它的典型部署场景包括多个节点组成的分布式集群,其中每个节点可以是一个独立的物理设备或者虚拟机。 - **存储桶 (Bucket)** 存储桶是 MinIO 中用于组织和管理对象的基本单元。在实际应用中,用户可以根据业务需求创建不同的存储桶来分类保存文件。例如,在给定的例子中存在 `images`、`videos` 和 `articles` 这样的存储桶结构[^1]。 - **对象 (Object)** 对象代表具体的数据实体,通常是以二进制形式存在的文件MinIO 支持大容量对象上传,并能够按照预定义规则自动生成目录层次结构以便于检索和维护。 #### 2. **高可用性一致性机制** 为了保障数据的安全可靠以及读写操作的一致性,MinIO 实现了一系列先进的技术手段: - **Erasure Code 编码** Erasure Code 技术被广泛应用于 MinIO 来提高磁盘利用率并增强容错能力。当启用此功能时,原始数据会被分割成若干片段并通过冗余编码生成额外校验信息分布到不同位置上。即使部分硬件发生故障丢失某些分片的情况下仍能恢复完整的资料集。 - **Quorum Consensus 协议** 在多副本模式下,MinIO 使用 Quorum Consensus 方法达成全局状态同步目标。这意味着只有超过半数以上的成员确认提交成功之后才会对外宣布事务完成从而确保强一致性的用户体验[^3]。 #### 3. **水平扩展特性** 得益于原生支持的分布式架构特点,MinIO 能够轻松应对海量规模的增长挑战而无需担心性能瓶颈问题出现: - **线性增长模型** 随着新增加更多计算资源加入进来形成更大范围内的联合体后,整体吞吐能力和并发处理请求的数量都会相应增加保持比例关系不变. - **动态再平衡过程** 当检测到现有配置发生变化(比如新添加节点或是移除旧有成员),系统内部会启动自动化迁移流程重新分配已存档项目至最佳候选地点直至达到均衡状态为止. ```python import minio client = minio.Minio( "play.min.io", access_key="Q3AM3UQ867SPQQA43P2F", secret_key="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG" ) buckets = client.list_buckets() for bucket in buckets: print(bucket.name, bucket.creation_date) ``` 上述代码展示了如何利用 Python SDK 初始化连接并远程 MinIO 服务交互获取当前所有可用 Bucket 列表的信息。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值