长沙一女子与“相亲对象”打麻将,2小时输12800元! 近日,长沙一女子在相亲网结识一名“趣味相投”男子,相约见面竟遭“杀猪盘”,打两小时麻将输了...
.NET 学习 MinIO高性能对象存储
↓推荐关注↓
一、Minio及背景
Minio是一个开源的 分布式文件存储系统,它基于 Golang 编写,虽然 轻量,却拥有着不错的 高性能,可以将图片、视频、音乐、pdf这些文件存储到多个主机,可以存储到多个Linux,或者多个Windows,或者多个Mac,Minio中存储 最大文件可以达到 5TB。
任何类型的文件都是 支持的,主要应用在微服务系统中。
1、使用Minio的背景
我们先回顾下,平时我们做文件存储是普遍如何操作的,简单描述下步骤和时序,例如我们在添加用户信息&上传照片这个业务中,首先客户端发起文件上传操作到API,服务将文件存储到服务器本地文件夹中,生成返回一个文件摘要,摘要包括路径,文件ID等一些基本信息,然后将这些摘要信息和用户业务数据组装程一个DTO,最终存储到数据库中。
此时我们只是一个单系统的上传文件操作,无论是业务逻辑还是技术都比较简单,但是如果是一些分布式高并发和高访问量的电商网站面临此类业务应该怎么做呢?一般电商类都是几十上百个微服务组成,如果按照单体系统的思路去实现,如果有100个微服务,那就存储在100个地方,后期的维护量岂不是令人非常头疼,加上事情做多错多,为了降低维护量,提升访问效率,我们需要将文件统一存储,基于MinIO高性能和可用性,我们选择使用MinIO来作为我们的文件管理中间件,用它承载系统文件上传下载。
展开全文
二、MinIO实践
我们先上手简单操作一下MinIO,先准备环境,然后使用minio来进行文件的上传下载 ,首先我们需要下载MinIO,然后创建一个Api服务项目作为我们的文件微服务。
1、Windows浏览器在线下载MinIO和mc客户端,官方文档地址
2、Linux直接创建对应目录输入下载命令或者下到本地拷贝进去,也可以使用Docker
wget
chmod +x minio
./minio server ./data
3、准备一个Api服务作为文件微服务说白了就是使创建一个控制器,访问这个控制器进行文件操作,然后Nuget引入操作的Minio包
4、创建一个FileUploadControll控制器来作为我们的接口,此处只演示简单的上传下载,当然它还支持分片和批量以及拷贝操作,具体的可以根据需要查看对应的api,也比较简单
[ApiController]
[Route( "[controller]")]
publicclassFileUploadController: ControllerBase
privatereadonly ILogger<FileUploadController> _logger;
publicFileUploadController(ILogger<FileUploadController> logger)
_logger = logger;
[")]
publicIActionResult Upload(IFormFile formFile)
//1.创建MinioClient客户端
MinioClient minioClient = newMinioClient( "127.0.0.1:9000", "minioadmin", "minioadmin");
//2.创建文件桶(数据库)
if(!minioClient.BucketExistsAsync( "micservice").Result)
minioClient.MakeBucketAsync( "micservice").Wait;
//3.上传文件(最大上传5TB的数据)
minioClient.PutObjectAsync( "micservice", formFile.FileName, formFile.OpenReadStream, formFile.Length).Wait;
_logger.LogInformation($ "文件:{formFile.FileName}上传到MinIO成功");
returnnewJsonResult( "上传文件成功");
[")]
publicIActionResult Download( stringfileName)
FileStreamResult fileStreamResult = null;
try
// 1、创建MioIO客户端
MinioClient minioClient = newMinioClient( "127.0.0.1:9000", "minioadmin", "minioadmin");
var imgStream = newMemoryStream;
// 2、下载图片
minioClient.GetObjectAsync( "micservice", fileName, stream => stream.CopyTo(imgStream)).Wait;
imgStream.Position = 0;
fileStreamResult = newFileStreamResult(imgStream, "image/jpg");
catch(MinioException e)
_logger.LogInformation($ "文件:{fileName}下载失败");
returnfileStreamResult;
4、现在需要启动我们的Minio服务,进入到我们的下载目录Linux一样,然后启动命令行工具
minin.exe server ./data
我们启动后控制台会输出如下信息,首先第一部分中是我们和Minio,进程通信的服务地址和用户名密码
API:
API:
第二部分就是minio提供给我们查看和运维的可视化界面,包含地址和用户名密码,密码账号是支持修改的
Console:
Console:
在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,因为多存储了校验位),安全性也很高(可以利用校验位恢复数据),空间利用率也不错(不完全复制,只冗余校验位),这也是互联网公司用的比较多的存储方案
RAID0:存储性能高的磁盘阵列,又称striping,它的原理是,将连续的数据分散到不同的磁盘上存储,这些不同的磁盘能同时并行存取数据
RAID1:安全性高的磁盘阵列,又称mirror,它的原理是,将数据完全复制到另一个磁盘上,磁盘空间利用率只有50%
RAID0+1:RAID0和RAID1的综合方案,速度快,安全性又高,但是很贵,这也是国企用的比较多的存储方案
RAID5:RAID0和RAID1的折衷方案,读取速度比较快(不如RAID0,因为多存储了校验位),安全性也很高(可以利用校验位恢复数据),空间利用率也不错(不完全复制,只冗余校验位),这也是互联网公司用的比较多的存储方案
通常面对这种防止误删的问题,我们使用的策略就是使用冗余多个目录来存储多个副本文件,多副本技术比较简单直接,要冗余保护关键数据,就干脆多存几份,单个数据的损坏不要紧,还有备份可以使用。同理多个目录不行,加入多个主机来存储,这种做法在很多场景下适用。
但这种方法的优缺点也比较明显,优点是 写入效率高,无需多余的计算,直接存多份即可, 数据恢复快,从副本复制就好了。 缺点就是 存储效率低、 占用空间以前需要的磁盘容量直接 X2 或者 X3 倍了,对于Minio来说,文件最大可以支持5TB,那如果按照这种做法对磁盘的消耗是巨大的,就 成本方面而言是不可行的,所以MinIO实现了另外一种保证文件高可用的机制,核心思想和集群方式差不多,但是对文件存储的方式跟简副本拷贝不同,Minio使用了纠删码的策略来保证我们的文件高可用。
但这种方法的优缺点也比较明显, 优点是 写入效率高,无需多余的计算,直接存多份即可, 数据恢复快,从副本复制就好了。 缺点就是 存储效率低、 占用空间以前需要的磁盘容量直接 X2 或者 X3 倍了,对于Minio来说,文件最大可以支持4个G,那如果按照这种做法对磁盘的消耗是巨大的,就 成本方面而言是不可行的,所以Minio实现了另外一种保证文件高可用的机制,核心思想和集群方式差不多,但是对文件存储的方式跟简副本拷贝不同,Minio使用了纠删码的策略来保证我们的文件高可用。
3、纠删码
在这里我们需要搞清楚的问题有好几个,先列出来吧,当然只是简单的介绍,具体深入还是需要自己去了解一下。
1、什么是RAID?
RAID中文简称为独立磁盘冗余磁盘阵列。简单的说,RAID是一种把多块独立的物理硬盘)按不同的方式组合起来形成一个硬盘组(逻辑硬盘),从而提供比单个硬盘更高的存储性能和提供数据备份技术。
RAID中文简称为独立磁盘冗余磁盘阵列。简单的说,RAID是一种把多块独立的物理硬盘)按不同的方式组合起来形成一个硬盘组(逻辑硬盘),从而提供比单个硬盘更高的存储性能和提供数据备份技术。
2、什么是纠删码?
我们使用一个简单的例子来理解**纠删码,首先从冗余思想来着手,假设我们在存储一份大小为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.纠删码可以恢复任何磁盘损坏的数据,包括人为删除、磁盘信道丢失、磁盘中毒。
1.使用传统副本冗余至少2个数据目录,如果分片后就需要最少4份数据。
2.Minio按照最少分片2个的话,至少需要4个数据目录,必须有一半数据,数据不丢失,才能恢复 (N/2)。
3.纠删码可以恢复任何磁盘损坏的数据,包括人为删除、磁盘信道丢失、磁盘中毒。
有时我们想把客户端上传下载文件的一些操作,存储起来,方便以后做 数据分析,最简单的做法我们可以使用 写日志的方式,但是目前要做的不是介绍这种,而是使用MioIO自带的 文件监听机制,MinIO允许我们配置存储操作日志的存储介质,例如Mysql、Redis、Elastic Search、Kafka、WebHook等等,MinIO可以设置对某一个 Bucket实现事件监听。
1、首先我们需要在Console中配置存储介质,此处选择 Mysql
1.在mysql中创建一个可供MinIO存储操作的数据库。
2.在MinIO中配置数据库名称、表以及其他连接信息。
1.在mysql中创建一个可供MinIO存储操作的数据库。
2.在MinIO中配置数据库名称、表以及其他连接信息。
2、 重启MinIO服务,并指定 Console地址为 9001,
minio server --address :9000 --console-address ":9001" ./data
重启后控制台会给出操作 Mysql的队列名arn:minio:sqs::_:mysql
重启后控制台会给出操作 Mysql的队列名arn:minio:sqs::_:mysql
3、启动MinIO自带的命令客户端 mc.exe,给MinIO的 Api地址取一个 别名为 minio_queue,方便后续使用
mc.exe alias set minio_queue
4、然后执行客户端命令。用于告诉 MinIO服务将文件Bucket 和 Mysql队列事件注册绑定
下面命令的意思是对 minio_queue服务中的 micservice这个 Bucket添加增、删、改、查的监听事件到 arn:minio:sqs::_:mysql中,说白了就是如果 对这个桶中的文件进行操作,那么就会写入日志到Mysql中
下面命令的意思是对 minio_queue服务中的 micservice这个 Bucket添加增、删、改、查的监听事件到 arn:minio:sqs::_:mysql中,说白了就是如果 对这个桶中的文件进行操作,那么就会写入日志到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
转自:有梦想的鱼i
转自:有梦想的鱼i
- EOF -
点击标题可跳转
设计一个支持百万用户的系统
ASP.NET Core 实体类可生产 CRUD 后台管理界面
.NET WebView2 项目 实现嵌入 Web 页面
看完本文有收获?请转发分享给更多人
推荐关注「DotNet」,提升.Net技能
点赞和在看就是最大的支持❤️
相关文章
发表评论