分布式文件存储Minio学习入门

news2024/11/18 1:38:40

文章目录

  • 一、分布式文件系统应用场景
    • 1. Minio介绍
      • Minio优点
    • 2. MinIO的基础概念、
    • 3. 纠删码ES(Erasure Code)
    • 4. 存储形式
    • 5. 存储方案
  • 二、Docker部署单机Minio
  • 三、minio纠删码模式部署
  • 四、分布式集群部署
    • 分布式存储可靠性常用方法
      • 冗余
      • 校验
    • 分布式Minio优势
    • 运行分布式minio
    • 使用docker compose部署minio
  • 五、Minio客户端使用
    • docker 中使用MC
  • 六、Minio整合SpringBoot
    • 1. 编写MinioConfig类
    • 2. 编写application.yml
    • 3. 编写Controller测试类(查询、下载、上传)

一、分布式文件系统应用场景

互联网海量非结构化数据的存储需求。电商图片、视频、网盘文件、社交图片。
分布式文件存储系统Minio与FastDFS的区别。FastDFS文件名是自动生成的。

1. Minio介绍

MinIO是一个开源的对象存储服务。兼容亚马逊S3云存储服务接口。适合存储大量非结构化数据,eg:图片、视频、日志文件、备份数据、容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几K到最大5T不等。
MinIO是一个非常轻量的服务,可以很简单的和其他应用结合,类似NodeJS、Redis或者MySQL。
中文官方网站:http://minio.org.cn/

Minio优点

  • 部署简单:一个single二进制文件即是一切,还可支持各种平台
  • minio支持海量存储,可按zone扩展,支持单个对象最大5TB
  • 兼容Amazon S3,充分考虑开发人员的需求和体验
  • 低冗余且磁盘损坏高容忍,标准且最高的数据荣誉系数为2(即存储一个1M的数据,实际占用2M),但在任意n/2块disk损坏的情况下依赖可以读出数据(n为一个纠删码集合中的disk数量)。并且这种损坏恢复是基于单个对象的,而不是基于整个存储卷的。
  • 读写性能优异

2. MinIO的基础概念、

  • Object: 存储到MinIO的基本对象,如文件、字节流等
  • Bucket: 用来存储Object的逻辑空间。每个Bucket之间的数据是相互隔离的。对于客户端来说,相当于一个存放文件的顶层文件夹。(隔离的作用)
  • Drive: 即存储数据的磁盘,在Minio启动时,以参数的方式传入。Minio中所有的对象数据都会存储在Drive中。
  • Set: 即一组Drive的集合,分布式部署根据集群规模自动划分一个或多个Set,每个Set中的Dirve分布位置不同。一个对象存储在一个Set上。
    • 一个对象存储在一个Set上
    • 一个集群划分为多个Set
    • 一个Set包含的Drive数量固定,默认由系统根据集群规模计算
    • 一个Set中的Drive尽可能分布在不同的节点上。

3. 纠删码ES(Erasure Code)

MinIO使用纠删码机制来保证高可用,使用HighWayHash来处理数据损坏。关于纠删码,简单的说即通过计算,将丢失的数据还原,可以将n份原始数据,增加m份数据。并能通过n+m份中的任意n份数据,还原为原始数据。
即如果有任意小于m份的数据失败,仍可以通过剩下的数据还原。

4. 存储形式

文件对象上传到Minio,会在对应的数据磁盘中,以Bucket名称为目录,文件名为下一级目录,文件名下为part.1和xl.meta,前者为编码数据块及校验块,后者是元数据文件。

5. 存储方案

在这里插入图片描述

二、Docker部署单机Minio

  1. 参考官方文档:https://min.io/docs/minio/container/index.html
    在这里插入图片描述
  2. 命令启动
    这里我们用的是docker,所以需要将命令换成docker run
λ docker search minio
λ docker pull minio/minio
docker run -p 9000:9000 -p 9090:9090 --name minio -v D:\docker\minio\data:/data -e "MINIO_ROOT_USER=admin" -e "MINIO_ROOT_PASSWORD=admin123" minio/minio server /data --console-address ":9090"
# 下面是多行模式的
docker run -d 	\ 	# 后台启动
	-p 9000:9000  \	# api
	-p 9090:9090  \	# 访问地址
	--name minio 
	-v D:\docker\minio\data:/data  \		#映射数据文件
	-e "MINIO_ROOT_USER=admin"  \		#账号
	-e "MINIO_ROOT_PASSWORD=admin123"  \		#密码
	minio/minio server /data --console-address ":9090"	#指定访问端口9090不变更

