1.使用分布式文件系统Minio管理文件

news2025/5/25 3:51:23

分布式文件系统DFS分类

文件系统

文件系统是操作系统用于组织管理存储设备(磁盘)或分区上文件信息的方法和数据结构,负责对文件存储设备空间进行组织和分配,并对存入文件进行保护和检索

文件系统是负责管理和存储文件的系统软件,操作系统通过文件系统提供的接口去存取文件,用户通过操作系统访问磁盘上的文件

  • 常见的文件系统:FAT16/FAT32、NTFS、HFS、UFS、APFS、XFS、Ext4

在这里插入图片描述

一个计算机无法存储海量的文件,通过网络将若干计算机组织起来共同去存储海量的文件,这些组织起来的计算机之间通过网络进行通信

  • 文件系统处理能力: 由一台计算机扩充到多台计算机同时处理
  • 文件副本: 一台计算机挂了还有其他的副本计算机提供数据
  • 访问速度: 每台计算机可以放在不同的地域方便用户就近访问从而提高访问速度

分布式文件系统(Distributed File System)是若干不同的逻辑磁盘分区或卷标组合在一起而形成的完整的有层次的文件系统

  • DFS为分布在网络上任意位置的资源提供一个逻辑上的树形文件系统结构,从而使用户访问分布在网络上的共享文件更加简便

在这里插入图片描述

网络文件系统(NFS)

网络文件系统(NFS)是文件系统之上的一个网络抽象,它允许多个用户通过网络共享文件系统,并提供数据集中的优势,来最小化所需的存储空间

  • 客户端需要安装映射NFS服务器的驱动器,客户端通过网络访问NFS服务器的硬盘完全透明

NFS文件系统基于UDP/IP协议,其实现主要是采用远程过程调用RPC机制,RPC提供了一组与机器、操作系统以及低层传送协议无关的存取远程文件的操作

  • RPC采用了XDR的支持: XDR是一种与机器无关的数据描述编码协议,以独立于任意机器体系结构的格式对网络传送数据编码和解码,支持在异构系统间的数据传送

在这里插入图片描述

分布式文件系统GFS

GoogleFS运行于廉价的普通硬件上并提供容错功能,用于大型的、分布式的、对大量数据进行访问的应用.可以给大量的用户提供总体性能较高的服务

  • GFS采用主从结构: 一个GFS集群由一个master和大量的chunkserver组成
  • master存储了数据文件的元数据,一个文件被分成了若干块存储在多个chunkserver中
  • 用户从master中获取数据元信息,向chunkserver中存储数据

在这里插入图片描述

分布式文件系统HDFS

Hadoop Distributed File System是Hadoop抽象文件系统的一种实现,它是一个高容错性((fault-tolerant))的系统,适合部署在廉价通用的机器上

  • 提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序
  • HDFS放宽了一部分POSIX约束,这样就可以使用流的形式访问(streaming access)文件系统中的数据
  • HDFS的文件分布在集群机器上同时提供副本进行容错及可靠性保证,如客户端写入读取文件的直接操作都是分布在集群各个机器上的,没有单点性能压力

HDFS采用主从结构,一个HDFS集群由一个名称节点和若干数据节点组成

  • 名称节点存储数据的元信息,一个完整的数据文件被分成若干块存储在各个数据节点
  • 客户端从名称节点获取数据的元信息及数据分块的信息,得到信息后客户端即可从数据块中存储数据

在这里插入图片描述

云计算厂家

阿里云对象存储服务OOS(Object Storage Service)是阿里云提供的海量、安全、低成本、高可靠的云存储服务

  • 数据设计持久性不低于 99.9999999999%,服务设计可用性即业务连续性不低于99.995%

百度对象存储服务BOS是百度提供的稳定、安全、高效、高可扩展的云存储服务

  • 可以将任意数量和形式的非结构化数据存入BOS,并对数据进行管理和处理
  • BOS支持标准、低频、冷和归档存储等多种存储类型,满足多场景的存储需求

分布式文件系统Minio

MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合使用,它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据

  • 优点: 轻量,使用简单,功能强大,支持各种平台,单个文件最大5TB,兼容 Amazon S3接口并提供了 Java、Python、GO等多版本SDK支持

