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

2024-01-22 07:36

本文主要是介绍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();}
}

这篇关于1.使用分布式文件系统Minio管理文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/632277

相关文章

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND