MinIO学习
1.Minio及背景
Minio是一个开源的分布式文件存储系统,它基于 Golang 编写,虽然轻量,却拥有着不错的高性能,可以将图片、视频、音乐、pdf这些文件存储到多个主机,可以存储到多个Linux,或者多个Windows,或者多个Mac,Minio中存储最大文件可以达到5TB。任何类型的文件都是支持的,主要应用在微服务系统中。

1.使用Minio的背景
我们先回顾下,平时我们做文件存储是普遍如何操作的,简单描述下步骤和时序,例如我们在添加用户信息&上传照片这个业务中,首先客户端发起文件上传操作到API,服务将文件存储到服务器本地文件夹中,生成返回一个文件摘要,摘要包括路径,文件ID等一些基本信息,然后将这些摘要信息和用户业务数据组装程一个DTO,最终存储到数据库中。

此时我们只是一个单系统的上传文件操作,无论是业务逻辑还是技术都比较简单,但是如果是一些分布式高并发和高访问量的电商网站面临此类业务应该怎么做呢?一般电商类都是几十上百个微服务组成,如果按照单体系统的思路去实现,如果有100个微服务,那就存储在100个地方,后期的维护量岂不是令人非常头疼,加上事情做多错多,为了降低维护量,提升访问效率,我们需要将文件统一存储,基于MinIO高性能和可用性,我们选择使用MinIO来作为我们的文件管理中间件,用它承载系统文件上传下载。

2.MinIO实践
我们先上手简单操作一下MinIO,先准备环境,然后使用minio来进行文件的上传下载 ,首先我们需要下载MinIO,然后创建一个Api服务项目作为我们的文件微服务 。
1.Windows浏览器在线下载MinIO和mc客户端,官方文档地址
2.Linux直接创建对应目录输入下载命令或者下到本地拷贝进去,也可以使用Docker
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
./minio server ./data
3.准备一个Api服务作为文件微服务 说白了就是使创建一个控制器,访问这个控制器进行文件操作,然后Nuget引入操作的Minio包
4.创建一个FileUploadControll控制器来作为我们的接口,此处只演示简单的上传下载,当然它还支持分片和批量以及拷贝操作,具体的可以根据需要查看对应的api,也比较简单
[ApiController]
[Route("[controller]")]
public class FileUploadController : ControllerBase
{
private readonly ILogger<FileUploadController> _logger;
public FileUploadController(ILogger<FileUploadController> logger)
{
_logger = logger;
}
[HttpPost("Upload")]
public IActionResult Upload(IFormFile formFile)
{
//1.创建MinioClient客户端
MinioClient minioClient = new MinioClient("127.0.0.1:9000", "minioadmin", "minioadmin");
//2.创建文件桶(数据库)
if (!minioClient.BucketExistsAsync("micservice").Result)
{
minioClient.MakeBucketAsync("micservice").Wait();
}
//3.上传文件(最大上传5TB的数据)
minioClient.PutObjectAsync("product", formFile.FileName, formFile.OpenReadStream(), formFile.Length).Wait();
_logger.LogInformation($"文件:{formFile.FileName}上传到MinIO成功");
return new JsonResult("上传文件成功");
}
[HttpGet("Download")]
public IActionResult Download(string fileName)
{
FileStreamResult fileStreamResult = null;
try
{
// 1、创建MioIO客户端
MinioClient minioClient = new MinioClient("127.0.0.1:9000", "minioadmin", "minioadmin");
var imgStream = new MemoryStream();
// 2、下载图片
minioClient.GetObjectAsync("product", fileName, stream => stream.CopyTo(imgStream)).Wait();
imgStream.Position = 0;
fileStreamResult = new FileStreamResult(imgStream, "image/jpg");
}
catch (MinioException e)
{
_logger.LogInformation($"文件:{fileName}下载失败");
}
return fileStreamResult;
}
}
3.现在需要启动我们的Minio服务,进入到我们的下载目录Linux一样,然后启动命令行工具
minin.exe server ./data

