写点什么

Minio 基本使用与原理

作者:神秘码农
  • 2022 年 4 月 22 日
  • 本文字数:6326 字

    阅读完需:约 21 分钟

@[toc]

一、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;
复制代码


    如图:    ![在这里插入图片描述](https://img-blog.csdnimg.cn/59852a2c8a464b75ae919d52566ebc9a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQEDnpZ7lhpzlhpnku6PnoIE=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
复制代码



  - 下载对象
复制代码


          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,并设置读和写的权限,如图:    ![在这里插入图片描述](https://img-blog.csdnimg.cn/183a0c5163554934af6cc196d5bdff35.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQEDnpZ7lhpzlhpnku6PnoIE=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
复制代码



    代码如下:
复制代码


           //文件上传           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  
复制代码


  执行结果如下:  ![在这里插入图片描述](https://img-blog.csdnimg.cn/8af974ade5a84909a5d2d7e70c676ed5.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQEDnpZ7lhpzlhpnku6PnoIE=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
- 验证是否启动成功 访问 http://10.1.57.35:9001,如图: ![在这里插入图片描述](https://img-blog.csdnimg.cn/c4e0eaf959bb4935829e8083e7adfc71.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQEDnpZ7lhpzlhpnku6PnoIE=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
复制代码

四、MinIo 文件高可用

  • 场景

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

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

  • 命令


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


    运行结果如图:    ![在这里插入图片描述](https://img-blog.csdnimg.cn/f951804eb316470b8f7b5ea970a823d7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQEDnpZ7lhpzlhpnku6PnoIE=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
复制代码


  • 纠删码

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

  • 实现过程先将对象文件拆分成多份,进行编码(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、再次重新启动 MinIo8、关联文件桶并往队列中发送消息命令:


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


 如图:![在这里插入图片描述](https://img-blog.csdnimg.cn/1faa7568def04ef096127c1f6365c326.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQEDnpZ7lhpzlhpnku6PnoIE=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
复制代码






  • 实现原理在 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}
复制代码


发布于: 刚刚阅读数: 3
用户头像

神秘码农

关注

还未添加个人签名 2022.03.14 加入

好好学习,天天向上!

评论

发布
暂无评论
Minio基本使用与原理_神秘码农_InfoQ写作社区