在大数据领域通常的设计理念都是无中心和分布式,MinIO集群采用去中心化共享架构即每个结点是对等关系,通过Nginx可对MinIO进行负载均衡访问

  • Minio分布式模式可以帮助我们搭建一个高可用的对象存储服务,访问文件时不用考虑其真实物理位置

Minio将分布在不同服务器上的多块硬盘组成一个对象存储服务,由于硬盘分布在不同的节点上,分布式Minio避免了单点故障

纠删码是一种恢复丢失和损坏数据的数学算法,Minio使用该技术将数据分块并冗余的分散存储在各个节点的磁盘上,所有的可用磁盘组成一个集合

  • 当上传一个文件时会通过纠删码算法对文件进行分块存储,除了将文件本身分成4个数据块还会生成4个校验块,数据块和校验块会分散的存储在这8块硬盘
  • 使用纠删码的好处是即便丢失一半数量的硬盘也能恢复数据即不影响上传和下载,但如果多于一半的硬盘坏了则无法恢复

在这里插入图片描述

测试数据恢复

第一步: 首先在本地创建4个目录表示4个硬盘,下载minio解压即可使用,在有minio.exe的目录执行命令

minio.exe server D:\develop\minio_data\data1  D:\develop\minio_data\data2  D:\develop\minio_data\data3  D:\develop\minio_data\data4

在这里插入图片描述

第二步: 访问http://localhost:9000进行登录,账号和密码均为minioadmin/minioadmin
在这里插入图片描述

第三步: 创建bucket即存储文件的目录(可创建多个)并选择上传的文件

在这里插入图片描述

第四步: 查看本地创建的四个目录观察文件的存储情况,测试minio的数据恢复情况

  • 删除一个/两个目录: 在web控制台中仍然可以上传文件和下载文件并且删除的目录可以恢复
  • 删除三个目录: 由于集合中共有4块硬盘,当有大于一半的硬盘损坏时数据无法恢复,此时报Insufficient number of drives online(驱动不足)错误

在这里插入图片描述

Docker部署

开发阶段和生产阶段统一使用Docker安装镜像,容器启动后访问http://IP:9000查看是否正常

在这里插入图片描述

SDK

连接Minio服务

第一步: 在media-service工程中添加此依赖,MinIO提供多个语言版本SDK的支持,对于Java版本要求最低Java 1.8或更高版本

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.4.3</version>
</dependency>
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.8.1</version>
</dependency>

第二步: 指定连接minio服务的三个参数

