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浏览器在线下载MinIOmc客户端官方文档地址

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+分片2A4 = 分片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学习的更多相关文章

  1. 在Linux系统下搭建和配置一个minio文件服务器(一)

    1.minio文件服务器的介绍 Minio 是一个基于Go语言的对象存储服务.它实现了大部分亚马逊S3云存储服务接口,可以看做是是S3的开源版本,非常适合于存储大容量非结构化的数据,例如图片.视频.日 ...

  2. Github 29K Star的开源对象存储方案——Minio入门宝典

    对象存储不是什么新技术了,但是从来都没有被替代掉.为什么?在这个大数据发展迅速地时代,数据已经不单单是简单的文本数据了,每天有大量的图片,视频数据产生,在短视频火爆的今天,这个数量还在增加.有数据表明 ...

  3. docker安装minio

    目录 一.简介 二.docker安装 三.java中使用minio上传与下载 一.简介 MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能对象存储. 它是与 Amazon ...

  4. MinIO多租户(Multi-tenant)部署指南

    官方文档地址:http://docs.minio.org.cn/docs/master/multi-tenant-minio-deployment-guide 单机部署 在单台机器上托管多个租户,为每 ...

  5. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  6. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  7. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  8. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  9. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

随机推荐

  1. 攻防世界 unserialize3

    unserialize3 class xctf{ public $flag = '111'; public function __wakeup(){ exit('bad requests'); } } ...

  2. ubuntu sublime text3 python 配置 sublime text3 python 配置

    ubuntu sublime text3 python 配置     1.安装sublime text 3 安装过程非常简单,在terminal中输入: sudo add-apt-repository ...

  3. 7步学会在Windows下上架iOS APP流程

    之前用跨平台开发工具做了一个应用,平台可以同时生成安卓版和苹果版,想着也把这应用上架到App Store试试,于是找同学借了个苹果开发者账号,但没那么简单,还要用到Mac电脑的钥匙串申请发布证书和上传 ...

  4. 如何监控微信小程序HTTP请求错误

    摘要: Fundebug的微信小程序错误监控插件更新至0.5.0,支持监控HTTP请求错误. 接入插件 接入Fundebug的错误监控插件非常简单,只需要下载fundebug.0.5.0.min.js ...

  5. leetcode-剑指 Offer II 012. 左右两边子数组的和相等

    题目描述: 给你一个整数数组 nums ,请计算数组的 中心下标 . 数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和. 如果中心下标位于数组最左端,那么左侧数之和视为 ...

  6. for 循环详解

    学习目标: 掌握 for 循环的使用 学习内容: 1.for语法 for(初始化语句; boolean表达式; 循环后操作语句) { 循环体; } 流程图如下: 特点: 初始化语句:只在循环开始时执行 ...

  7. JAVASE for 笔记

    //0到100中奇数偶数的和package com.huang.boke.flowPath;public class Fordeme { public static void main(String[ ...

  8. Python数据展示 - 生成表格图片

    前言 前一篇文章介绍了推送信息到企业微信群里,其中一个项目推送的信息是使用Python自动生成的表格,本文来讲讲如何用Python生成表格图片. 选一个合适库 Python最大的优点就是第三方库丰富, ...

  9. SSL及GMVPN握手协议详解

    之前写过一篇文章搞懂密码学基础及SSL/TLS协议,主要介绍了加密学的基础,并从整体上对SSL协议做了介绍.由于篇幅原因,SSL握手的详细流程没有深入介绍.本文将拆解握手流程,在消息级别对握手进行详细 ...

  10. Java语言学习day13--7月14日

    今日内容介绍1.循环练习2.数组方法练习 ###01奇数求和练习 * A: 奇数求和练习 * a: 题目分析 * 为了记录累加和的值,我们需要定义一个存储累加和的变量 * 我们要获取到1-100范围内 ...