启动控制台打印内容:
在这里插入图片描述

  1. 访问:http://localhost:9090/login 账号:admin,密码:admin123

  2. 创建存储桶,并上传文件测试,查看映射磁盘目录的变化。
    在这里插入图片描述
    这里我参考的版本是说单台没有启用纠删码存储的即为源文件,而我这里docker启动的却存储的是

    λ tree
    D:\docker\minio\data
    └─test1
        └─Doc1.docx
            └─f9014ffb-63fd-4f5d-a250-fbccf131f87d
    

三、minio纠删码模式部署

minio使用纠删码(erasure code)与校验和(checksum)来保护数据不受硬件故障和无声数据损坏。即使丢失一半(n/2)数据的硬盘,仍然可以恢复数据。当有一半的磁盘损坏时数据无法上传,必须存在2n+1块才可以。

  1. docker 部署
docker run -p 9000:9000 -p 9090:9090 --name minio -v D:\docker\minio\data1:/data1 -v D:\docker\minio\data2:/data2 -v D:\docker\minio\data3:/data3 -v D:\docker\minio\data4:/data4  -v D:\docker\minio\data5:/data5 -v D:\docker\minio\data6:/data6 -v D:\docker\minio\data7:/data7 -v D:\docker\minio\data8:/data8 -e "MINIO_ROOT_USER=admin" -e "MINIO_ROOT_PASSWORD=admin123" minio/minio server /data{1...8} --console-address ":9090"

docker run -d 	\ 	# 后台启动
	-p 9000:9000  \	# api
	-p 9091:9091  \	# 访问地址
	--name minio 
	-v D:\docker\minio\data1:/data1 \
	-v D:\docker\minio\data2:/data2 \
	-v D:\docker\minio\data3:/data3 \
	-v D:\docker\minio\data4:/data4 \
	-v D:\docker\minio\data5:/data5 \
	-v D:\docker\minio\data6:/data6 \
	-v D:\docker\minio\data7:/data7 \
	-v D:\docker\minio\data8:/data8 \
	-e "MINIO_ROOT_USER=admin"  \		#账号
	-e "MINIO_ROOT_PASSWORD=admin123"  \		#密码
	minio/minio server /data{1...8} --console-address ":9091"	#指定访问端口9090不变更

四、分布式集群部署

分布式minio可以将多块硬盘组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式minio避免了单点故障。
在这里插入图片描述

分布式存储可靠性常用方法

分布式存储,关键点在于数据可靠性、完整性、不丢失损坏。只有在可靠的前提下才追求一致性、高可用、高性能。

冗余

冗余即对存储的数据进行备份,当数据丢失、损坏,可以使用副本进行恢复。而备份份数决定了可靠性。可靠性是允许丢失其中一部分数据。当前分布式系统中采用该模式的,eg:Hadoop的文件系统(3个副本)、Redis集群、Mysql主备。

校验

校验即通过校验码的计算方式,对丢失损坏的数据进行校验、还原。注意:这里有两个作用,一个校验通过对数据进行校验和计算,可以检查数据的完整性,检查数据是否损坏、更改,在数据传输中使用。二是恢复还原,通过对数据结合校验码计算,还原丢失损坏的数据,在保证可靠性的前提下减少冗余。eg:单机硬盘存储的RAID技术、纠删码技术。

分布式Minio优势

  • 数据保护:分布式minio采用纠删码来防范多个节点宕机和位衰减(bit rot)。分布式minio最少需要4个磁盘,使用分布式minio自动引入纠删码。
  • 高可用:单机minio存在单点故障。而如果一个有N块硬盘的分布式minio,只要有n/2块硬盘可用,则数据安全可读。可写需要n/2+1。
  • 一致性:minio在分布式和单机模式下,所有写操作都严格遵守read-after-write一致性。

运行分布式minio

启动一个分布式minio实例,只需要把硬盘位置作为参数传给minio server命令即可,然后在其他节点运行相同命令。

  • 分布式minio所有节点需要同样的access密钥和secret密钥以保证所有节点可以建立连接。新版(MINIO_ROOT_USER、MINIO_ROOT_PASSWORD)
  • 分布式 minio使用磁盘必须干净无数据。
  • 分布式minio节点时间差不得超过3秒,可以使用NTP来保证时间同步。
    在这里插入图片描述
    在这里插入图片描述

使用docker compose部署minio

version: '3.7'

# Settings and configurations that are common for all containers
x-minio-common: &minio-common
  image: minio/minio:latest
  command: server --console-address ":9001" http://minio{1...4}/data{1...2}
  expose:
    - "9000"
    - "9001"
  environment:
    MINIO_ROOT_USER: minio
    MINIO_ROOT_PASSWORD: minio123
  healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
    interval: 30s
    timeout: 20s
    retries: 3

