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) {// 创建一个桶并命名为asiatripminioClient.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();//上传文件@Testpublic  void upload() {//根据扩展名取出mimeTypeContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(".mp4");// 对于不含文件扩展名或文件扩展名未知的文件,字节流是通用的mimeTypeString 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.hqwc.cn/news/421399.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解析EMC滤波器:功用、设计与应用?|深圳比创达电子EMC

电磁兼容性&#xff08;EMC&#xff09;一直是电子设备设计中的关键问题。为了有效应对电磁干扰&#xff0c;EMC滤波器成为设计中不可或缺的一环。本文将深入探讨EMC滤波器的各个方面&#xff0c;包括其定义、原理、设计要点以及在不同领域的应用。通过对这些内容的递进式阐述&…

第二周,第二期技术动态

大家好&#xff0c;才是真的好。 又到周五&#xff0c;我们继续介绍与Domino相关产品新闻&#xff0c;以及互联网或其他IT行业动态等。 一、Domino 12.0.2FP3补丁发布 本周四&#xff0c;HCL发布了Domino 12.0.2FP3补丁程序&#xff0c;有HCL官网注册的企业账户现在可以下载…

模拟jQuery简单封装$方法

jQuery是一个快速、简洁的JavaScript框架&#xff0c;$是jQuery的核心选择器&#xff0c;由$获取到需要修改的元素&#xff0c;然后对元素进行一系列方法操作 模拟jQuery简单封装$方法

【前端设计】card

欢迎来到前端设计专栏&#xff0c;本专栏收藏了一些好看且实用的前端作品&#xff0c;使用简单的html、css语法打造创意有趣的作品&#xff0c;为网站加入更多高级创意的元素。 html <!DOCTYPE html> <html lang"en"> <head><meta charset&quo…

SwiftUI 纯手工打造 100% 可定制的导航栏

功能需求 何曾几时,我们是否也厌倦了 SwiftUI 界面中刻板守旧的导航栏外观,而想要自己动手充分展示灵动炸裂的创造力呢? 如上图所示:我们在 SwiftUI 中通过纯手工打造了一款 100 在本篇博文中,您将学到以下内容 功能需求1. 导航栏基本结构2. 如何感知当前发生用户拖拽行为…

Docker基础语法

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

外汇天眼:每一个骗局的背后,可能是倾家荡产!

在网络科技还没有发达的以前&#xff0c;骗子主要通过线下揽客的方式推荐各类虚假的投资理财项目&#xff0c;有的甚至打着专门的理财咨询机构吸引了一大批新手投资者。在当时&#xff0c;外汇投资还不为多数人知道&#xff0c;随便忽悠“高利益保本”就有投资者上当受骗。 现如…

flinkcdc 3.0 尝鲜

本文会将从环境搭建到demo来全流程体验flinkcdc 3.0 包含了如下内容 flink1.18 standalone搭建doris 1fe1be 搭建整库数据同步测试各同步场景从检查点重启同步任务 环境搭建 flink环境(Standalone模式) 下载flink 1.18.0 链接 : https://archive.apache.org/dist/flink/flink…

YOLOv8改进 | 主干篇 | 低照度图像增强网络SCINet改进黑暗目标检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是低照度图像增强网络SCINet,SCINet(自校正照明网络)是一种专为低光照图像增强设计的框架。它通过级联照明学习过程和权重共享机制来处理图像,优化了照明部分以提升图像质量。我将该网络集成在YOLOv8的主干上针对于图像的输入进行增…

网上训练补题

1.Codeforces Round 920 (Div. 3) A. 简单判断出边长即可 #include <stdio.h> #include <stdlib.h> #include <math.h> int main() {int n;scanf("%d", &n);while (n--){int x, y;scanf("%d%d", &x, &y);int e, f;scanf(&q…

SQL 注入总结(详细)

一、前言 这篇文章是最近学习 SQL 注入后的笔记&#xff0c;里面整理了 SQL 常见的注入方式&#xff0c;供大家学习了解 SQL 注入的原理及方法&#xff0c;也方便后续自己回顾&#xff0c;如有什么错误的地方欢迎指出&#xff01; 二、判断注入类型 按照注入点类型分类 数字型…

【Coding】寒假每日一题Day.5. 互质数的个数

题目来源 题目来自于AcWing平台&#xff1a;https://www.acwing.com/problem/content/4971/ 以blog的形式记录程序设计算法学习的过程&#xff0c;仅做学习记录之用。 题目描述 输入输出格式与数据范围 样例 第一组&#xff1a; 2 516第二组&#xff1a; 12 711943936思路…