参数说明
Endpoint对象存储服务所在的IP地址,如127.0.0.1:9000
Access KeyAccess key可以唯一标识你的账户,就像用户ID如minioadmin
Secret KeySecret key是你账户的密码,如minioadmin
public class FileUploader {
  public static void main(String[] args)
      throws IOException, NoSuchAlgorithmException, InvalidKeyException {
    try {
      // 指定连接的三个参数创建MinIO客户端
      MinioClient minioClient =
          MinioClient.builder()
              .endpoint("https://play.min.io")
              .credentials("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG")
              .build();

      // 创建bucket即存储文件的目录,如果手动创建了可以不用再创建
      boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("asiatrip").build());
      if (!found) {
        // 创建一个桶并命名为asiatrip
        minioClient.makeBucket(MakeBucketArgs.builder().bucket("asiatrip").build());
      } else {
        System.out.println("Bucket 'asiatrip' already exists.");
      }
}

MinioClient中上传/删除/查询/下载文件的方法

方法名参数描述
uploadObjectUploadObjectArgs上传文件
removeObjectRemoveObjectArgs删除文件
getObjectGetObjectArgs查询文件

获取content-type

在base工程中simplemagic依赖,使用它提供的方法根据文件扩展名得到资源的content-type

<dependency>
    <groupId>com.j256.simplemagic</groupId>
    <artifactId>simplemagic</artifactId>
    <version>1.17</version>
</dependency>
ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(文件扩展名);
String contentType = extensionMatch.getMimeType();

不同文件扩展名对应的MimeType媒体类型的枚举类

public class MediaType extends MimeType implements Serializable {
    private static final long serialVersionUID = 2069937152339670231L;
    public static final MediaType ALL = new MediaType("*""*");
    public static final String ALL_VALUE ="*/*"
    public static final MediaType APPLICATION_ATOM_XML = new MediaType("application","atom+xml");
    public static final String APPLICATIONATOM_XML_VALUE ="application/atom+xml";
    public static final MediaType APPLICATION_CBOR = new MediType("application""cbor");
    public static final String APPLICATION_CBOR_VALUE = "application/cbor";
    public static final MediaType APPLICATION_FORM URLENCODED = new Mediatype("application","x-wm-fomm-urlencoded");
    public static final String APPLICATION_FORM_URLENCODED_VALUE = "application/x-Www-form-urlencoded";
    public static final MediaType APPLICATION JSON = new MediaType("application","json");
    public static final String APPLICATION_JSON_VALUE = "application/json";
    public static final MediaType APPLICATION_XHTML_XML;
    public static final String APPLICATION_XHTML_XML_VALUE = "application/xhtml+xmL";
    public static final MediaType APPLICATION_XML;
    public static final String APPLICATION_XML_VALUE = "application/xml";
    public static final MediaType IMAGE_GIF;
    public static final String IMAGE_GIF_VALUE = "image/gif";
    public static final MediaType IMAGE_JPEG;
    public static final String IMAGE_JPEG_VALUE = "image/jpeg";
    public static final MediaType IMAGE_PNG;
    public static final String IMAGE_PNG_VALUE = "image/png";
    public static final MediaType MULTIPART_FORM_DATA;
    public static final String MULTIPART_FORM_DATA_VALUE = "multipart/form-data";
    public static final MediaType MULTIPART_MIXED;
    public static final String MULTIPART_MIXED_VALUE = "multipart/mixed";
    //........
}

上传文件

第一步: 创建一个名为testbucket的桶,然后将其访问权限修改为public,这样就可以直接通过http://127.0.0.1:9000/testbucket/pic01.png访问桶内存储的文件
在这里插入图片描述

第二步: 执行upload方法向桶的根目录或其子目录中上传文件,上传成功后访问http://127.0.0.1:9000/查看上传的文件并预览文件

@SpringBootTest
public class MinIOTest {
    // 创建MinioClient对象
    static MinioClient minioClient =
        MinioClient.builder()
        .endpoint("http://127.0.0.1:9000")
        .credentials("minioadmin", "minioadmin")
        .build();
    //上传文件
    @Test
    public  void upload() {
        //根据扩展名取出mimeType
        ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(".mp4");
        // 对于不含文件扩展名或文件扩展名未知的文件,字节流是通用的mimeType
        String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
        if(extensionMatch!=null){
            mimeType = extensionMatch.getMimeType();
        }
        try {
            UploadObjectArgs testbucket = UploadObjectArgs.builder()
                .bucket("testbucket")
                //.object("test001.mp4") // 在桶的根目录中指定上传的文件名及其扩展名
                .object("001/test001.mp4") // 在桶的根目录下的子目录中指定上传文件的文件名及其扩展名,文件名不能重复
                .filename("D:\\develop\\upload\\1mp4.temp")// 上传的源文件
                //.contentType("video/mp4")// 默认会根据扩展名确定文件内容类型,也可以手动指定
                .build();
            minioClient.uploadObject(testbucket);
            System.out.println("上传成功");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("上传失败");
        }

    }
}

删除文件

@Test
public void delete(){
    try {
        minioClient.removeObject(
            RemoveObjectArgs.builder().bucket("testbucket").object("001/test001.mp4").build());
        System.out.println("删除成功");
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("删除失败");
    }
}

查询文件

通过查询文件查看文件是否存在minio文件系统中

// IO流的读取简化
@Test
public void getFile() {
    GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket("testbucket").object("test001.mp4").build();
    try(
        FilterInputStream inputStream = minioClient.getObject(getObjectArgs);
        FileOutputStream outputStream = new FileOutputStream(new File("D:\\develop\\upload\\1_2.mp4"));
     ) {
        IOUtils.copy(inputStream,outputStream);
     } catch (Exception e) {
        e.printStackTrace();
     }
}

查询并下载文件

查看文件是否存在minio文件系统中,并且可以将查询到的字节流写入到本地文件中

@Test
public void getFileTest() {
    try {
        InputStream inputStream = minioClient.getObject(GetObjectArgs.builder()
                                                        .bucket("testbucket")
                                                        .object("pic01.png")
                                                        .build());
        FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\15863\\Desktop\\tmp.png");
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1) {
            fileOutputStream.write(buffer,0,len);
        }
        inputStream.close();
        fileOutputStream.close();
        System.out.println("下载成功");
    } catch (Exception e) {
        System.out.println("下载失败");
    }
}
// IO流的读取简化
@Test
public void getFile() {
    GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket("testbucket").object("test001.mp4").build();
    try(
        FilterInputStream inputStream = minioClient.getObject(getObjectArgs);
        FileOutputStream outputStream = new FileOutputStream(new File("D:\\develop\\upload\\1_2.mp4"));
     ) {
        IOUtils.copy(inputStream,outputStream);
     } catch (Exception e) {
        e.printStackTrace();
     }
}

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

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