# starts 4 docker containers running minio server instances.
# using nginx reverse proxy, load balancing, you can access
# it through port 9000.
services:
  minio1:
    <<: *minio-common
    hostname: minio1
    volumes:
      - data1-1:/data1
      - data1-2:/data2

  minio2:
    <<: *minio-common
    hostname: minio2
    volumes:
      - data2-1:/data1
      - data2-2:/data2

  minio3:
    <<: *minio-common
    hostname: minio3
    volumes:
      - data3-1:/data1
      - data3-2:/data2

  minio4:
    <<: *minio-common
    hostname: minio4
    volumes:
      - data4-1:/data1
      - data4-2:/data2

  nginx:
    image: nginx:1.19.2-alpine
    hostname: nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "9000:9000"
      - "9001:9001"
    depends_on:
      - minio1
      - minio2
      - minio3
      - minio4

## By default this config uses default local driver,
## For custom volumes replace with volume driver configuration.
volumes:
  data1-1:
  data1-2:
  data2-1:
  data2-2:
  data3-1:
  data3-2:
  data4-1:
  data4-2:

五、Minio客户端使用

MinIO Client(MC)为ls、cat、cp、mirror、diff、find等unix命令提供了一种替代方案。

ls 			#	列出文件和文件夹。
mb			#	创建一个存储桶或一个文件夹。
cat			#	显示文件和对象内容。
pipe		#	将一个STDIN重定向到一个对象或者文件或者STDOUT。
share		#	生成用于共享的URL。
cp			#	拷贝文件和对象。
mirror		#	给存储桶和文件夹做镜像。
find		#	基于参数查找文件。
diff		#	对两个文件夹或者存储桶比较差异。
rm			#	删除文件和对象。
events		#	管理对象通知。
watch		#	监视文件和对象的事件
policy		#	管理访问策略。
config		#	管理mc配置文件。
update		#	检查软件更新。
version		# 	输出版本信息。

http://docs.minio.org.cn/minio/baremetal/reference/minio-cli/minio-mc.html

docker 中使用MC

启动控制台

λ docker pull minio/mc
λ docker run -it --name mc --entrypoint=/bin/sh minio/mc
λ docker start -i mc

配置管理

# 查询mc host配置
mc config host ls
# 添加minio服务
mc config host add minio-server http://172.17.0.3:9090 admin admin123
# 删除host
mc config host remove minio-server

文件管理

# 上传下载
mc cp 源文件地址 目标地址
mc rm 文件地址

Bucket管理

# 创建桶
mc mb hostname / bucketName
eg:mc mb minio-server /bucket01
# 删除桶 --force表示强制删除
mc rb hostname  /bucketName
eg:mc rb --force minio-server /bucket02

admin管理

service		# 服务重启并停止所有MinIO服务器
update		# 更新所有MinIO服务器
info		# 显示MinIO服务器信息
user		# 管理用户
group		# 管理小组
policy		# MinIO服务器中定义的策略管理
config		# MinIO服务器配置管理
heal		# 修复MinIO服务器上的磁盘,存储桶和对象
profile		# 生成概要文件数据以进行调试
top			# 提供MinIo的顶部统计信息
trace		# 跟踪显示MinIO服务器的http跟踪
console			# 控制台显示MinIo服务器的控制台日志
prometheus		# Prometheus管理Prometheus配置
kms				# kms执行KMS管理操作

六、Minio整合SpringBoot

1. 编写MinioConfig类

@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    private String url;
    private String username;
    private String pwd;

    @Bean
    public MinioClient getMinioClient() {
        MinioClient minioClient = MinioClient.builder().endpoint(this.getUrl())
                .credentials(this.getUsername(), this.getPwd())
                .build();
        return minioClient;
    }
}

2. 编写application.yml

minio:
  url: http://localhost:9000
  username: admin
  pwd: admin123
  bucket: test
server:
  port: 8888
spring:
  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 500MB

3. 编写Controller测试类(查询、下载、上传)