我们启动后控制台会输出如下信息,首先第一部分中是我们和Minio,进程通信的服务地址和用户名密码
API: http://192.168.0.102:9000 http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin
第二部分就是minio提供给我们查看和运维的可视化界面,包含地址和用户名密码,密码账号是支持修改的
Console: http://192.168.0.102:52429 http://127.0.0.1:52429
RootUser: minioadmin
RootPass: minioadmin
3.MinIO文件高可用
在MinIO中目前我们上传的文件存储在服务器的磁盘中,我们在启动时默认创建了一个目录来存储文件bucket(文件桶,理解为存储文件的容器),这时如果删除了目录中的文件,可想而知会发生什么,所以保证文件高可用首要需求就是防止误删引发的数据丢失,直接导致用户使用文件失效。
1.常用的部署架构
在进行MInio文件高可用应对策略学习之前,我们先了解下保证系统和存储高可用层面的一些部署方式。
单机部署(stand-alone):只有一个服务实例提供服务,服务只部署一份。
集群部署(cluster):有多个服务实例同时提供服务,服务冗余部署,每个冗余的服务都对外提供服务 。
热备部署(hot-swap):只有一个服务提供服务,另一个服务stand-by,在服务挂掉时自动热替换。
服务冗余部署:只有一个主服务对外提供服务,影子服务在主服务挂掉时顶上
磁盘阵列RAID(Redundant Arrays of independent Disks)
RAID0:存储性能高的磁盘阵列,又称striping,它的原理是,将连续的数据分散到不同的磁盘上存储,这些不同的磁盘能同时并行存取数据
RAID1:安全性高的磁盘阵列,又称mirror,它的原理是,将数据完全复制到另一个磁盘上,磁盘空间利用率只有50%
RAID0+1:RAID0和RAID1的综合方案,速度快,安全性又高,但是很贵,这也是国企用的比较多的存储方案
RAID5:RAID0和RAID1的折衷方案,读取速度比较快(不如RAID0,因为多存储了校验位),安全性也很高(可以利用校验位恢复数据),空间利用率也不错(不完全复制,只冗余校验位),这也是互联网公司用的比较多的存储方案
2.多副本
通常面对这种防止误删的问题,我们使用的策略就是使用冗余多个目录来存储多个副本文件,多副本技术比较简单直接,要冗余保护关键数据,就干脆多存几份,单个数据的损坏不要紧,还有备份可以使用。同理多个目录不行,加入多个主机来存储,这种做法在很多场景下适用。
但这种方法的优缺点也比较明显,优点是写入效率高,无需多余的计算,直接存多份即可,数据恢复快,从副本复制就好了。缺点就是存储效率低、占用空间以前需要的磁盘容量直接 X2 或者 X3 倍了,对于Minio来说,文件最大可以支持5TB,那如果按照这种做法对磁盘的消耗是巨大的,就成本方面而言是不可行的,所以MinIO实现了另外一种保证文件高可用的机制,核心思想和集群方式差不多,但是对文件存储的方式跟简副本拷贝不同,Minio使用了纠删码的策略来保证我们的文件高可用。

但这种方法的优缺点也比较明显,优点是写入效率高,无需多余的计算,直接存多份即可,数据恢复快,从副本复制就好了。缺点就是存储效率低、占用空间以前需要的磁盘容量直接 X2 或者 X3 倍了,对于Minio来说,文件最大可以支持4个G,那如果按照这种做法对磁盘的消耗是巨大的,就成本方面而言是不可行的,所以Minio实现了另外一种保证文件高可用的机制,核心思想和集群方式差不多,但是对文件存储的方式跟简副本拷贝不同,Minio使用了纠删码的策略来保证我们的文件高可用。
3.纠删码
在这里我们需要搞清楚的问题有好几个,先列出来吧,当然只是简单的介绍,具体深入还是需要自己去了解一下。
1.什么是RAID?
RAID中文简称为独立磁盘冗余磁盘阵列。简单的说,RAID是一种把多块独立的物理硬盘)按不同的方式组合起来形成一个硬盘组(逻辑硬盘),从而提供比单个硬盘更高的存储性能和提供
数据备份技术。
2.什么是纠删码?
一种数据冗余保护技术,RAID的延伸,纠删码不仅具备识别错码和纠正错码的功能,而且当错码超过纠正范围时可把无法纠错的信息删除。
我们使用一个简单的例子来理解纠删码,首先从冗余思想来着手,假设我们在存储一份大小为2M的文件时,按照4份副本冗余的做法,占用的空间就是 2Mx4的空间,先将文件分片为2份,我们取名为Sharding1、Sharding2,然后再做冗余 就是4份数据,如果我们删除A1和A2那么A3和A4可以继续组合成一个完整的文件,同理删除A3和A4它依然可以组合成完整文件。

这时我们思考,如果我们同时删除分片1的数据A1和A3,剩下A2和A4中都是分片2的数据,不就组合不成了吗?

此时如果使用纠删码的做法就是,A1和A2分片数据还是保持不变,A3=分片1+分片2,A4 = 分片1+ 2*分片2,这样任意两份数据丢失,都可以恢复出分片1 和 分片2的数据了

1.使用传统副本冗余至少2个数据目录,如果分片后就需要最少4份数据。
2.Minio按照最少分片2个的话,至少需要4个数据目录,必须有一半数据,数据不丢失,才能恢复(N/2)。
3.纠删码可以恢复任何磁盘损坏的数据,包括人为删除、磁盘信道丢失、磁盘中毒。
4.MinIO文件监听及多租户
1.文件监听
有时我们想把客户端上传下载文件的一些操作,存储起来,方便以后做数据分析,最简单的做法我们可以使用写日志的方式,但是目前要做的不是介绍这种,而是使用MioIO自带的文件监听机制,MinIO允许我们配置存储操作日志的存储介质,例如Mysql、Redis、Elastic Search、Kafka、WebHook等等,MinIO可以设置对某一个Bucket实现事件监听。
1.首先我们需要在Console中配置存储介质,此处选择 Mysql
1.在mysql中创建一个可供MinIO存储操作的数据库。
2.在MinIO中配置数据库名称、表以及其他连接信息。