相关文章

【网站项目】基于SSM的273校园二手交易网站

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

QQ数据包解密

Windows版qq数据包格式&#xff1a; android版qq数据包格式&#xff1a; 密钥&#xff1a;16个0 算法&#xff1a;tea_crypt算法 pc版qq 0825数据包解密源码&#xff1a; #include "qq.h" #include "qqcrypt.h" #include <WinSock2.h> #include…

Flink(十四)【Flink SQL(中)查询】

前言 接着上次写剩下的查询继续学习。 Flink SQL 查询 环境准备&#xff1a; # 1. 先启动 hadoop myhadoop start # 2. 不需要启动 flink 只启动yarn-session即可 /opt/module/flink-1.17.0/bin/yarn-session.sh -d # 3. 启动 flink sql 的环境 sql-client ./sql-client.sh …

【优化技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路

针对Java对象压缩及序列化技术的探索之路 序列化和反序列化为何需要有序列化呢&#xff1f;Java实现序列化的方式二进制格式 指定语言层级二进制格式 跨语言层级JSON 格式化类JSON格式化&#xff1a;XML文件格式化 序列化的分类在速度的对比上一般有如下规律&#xff1a;Java…

IDEA连接mysql5.7,报[08001] Could not create connection to database server错误

导致的原因是&#xff1a; MySQL版本过高 解决方法&#xff1a; 在数据库后面添加&#xff1a;useSSLserverTimezonecharacterEncodingautoReconnect 即&#xff1a;jdbc:mysql://localhost:3306/test?useSSLfalse&serverTimezoneHongkong&characterEncodingutf-8&…

Django从入门到精通(二)

目录 三、视图 3.1、文件or文件夹 3.2、相对和绝对导入urls 3.3、视图参数requests 3.4、返回值 3.5、响应头 3.6、FBV和CBV FBV 四、静态资源 4.1、静态文件 4.2、媒体文件 五、模板 5.1、寻找html模板 5.2、模板处理的本质 5.3、常见模板语法 5.4、内置模板函…

一.初识Linux 1-3操作系统概述Linux初识虚拟机介绍

目录 一.初识Linux 1.操作系统概述 计算机组成 硬件&#xff1a; 软件&#xff1a; 操作系统&#xff1a; 操作系统工作流程 操作系统作用 常见的操作系统 PC端&#xff1a; 移动端&#xff1a;&#xff08;掌上操作系统&#xff09; 一.初识Linux 2.Linux初识 linu…

GSP专版软件系统(医疗器械进销存)

产品概述 软件完全符合药监局GSP认证要求&#xff0c;可订制其它平台的数据对接; 业务流程清晰&#xff0c;操作简单合理&#xff0c;软件速度非常快; 完善的序列号(UDI)管理,并与整个系统融合在一起; 财务账和业务账完美结合; 可自定义的界面、布局管理;灵活的打印样式设计; 可…

Spring 事务原理一

从本篇博客开始&#xff0c;我们将梳理Spring事务相关的知识点。在开始前&#xff0c;想先给自己定一个目标&#xff1a;通过此次梳理要完全理解事务的基本概念及Spring实现事务的基本原理。为实现这个目标我想按以下几个步骤进行&#xff1a; 讲解事务中的一些基本概念使用Sp…

大数据导论(4)---大数据应用

文章目录 1. 在互联网中的应用1.1 推荐系统1.2 长尾理论1.3 推荐方法与模型1.4 推荐系统应用 2. 在其他领域的应用2.1 企业营销2.2 智慧交通 1. 在互联网中的应用 1.1 推荐系统 1. 推荐系统产生&#xff1a;  (1) 互联网的飞速发展使我们进入了信息过载的时代&#xff0c;搜索…