@RestController
@Slf4j
public class MinioController {
    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucket}")
    private String bucketName;

    @GetMapping("/list")
    public List<Object> list() throws Exception {
        Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder()
                .bucket(bucketName).build());
        ArrayList<Object> list = new ArrayList<>();
        Iterator<Result<Item>> iterator = results.iterator();
        while (iterator.hasNext()) {
            Item item = iterator.next().get();
            list.add(JSONUtil.parse(this.format(item.objectName(), item.size())));
        }
        return list;
    }

    @GetMapping("/download/{fileName}")
    public void download(HttpServletResponse resp, @PathVariable("fileName") String fileName) throws Exception {
        StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder()
                .bucket(bucketName).object(fileName).build());
        resp.setContentType(stat.contentType());
        resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        GetObjectResponse object = minioClient.getObject(GetObjectArgs.builder()
                .bucket(bucketName).object(fileName).build());
        IOUtils.copy(object, resp.getOutputStream());
    }

    @GetMapping("/delete/{fileName}")
    public String delete(@PathVariable("fileName") String fileName) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return "删除失败!" + e.getMessage();
        }
        return "删除成功!";
    }

    @GetMapping("/upload")
    public String upload(MultipartFile[] files) throws IOException {
        if (files == null || files.length == 0) {
            return "上传文件不能为空!";
        }
        InputStream ins = null;
        try {
            ArrayList<String> fileNames = new ArrayList<>(files.length);
            for (MultipartFile file : files) {
                String filename = file.getOriginalFilename();
                fileNames.add(filename);
                ins = file.getInputStream();
                ObjectWriteResponse response = minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName).object(filename)
                        .stream(ins, file.getSize(), -1)
                        .contentType(file.getContentType())
                        .build());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "上传失败!" + e.getMessage();
        } finally {
            if (ins != null) {
                ins.close();
            }
        }
        return "上传成功!";
    }

    private String format(String objectName, long size) {
        return String.format("{'fileName':'%s','fileSize':'%d'}", objectName, size);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/349960.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何设置股票接口版交易软件的指标涨跌家数?

如何设置股票接口版交易软件指标涨跌家数&#xff1f;今天小编就以通达信为例给大家介绍一下&#xff0c;很多人其实不知道通达信里面有个很厉害的股票情绪的指标&#xff0c;叫做通达信涨跌家数&#xff0c;打开在通达信软件k线界面&#xff0c;然后输入880005就可以找到了。下…

如何解决 Python 中 TypeError: unhashable type: ‘dict‘ 错误

Python “TypeError: unhashable type: ‘dict’ ” 发生在我们将字典用作另一个字典中的键或用作集合中的元素时。 要解决该错误&#xff0c;需要改用 frozenset&#xff0c;或者在将字典用作键之前将其转换为 JSON 字符串。 当我们将字典用作另一个字典中的键时&#xff0c…

AnlogicFPGA-IO引脚约束设置

&#xff08;https://www.eefocus.com/article/472120.html此链接是一篇关于XillinxFPGA的IO的状态分析&#xff0c;希望自己也要能了解到AnLogic的IO状态并有对此问题的分析能力&#xff09; 1、DriveStrength: 驱动强度&#xff0c;即最大能驱动的电流大小&#xff08;见带负…

Project Caliper:目标是打造最佳VR手柄

一提到Valve Index&#xff0c;人们很快联想到它的五指追踪VR手柄&#xff0c;这款支持手势追踪和体感反馈的高端VR手柄&#xff0c;是市面上最强大的C端VR手柄之一。尽管如此&#xff0c;它依然存在许多缺陷&#xff0c;比如配备的小型摇杆质量不佳、集成式设计不利于维修、人…

算法问题——排序算法问题

摘要 查找和排序算法是算法的入门知识&#xff0c;其经典思想可以用于很多算法当中。因为其实现代码较短&#xff0c;应用较常见。所以在面试中经常会问到排序算法及其相关的问题。但万变不离其宗&#xff0c;只要熟悉了思想&#xff0c;灵活运用也不是难事。一般在面试中最常…

布林线(BOLL)计算公式详解,开口收口代表什么

布林带&#xff0c;英文名称BOLL&#xff0c;是John Bollinger在上世纪八十年代创建的&#xff0c;由中轨、上轨、下轨三条线组成。 一、布林线计算公式详解 布林线中轨是简单移动平均线&#xff0c;一般软件上自带的布林带中轨是20日均线&#xff0c;上轨是中轨加上2个标准差…

Spring 系列之FrameWork

Spring 系列文章 文章目录Spring 系列文章前言一、Spring 介绍二、Spring 架构特征三、Spring 优势四、Spring 体系结构五、IOC 控制反转1. 概念引入2. 原理分析六、Bean 管理1. 介绍2. 管理的内容3. Bean 管理方式1. XML实现DI 赋值2. Bean生命周期1. 测试生命周期2. 后置处理…

RuoYi-Vue搭建(若依)

项目简介 RuoYi-Vue基于SpringBootVue前后端分离的Java快速开发框架1.前端采用Vue、Element UI2.后端采用Spring Boot、Spring Security、Redis & Jwt3.权限认证使用Jwt&#xff0c;支持多终端认证系统4.支持加载动态权限菜单&#xff0c;多方式轻松权限控制5.高效率开发&a…

27岁想转行IT,还来得及吗?

来不来得及不还是看你自身的意愿和条件&#xff0c;这个问题要问你自己吧&#xff01; 每个人的能力、看法都不同。面对类似的问题&#xff0c;很多人会把侧重点放在IT上&#xff0c;或者27岁上面。那么我们试着换一个方式来问呢&#xff1a;什么时候适合转行&#xff0c;有哪些…

1.PostgreSQL

文章目录LIMITWITH 和RECURSIVEPostgreSQL 约束PostgreSQL AUTO INCREMENT&#xff08;自动增长&#xff09;PostgreSQL PRIVILEGES&#xff08;权限&#xff09;GRANT语法LIMIT SELECT * FROM COMPANY LIMIT 3 OFFSET 2;WITH 和RECURSIVE WITH RECURSIVE t(a,b) AS (VALUES (…

每日学术速递2.16

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Efficient Teacher: Semi-Supervised Object Detection for YOLOv5 标题&#xff1a;高效教师&#xff1a;YOLOv5 的半监督目标检测 作者&#xff1a;Bowen Xu, Mingtao Chen, Wen…

用ChatGPT来预测2023美国大学生数学建模赛题以及高分攻略

一.2023年美赛 2023年美赛将于2023年2月17-21日举行&#xff0c;将会在北京时间&#xff1a;2023年2月 21日&#xff0c;上午10&#xff1a;00前提交论文。 二.用ChatGPT来预测2023美国大学生数学建模赛题 2.1预测一下会有什么类型的题目 答&#xff1a; 由于我是一个人工…

AcWing语法基础课笔记 第五章 C++中的字符串

第五章 C中的字符串 字符串是计算机与人类沟通的重要手段。 ——闫学灿 字符与整数的联系——ASCII码 每个常用字符都对应一个-128~127的数字&#xff0c;二者之间可以相互转化&#xff1a; 常用ASCII值&#xff1a;’A’-‘Z’ 是65~90&#xff0c;’a’-‘z’…

【docker知识】DockerFile语法 2:构造指令

1官方文档&#xff1a;Dockerfile reference | Docker Documentation 一、说明 我们将以HelloWorld案例的方法&#xff0c;由浅入深地理解DockerFile指令&#xff0c;并生成自己的镜像。为了避免冗长的官网文章污染您的视线&#xff0c;这里将重要的&#xff0c;常见的指令…

Springcloud-配置中心config

一、添加依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId&…

【大数据】HADOOP-YARN容量调度器多队列配置详解实战

简介 Capacity调度器具有以下的几个特性&#xff1a; 层次化的队列设计&#xff0c;这种层次化的队列设计保证了子队列可以使用父队列设置的全部资源。这样通过层次化的管理&#xff0c;更容易合理分配和限制资源的使用。容量保证&#xff0c;队列上都会设置一个资源的占比&a…

数据分析与SAS学习笔记4

INPUT语句&#xff1a;格式修饰符&#xff1a; “:” 修饰符。表示从下一个非空格列读入数据&#xff0c;直到:1 遇到再下一个空格列&#xff1b; 2 读到预先定义的变量长度&#xff1b; 3 数据行结束。哪个先出现就在哪儿结束。 “&” 修饰符。表示从下一个非空格列读入…

分享我从功能测试转型到测试开发的真实故事

由于这段时间我面试了很多家公司&#xff0c;也经历了之前公司的不愉快。所以我想写一篇文章来分享一下自己的面试体会。希望能对我在之后的工作或者面试中有一些帮助&#xff0c;也希望能帮助到正在找工作的你。 找工作 我们总是草率地进入一个自己不了解的公司工作&#xf…

【C语言】web后端 CGI

web后端 CGI 一、cgi的学习 cgi通用网关接口 是web服务器主机提供信息服务的标准接口。通过CGI接口&#xff0c;web服务器就能获取客户端提交的信息&#xff0c;转交给服务器端端CGI程序进行处理&#xff0c;最后返回结果给客户端。 服务器和CGI程序之间通过 stdin/stdout 标准…

Python学习-----函数3.0(嵌套函数、闭包、装饰器)

目录 1.函数嵌套 2.闭包 3.装饰器 这一节&#xff0c;我会详细Python中讲解函数的进阶内容&#xff0c;包括嵌套函数、闭包和装饰器。一起来学习吧&#xff01;&#xff01;&#xff01; 1.函数嵌套 概念&#xff1a;函数里面再定义一个函数 作用&#xff1a;当我们在一个多…