Minio基本使用与原理

@[toc]

一、MinIo 核心概念

  • 概念
    分布式文件系统,简称为OSS对象存储【文件,图片.......】。
    如图:
    Minio基本使用与原理_第1张图片

二、MinIo 应用场景

  • 应用场景
    主要是在微服务系统中使用。
    如图:
    Minio基本使用与原理_第2张图片

三、MinIo 项目落地

  • 条件

  • 步骤

    • 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;

          如图:
          Minio基本使用与原理_第3张图片
          Minio基本使用与原理_第4张图片

        • 下载对象

           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,并设置读和写的权限,如图:
          Minio基本使用与原理_第5张图片
          Minio基本使用与原理_第6张图片

          代码如下:

             //文件上传
             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 ("文件下载成功!");
            }
          • 删除文件

              /// 
              /// 删除文件
              /// 
              /// 
              /// 
              [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("删除成功!");
              }
          • 批量删除文件

              /// 
              /// 删除文件
              /// 
              /// 
              /// 
              [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("删除成功!");
              }
          • 拷贝文件

              /// 
              /// 复制文件
              /// 
              /// 原始文件名称
              /// 复制的文件名称
              /// 
              [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  

        执行结果如下:
        Minio基本使用与原理_第7张图片

      • 验证是否启动成功
        访问 http://10.1.57.35:9001,如图:
        Minio基本使用与原理_第8张图片

四、MinIo 文件高可用

  • 场景

    • 如果文件误删后,如何实现文件的高可用性

      • 步骤
        使用多个数据目录来存储。
        新建4个数据目录。

        • 命令

            minio.exe server  --console-address  ":9001"  D:/Assembly/MinIo/data1  D:/Assembly/MinIo/data2 D:/Assembly/MinIo/data3 D:/Assembly/MinIo/data4

          运行结果如图:
          Minio基本使用与原理_第9张图片

  • 纠删码

    • 概念
      纠删码是一种数据保护方法,它将数据分割成片段,把冗余数据块扩展、编码,并将其存储在不同的位置,比如磁盘、存储节点或者其它地理位置,通俗的说就是一个数据编码而已。
      可以理解为将对象文件进行拆分,然后进行编码,防止任意两份数据丢失。
    • 实现过程
      先将对象文件拆分成多份,进行编码(2种编码:数据编码和扩展编码)。
    • 目的
      降低对象文件的存储空间。
    • 纠删码如何保证对象文件的恢复
      如图:
      Minio基本使用与原理_第10张图片

      假如有一个文件对象,在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基本使用与原理_第11张图片

    • 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基本使用与原理_第12张图片
    在这里插入图片描述
    Minio基本使用与原理_第13张图片
    在这里插入图片描述
    Minio基本使用与原理_第14张图片

  • 实现原理
    在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)