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

分布式文件系统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();
     }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

html 会跳舞的时间动画特效

下面是是代码&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta h…

Python环境下一维时间序列信号的时频脊线追踪方法

瞬时频率是分析调频信号的一个重要参数&#xff0c;它表示了信号中的特征频率随时间的变化。使用短时傅里叶变换或小波变换获得信号的时频表示TFR后&#xff0c;从TFR中估计信号各分量的瞬时频率&#xff0c;即可获得信号中的特征信息。在TFR中&#xff0c;调频信号的特征分量通…

考试查分场景重保背后,我们如何进行可用性测试

作者&#xff1a;暮角 随着通过互联网音视频与知识建立连接的新学习方式在全国范围内迅速普及&#xff0c;在线教育/认证考试的用户规模呈井喷式增长。但教育容不得半点马虎与妥协&#xff0c;伴随用户规模不断增长&#xff0c;保证系统稳定性、有效避免千万考生考试时遭遇故障…

JAVA RPC Thrift基操实现与微服务间调用

一、Thrift 基操实现 1.1 thrift文件 namespace java com.zn.opit.thrift.helloworldservice HelloWorldService {string sayHello(1:string username) }1.2 执行命令生成Java文件 thrift -r --gen java helloworld.thrift生成代码HelloWorldService接口如下 /*** Autogene…

Oracle Vagrant Box 无法登录的2个问题

安装Oracle Database 19c 的 VagrantBox &#xff0c;非常顺利&#xff0c;耗时如下&#xff1a; real 30m36.783s user 0m0.000s sys 0m0.047s前面一切顺利&#xff0c;但是vagrant ssh和vagrant putty均不能登录虚机。我的环境是Windows 11&#xff0c;Vagrant 2.…

安卓Spinner文字看不清

Holo主题安卓13的Spinner文字看不清&#xff0c;明明已经解决了&#xff0c;又忘记了。 spinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {TextView textV…

【Python】使用Anaconda创建PyTorch深度学习虚拟环境

使用Anaconda Prompt 查看环境: conda env list 创建虚拟环境&#xff08;python3.10&#xff09;&#xff1a; conda create -n pytorch python3.10 激活创建的环境&#xff1a; conda activate pytorch在虚拟环境内安装PyTorch&#xff1a; 【Python】CUDA11.7/11.8安…

词语的魔力:语言在我们生活中的艺术与影响

Words That Move Mountains: The Art and Impact of Language in Our Lives 词语的魔力&#xff1a;语言在我们生活中的艺术与影响 Hello there, wonderful people! Today, I’d like to gab about the magical essence of language that’s more than just a chatty tool in o…

vue3-组件通信

1. 父传子-defineProps 父组件&#xff1a; <script setup> import { ref } from vueimport SonCom from /components/Son-com.vueconst message ref(parent)</script><template><div></div><SonCom car"沃尔沃" :message"…

应用层—HTTPS详解(对称加密、非对称加密、密钥……)

文章目录 HTTPS什么是 HTTPSHTTPS 如何加密HTTPS 的工作过程对称加密非对称加密 HTTPS 什么是 HTTPS HTTPS 也是一个应用层的协议。是在 HTTP 协议的基础上引入的一个加密层。 由来&#xff1a;HTTP 协议内容都是按照文本的方式明纹传输&#xff0c;这就导致在传输过程中出现…

万字长文:C++模板与STL【模板】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;C从基础到进阶 1 模板&#x1f30f;1.1 函数模板&#x1f349;1.1.1 函数模板语法&#x1f349;1.1.2 函数模板注意事项&#x1f349;1.1.3 函数模板案例&#x1f349;1.1.4 普通函数与函数…

C# WebApi传参及Postman调试

概述 欢迎来到本文&#xff0c;本篇文章将会探讨C# WebApi中传递参数的方法。在WebApi中&#xff0c;参数传递是一个非常重要的概念&#xff0c;因为它使得我们能够从客户端获取数据&#xff0c;并将数据传递到服务器端进行处理。WebApi是一种使用HTTP协议进行通信的RESTful服…

Dubbo 3.2版本分析Provider启动时操作

Dubbo 3.2版本分析Provider启动时操作 前言例子分析onStarting 模块doStart 模块 小结 前言 上一篇文章&#xff0c;我们分析了 Dubbo 3.2 版本在 Provider 启动前的操作流程&#xff0c;这次我们具体分析具体它的启动过程&#xff0c;揭开它的神秘面纱。 例子 这里我们还是…

BO、VO层应用实例

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; BO、VO层应用实例 BO&#xff08;Business Object&#xff09;层是一种用于处理业务逻辑的组件层。BO层主要负责封装和处理与业务相关的逻辑和数据操作&#xff0c;它…

Conda python管理环境environments 一 从入门到精通

Conda系列&#xff1a; 翻译: Anaconda 与 miniconda的区别Miniconda介绍以及安装Conda python运行的包和环境管理 入门 使用 conda&#xff0c;可以创建、导出、列出、删除和更新 具有不同 Python 版本和/或 安装在其中的软件包。在两者之间切换或移动 环境称为激活环境。您…

Oracle 隐式数据类型转换

目录 Oracle类型转换规则&#xff1a; 看如下实验&#xff1a; 1、创建一张表&#xff0c;字段id的类型为number&#xff0c;id字段创建索引&#xff0c;插入一条测试数据 2、我们做如下查询&#xff0c;id的值设置为字符型的1 3、查看执行计划&#xff1a; Oracle类型转换…

用于垃圾回收的运行时配置选项

反馈 本文内容 指定配置的方法垃圾回收的风格管理资源使用情况大型页面 显示另外 4 个 此页面包含有关 .NET 运行时垃圾回收器 (GC) 设置的信息。 如果你要尝试让正在运行的应用达到最佳性能&#xff0c;请考虑使用这些设置。 然而&#xff0c;在特定情况下&#xff0c;默认…

[小程序]Http网络请求

一、数据请求限制 出于安全性(bushi)考虑&#xff0c;小程序请求的数据接口必须具备以下两个条件&#xff1a; ①只能请求Https类型 ②必须将接口域名添加到信任列表中 1.配置request合法域名 配置步骤如下&#xff1a;小程序管理后台->开发->开发设置->服务器域名-&g…

【Android】app中阻塞的looper为什么可以响应touch事件

这里&#xff0c;我们考虑一个问题&#xff0c;Android中的应用是一个looper线程&#xff0c;没有任务时就阻塞着&#xff0c;其他线程通过handler调用等方式向主线程looper发送任务&#xff0c; 如果点击应用上的按钮&#xff0c;应用是怎么及时响应的呢&#xff0c; 是专门启…

Docker基础语法

目录 一.docker安装 二.docker基础名词 三.docker基础命令 四.命令别名 五.数据卷 六.挂载本地目录或文件 七.Docker镜像 八.网络 一.docker安装 1.安装yum工具 yum install -y yum-utils device-mapper-persistent-data lvm2 2.安装 docker yum源 yum-config-manag…