2.重启MinIO服务,并指定Console地址为9001,
minio server --address :9000 --console-address ":9001" ./data
重启后控制台会给出操作Mysql的队列名
arn:minio:sqs::_:mysql
3.启动MinIO自带的命令客户端mc.exe,给MinIO的Api地址取一个别名为minio_queue,方便后续使用
mc.exe alias set minio_queue http://127.0.0.1:9000 minioadmin minioadmin
4.然后执行客户端命令。用于告诉MinIO服务将文件Bucket 和 Mysql队列事件注册绑定
下面命令的意思是对minio_queue服务中的micservice这个Bucket添加增、删、改、查的监听事件到arn:minio:sqs::_:mysql中,说白了就是如果对这个桶中的文件进行操作,那么就会写入日志到Mysql中
mc event add --event "put,delete" minio_queue/micservice arn:minio:sqs::_:mysql
2.MinIO多租户
Minio默认会给一个客户使用,当客户变多了之后,所有客户的数据都集中在Minio内部的时候,导致数据冲突的问题。例如客户A的数据,可能会修改成客户B的数据,客户B可能查询客户C的数据。所以解决客户数据冲突问题,我们采用多租户来实现,说白了就是系统运行多个实例给多个不同的客户使用,为不同的客户端提供服务。

执行如下命令,创建3个minio实例,为三个不同租户提供服务
minio server --address :8001 --console-address ":9001" ./MinIO/tenant1
minio server --address :8002 --console-address ":9001" ./MinIO/tenant2
minio server --address :8003 --console-address ":9001" ./MinIO/tenant3
MinIO学习的更多相关文章
- 在Linux系统下搭建和配置一个minio文件服务器(一)
1.minio文件服务器的介绍 Minio 是一个基于Go语言的对象存储服务.它实现了大部分亚马逊S3云存储服务接口,可以看做是是S3的开源版本,非常适合于存储大容量非结构化的数据,例如图片.视频.日 ...
- Github 29K Star的开源对象存储方案——Minio入门宝典
对象存储不是什么新技术了,但是从来都没有被替代掉.为什么?在这个大数据发展迅速地时代,数据已经不单单是简单的文本数据了,每天有大量的图片,视频数据产生,在短视频火爆的今天,这个数量还在增加.有数据表明 ...
- docker安装minio
目录 一.简介 二.docker安装 三.java中使用minio上传与下载 一.简介 MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能对象存储. 它是与 Amazon ...
- MinIO多租户(Multi-tenant)部署指南
官方文档地址:http://docs.minio.org.cn/docs/master/multi-tenant-minio-deployment-guide 单机部署 在单台机器上托管多个租户,为每 ...
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
随机推荐
- 最新漏洞:Spring Framework远程代码执行漏洞
Spring Framework远程代码执行漏洞 发布时间 2022-03-31 漏洞等级 High CVE编号 CVE-2022-22965 影响范围:同时满足以下三个条件可确定受此漏洞影响: JD ...
- 一道关于压缩包的ctf题目(包括暴力破解,明文攻击,伪加密)
关于题目附件 链接:https://pan.baidu.com/s/1PRshlizSndkgxkslnqJrHA 提取码:p76e zip三连击 下载附件得到题目 手机号码一般是11位,那么我们设置 ...
- 【静态页面架构】CSS之定位
CSS架构 1.浮动: 是以float属性设置容器指定的位置 <style> div { width: 200px; height: 200px; } #qq { background-c ...
- Day 19: EmberJS 入门指南
编者注:我们发现了有趣的系列文章<30天学习30种新技术>,正在翻译,一天一篇更新,年终礼包.下面是第19天的内容. 到目前为止,我们这一系列文章涉及了Bower.AngularJS.Gr ...
- C#委托、多播委托极简案例,一看就懂
废话不多讲,直接上代码,看完代码再讲解: class Class1 { public delegate void Del();//声明委托 public static void F1() { Cons ...
- 大数据学习之路之ambari的安装
之前按照正常方式安装的hbase不能插入数据 所以今天来尝试下ambari能不能行 已经打了快照 如果不能还能恢复之前的样子
- JS实现列表移动(通过DOM操作select标签)
JS小例题 学习内容: 需求 总结: 学习内容: 需求 用 JavaScript 实现 select 标签的移动 实现代码 <!DOCTYPE html PUBLIC "-//W3C/ ...
- 开源.net core 验证码 - LazyCaptcha
LazyCaptcha 介绍 LazyCaptcha是仿EasyCaptcha和SimpleCaptcha,基于.Net Standard 2.1的图形验证码模块. 项目地址 效果展示 Captcha ...
- Mycat管理
Mycat 提供了类似数据库的管理监控方式,可以通过 mycat 端口 9066 执行相应的 SQL 语句进行管理,可以可以通过 navicat 软件进行远程连接管理,再使用 MySQL 命令行界面登 ...
- java四种访问修饰符及各自的权限
1.public,即共有的,是访问权限限制最宽的修饰符.被public修饰的类.属性.及方法不仅可以跨类访问,而且可以跨包访问. 2. protected,即保护访问权限,是介于public和priv ...