4D毫米波雷达——FFT-RadNet 目标检测与可行驶区域分割 CVPR2022

前言 本文介绍使用4D毫米波雷达&#xff0c;实现目标检测与可行驶区域分割&#xff0c;它是来自CVPR2022的。 会讲解论文整体思路、输入数据分析、模型框架、设计理念、损失函数等&#xff0c;还有结合代码进行分析。 论文地址&#xff1a;Raw High-Definition Radar for Mu…

【差分数组】【图论】【分类讨论】【整除以2】100213按距离统计房屋对数目

作者推荐 【动态规划】【数学】【C算法】18赛车 本文涉及知识点 差分数组 图论 分类讨论 整除以2 LeetCode100213按距离统计房屋对数目 给你三个 正整数 n 、x 和 y 。 在城市中&#xff0c;存在编号从 1 到 n 的房屋&#xff0c;由 n 条街道相连。对所有 1 < i < n…

【QT+QGIS跨平台编译】之二:【zlib+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、zlib介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、zlib介绍 zlib是一套通用的解压缩开源库&#xff0c;提供了内存&#xff08;in-memory&#xff09;压缩和解压函数。zlib是一套通用的解压缩开源库&#xff0c;提供了内存&#xff08;in-memory&am…

Mysql学习笔记系列(一)

本次mysql系列不会讲解具体的查询语句&#xff0c;而是放在mysql的一些性能优化和一些特性上&#xff0c;是学习笔记&#xff0c;供大家参考补充。 慢查询 MySQL的慢查询&#xff0c;全名是慢查询日志&#xff0c;是MySQL提供的一种日志记录&#xff0c;用来记录在MySQL中响应…

Paimon教程

教程来自尚硅谷 目录 教程来自尚硅谷1. 概述1.1 简介1.2 核心特性1.3 文件布局1.3.1 LSM Trees 2. 集成Flink2.1 安装&配置2.2 Catalog 3. 进阶使用3.1 写入性能3.1.1 并行度3.1.2 Compaction3.1.3 触发Compaction的Sorted Run数3.1.4 写入初始化3.1.5 内存 3.2 读取性能3.…

Unity下实现跨平台的RTMP推流|轻量级RTSP服务|RTMP播放|RTSP播放低延迟解决方案

2018年&#xff0c;我们开始在原生RTSP|RTMP直播播放器的基础上&#xff0c;对接了Unity环境下的低延迟播放&#xff0c;毫秒级延迟&#xff0c;发布后&#xff0c;就得到了业内一致的认可。然后我们覆盖了Windows、Android、iOS、Linux的RTMP推送、轻量级RTSP服务和RTSP|RTMP播…

数学建模--PageRank算法的Python实现

文章目录 1. P a g e R a n k PageRank PageRank算法背景2. P a g e R a n k PageRank PageRank算法基础2.1. P a g e R a n k PageRank PageRank问题描述2.2.有向图模型2.3.随机游走模型 3. P a g e R a n k PageRank PageRank算法定义3.1. P a g e R a n k PageRank PageRank…

springcloud Hystrix断路器

文章目录 代码下载简介写服务测试高并发测试写消费者端测试2 服务降级先修改cloud-provider-hystrix-payment8001修改cloud-consumer-feign-hystrix-order80 目前问题方法2:测试 服务熔断实操测试 服务监控hystrixDashboard建mudlue断路器演示(服务监控hystrixDashboard) 代码下…

第6章 SpringBoot缓存管理

学习目标 了解SpringBoot的默认缓存 熟悉SpringBoot中Redis的缓存机制及实现 掌握SpringBoot整合Redis的缓存实现 缓存是分布式系统中的重要组件&#xff0c;主要解决数据库数据的高并发访问问题。在实际开发中&#xff0c;尤其是用户访问量较大的网站&#xff0c;为了提高服…

(上) C语言中的语句分类及分支语句:if语句、switch语句介绍

目录 前言 一、语句的分类 1. 空语句 2. 表达式语句 3. 函数调用语句 4. 复合语句 5. 控制语句 二、分支语句 1. if语句 (1) if的使用 (2) else的使用 (3) 分支中包含多条语句 (4) 嵌套if (5) 悬空else问题 2. switch语句 (1) if语句和switch语句的对比 (2) s…