当前位置: 首页 > news >正文

【Java互联网技术】MinIO分布式文件存储服务

应用场景

互联网海量非结构化数据的存储

基本概念

Object:存储的基本对象,如文件、字节流等

Bucket:存储Object的逻辑空间,相当于顶层文件夹

Drive:存储数据的磁盘,在MinIO启动时,以参数的方式传入

Set:多个Drive的集合。分布式部署时划分一个或多个Set,一个Object存在Set上,Set中的每个Drive中都会有相同的Object

特点

  • 部署简单,整体只有一个二进制文件,还可支持各种平台
  • 支持海量存储,单个对象最大可达5TB
  • 兼容Amazon S3接口,充分考虑开发人员的需求和体验
  • 低冗余且磁盘损坏高容忍
  • 读写性能优异(HDD在16个结点的MinIO集群的读速度可达10GB/s,写速度可达8.5GB/s)

纠删码

Erasure Code(EC)。MinIO使用纠删码来保证高可靠性,使用highwayhash来处理数据损坏。n份原始数据保存后会生成m份纠删码算法转换后的数据,当有任意小于等于m份的数据损坏,就能通过剩下的额数据还原出来。

存储形式

文件上传到MinIO后,存储在对应的磁盘中,以Bucket名称为目录,文件名为下一级目录,这个目录下保存文件的编码数据块、校验块、元数据文件(json格式)

Docker部署MinIO(普通模式)

1、拉取镜像

docker pull minio/minio

2、创建挂载目录

mkdir /wanfeng/minio/data
mkdir /wanfeng/minio/config

3、运行容器

docker run -p 9000:9000 -p 9001:9001 --name wanfeng_minio --privileged=true \
-e "MINIO_ROOT_USER=登录用户名" \
-e "MINIO_ROOT_PASSWORD=登录密码" \
-v /wanfeng/minio/data:/data \
-v /wanfeng/minio/config:/root/.minio \
-d minio/minio server /data --console-address ":9001"
  • -p 9000:9000 -p 9001:9001:必须暴露出两个端口用户客户端和服务端
  • MINIO_ROOT_USER:用户名
  • MINIO_ROOT_PASSWORD:密码
  • /wanfeng/minio/data:/data:数据文件映射目录
  • /wanfeng/minio/config:/root/.minio:配置文件映射目录
  • –console-address “:9001”:指定服务端端口号(通过该端口访问minio服务)

Docker部署MinIO(纠删码模式)

纠删码的作用就是在上传一份数据后,会生成n个原始数据块和n个奇偶校验块,若任意丢失不超过n块盘,都可以进行数据恢复。

1、在docker启动时增加多块盘

docker run -p 9000:9000 -p 9001:9001 --name wanfeng_minio --privileged=true \
-e "MINIO_ROOT_USER=登录用户名" \
-e "MINIO_ROOT_PASSWORD=密码" \
-v /wanfeng/minio/config:/root/.minio \
-v /wanfeng/minio/data1:/data1 \
-v /wanfeng/minio/data2:/data2 \
-v /wanfeng/minio/data3:/data3 \
-v /wanfeng/minio/data4:/data4 \
-v /wanfeng/minio/data5:/data5 \
-v /wanfeng/minio/data6:/data6 \
-d minio/minio server /data{1...6} --console-address ":9001"

Docker部署MinIO(分布式集群)

分布式集群可以避免单台服务器故障带来的影响(单点故障),将minio

Java API整合MinIO

1、引入依赖

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.3.0</version>
</dependency><!-- https://mvnrepository.com/artifact/me.tongfei/progressbar -->
<dependency><groupId>me.tongfei</groupId><artifactId>progressbar</artifactId><version>0.5.3</version>
</dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.10.0</version>
</dependency>

2、API使用

@SpringBootTest
public class MinioApplicationTests {private MinioClient minioClient;public static final String IMAGE_FILE_NAME = "wallhaven01.jpg";public static final String TEXT_FILE_NAME = "笔记.txt";public static final String UPLOAD_FOLDER_PATH = "src/test/resources/upload";public static final String DOWNLOAD_FOLDER_PATH = "src/test/resources/download";@BeforeEachpublic void connectMinio(){minioClient = MinioClient.builder().endpoint(ServerConstant.CENTOS_IP_ADDRESS, 9000, false).credentials(LoginConstant.MINIO_ROOT_USERNAME, LoginConstant.MINIO_ROOT_PASSWORD).build();}/*** 本地文件上传*/@Testpublic void uploadFile(){try {//判断bucket是否存在boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket("ectest").build());if(!bucketExists){minioClient.makeBucket(MakeBucketArgs.builder().bucket("ectest").build());}else{System.out.println("Bucket[ectest] already exists");}/*** bucket:指定上传的bucket* object:上传到minio的路径(到文件名)* filename:上传的本地文件路径(到文件名)*/minioClient.uploadObject(UploadObjectArgs.builder().bucket("ectest").object(IMAGE_FILE_NAME).filename(UPLOAD_FOLDER_PATH + File.separator + IMAGE_FILE_NAME).build());} catch (Exception e){e.printStackTrace();}}/*** 上传流*/@Testpublic void uploadInputStream() throws Exception {File file = new File(UPLOAD_FOLDER_PATH + File.separator + IMAGE_FILE_NAME);FileInputStream fileInputStream = new FileInputStream(file);minioClient.putObject(PutObjectArgs.builder().bucket("ectest").object("image_" + NumberFactory.getRandomNumber(5) + ".jpg" ).stream(fileInputStream, fileInputStream.available(), -1).build());fileInputStream.close();}/*** 下载文件*/@Testpublic void downloadFile(){try {//判断bucket是否存在boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket("ectest").build());if(!bucketExists){minioClient.makeBucket(MakeBucketArgs.builder().bucket("ectest").build());}else{System.out.println("Bucket[ectest] already exists");}/*** bucket:指定上传的bucket* object:minio中的文件路径* filename:下载到本地的路径(到文件名)*/minioClient.downloadObject(DownloadObjectArgs.builder().bucket("ectest").object(IMAGE_FILE_NAME).filename(DOWNLOAD_FOLDER_PATH + File.separator + "minio_image_" + NumberFactory.getRandomNumber(8) + ".jpg").build());}catch (Exception e){e.printStackTrace();}}/*** 下载流*/@Testpublic void downloadInputStream() throws Exception{//获取流InputStream inputStream = minioClient.getObject(GetObjectArgs.builder().bucket("ectest").object(IMAGE_FILE_NAME).build());File file = new File(DOWNLOAD_FOLDER_PATH + File.separator + "image_aaa.jpg");FileUtils.copyInputStreamToFile(inputStream, file);inputStream.close();//直接把流保存到本地文件minioClient.downloadObject(DownloadObjectArgs.builder().bucket("ectest").object(IMAGE_FILE_NAME).filename(DOWNLOAD_FOLDER_PATH + File.separator + "image_bbb.jpg").build());}}

SpringBoot整合MinIO

本质就是把连接minio服务的参数放在配置文件中,并通过Bean对象在SpringBoor应用启动时生成MinioClient对象。

1、配置文件application.yml

minio:endpoint: http://ip:portrootUserName: 用户名rootPassword: 密码bucketName: bucket名称

2、读取配置属性的类

@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {private String endpoint;private String rootUserName;private String rootPassword;private String bucketName;
}

3、生成MinioClient对象的类

@Configuration
public class MinioClientFactory {@Resourceprivate MinioProperties minioProperties;@Beanpublic MinioClient getDefaultMinioClient(){return MinioClient.builder().endpoint(minioProperties.getEndpoint()).credentials(minioProperties.getRootUserName(), minioProperties.getRootPassword()).build();}
}

4、编写controller测试

@RestController
@Slf4j
@RequestMapping("/minio")
public class MinioController {@Resourceprivate MinioClient minioClient;@Value("${minio.bucketName}")private String bucketName;@GetMapping("/list_object_name")public List<String> listObject() throws Exception {Iterable<Result<Item>> objectResults = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());List<String> objectNameList = new ArrayList<>();for (Result<Item> objectResult : objectResults) {Item item = objectResult.get();objectNameList.add(item.objectName());}return objectNameList;}
}

相关文章:

【Java互联网技术】MinIO分布式文件存储服务

应用场景 互联网海量非结构化数据的存储 基本概念 Object&#xff1a;存储的基本对象&#xff0c;如文件、字节流等 Bucket&#xff1a;存储Object的逻辑空间&#xff0c;相当于顶层文件夹 Drive&#xff1a;存储数据的磁盘&#xff0c;在MinIO启动时&#xff0c;以参数的…...

在visual studio里配置Qt插件并运行Qt工程

Qt插件&#xff0c;也叫qt-vsaddin&#xff0c;它以*.vsix后缀名结尾。visual studio简称为VS&#xff0c;从visual studio 2010版本开始&#xff0c;VS支持Qt框架的开发&#xff0c;Qt以插件方式集成到VS里。这里简述在visual studio 2019里配置Qt 5.14.2插件&#xff0c;并配…...

【C语言】利用数组处理批量数据(字符数组)

前言:前面已经介绍了&#xff0c;字符数据是以字符的ASCII代码存储在存储单元中的&#xff0c;一般占一个字节。由于ASCII代码也属于整数形式&#xff0c;因此在C99标准中&#xff0c;把字符类型归纳为整型类型中的一种。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x…...

算法通过村第十二关-字符串|白银笔记|经典面试题

文章目录 前言1. 反转问题1.1 反转字符串1.2 k个一组反转1.3 仅仅反转字母1.3.1 采用栈实现操作1.3.2 采用双指针实现操作 1.4 反转字符串里面的单词1.4.1 使用语言提供的方法来解决(内置API)1.4.2 如何优雅自己实现上述功能 2. 验证回文串3. 字符串中的第一个唯一字符4. 判断是…...

《视觉 SLAM 十四讲》V2 第 5 讲 相机与图像

文章目录 相机 内参 && 外参5.1.2 畸变模型单目相机的成像过程5.1.3 双目相机模型5.1.4 RGB-D 相机模型 实践5.3.1 OpenCV 基础操作 【Code】OpenCV版本查看 5.3.2 图像去畸变 【Code】5.4.1 双目视觉 视差图 点云 【Code】5.4.2 RGB-D 点云 拼合成 地图【Code】 习题题…...

使用libmodbus库开发modbusTcp从站(支持多个主站连接)

使用libmodbus库开发modbusTcp从站&#xff08;支持多个主站连接&#xff09; Chapter1 使用libmodbus库开发modbusTcp从站(支持多个主站连接)rdsmodbusslave.hrdsmodbusslave.cppmain.cpp Chapter1 使用libmodbus库开发modbusTcp从站(支持多个主站连接) 参考链接&#xff1a…...

GPT系列论文解读:GPT-2

GPT系列 GPT&#xff08;Generative Pre-trained Transformer&#xff09;是一系列基于Transformer架构的预训练语言模型&#xff0c;由OpenAI开发。以下是GPT系列的主要模型&#xff1a; GPT&#xff1a;GPT-1是于2018年发布的第一个版本&#xff0c;它使用了12个Transformer…...

(四)激光线扫描-光平面标定

在上一章节,已经实现了对激光线条的中心线提取,并且在最开始已经实现了对相机的标定,那么相机标定的作用是什么呢? 就是将图像二维点和空间三维点之间进行互相转换。 1. 什么是光平面 激光发射器投射出一条线,形成的一个扇形区域平面就是光平面,也叫光刀面,与物体相交…...

妙不可言的Python之旅----(二)

Python基础语法 什么是字面量 字面量&#xff1a;在代码中&#xff0c;被写下来的的固定的值&#xff0c;称之为字面量 常用的值类型 类型 描述 说明 数字&#xff08;Number&#xff09; 支持 • 整数&#xff08;int&#xff09; • 浮点数&#xff08;float&#xff…...

cartographer(1)-运行

1.下载数据集 #1.下载数据集&#xff1a; mkdir /home/tang/bagfiles#2.开始二维建图 cd /home/tang/carto_ws/cartographer_detailed_comments_ws/install_isolated/source install_isolated/setup.bash rospack profile #新装的包索引地址存在ros的环境里 roslaunch ca…...

C++:模板进阶与继承

模板进阶与继承 模板进阶1.非类型的模板参数2.模板的特化2.1特化的概念2.2函数模板特化2.3类模板特化2.4全特化和偏特化2.4.1全特化2.4.2偏特化 3.模板的分离编译3.1同文件分离3.2不同文件下分离 继承1.继承的概念和定义1.1继承的概念1.2继承的定义1.2.1定义格式1.2.2继承关系和…...

vue-img-cutter 实现图片裁剪[vue 组件库]

借助 vue-img-cutter 可以在网页端实现图片裁剪功能&#xff0c;最终功能效果如下&#xff1a; 组件 npm 安装 npm install vue-img-cutter2 --save-dev # for vue2 npm install vue-img-cutter3 --save-dev # for vue3vue-img-cutter使用 template模板标签模块&#xff0c…...

手把手教你从零开始腾讯云服务器部署(连接建站教程)

使用腾讯云服务器搭建网站全流程&#xff0c;包括轻量应用服务器和云服务器CVM建站教程&#xff0c;轻量可以使用应用镜像一键建站&#xff0c;云服务器CVM可以通过安装宝塔面板的方式来搭建网站&#xff0c;腾讯云服务器网txyfwq.com分享使用腾讯云服务器建站教程&#xff0c;…...

微信开放平台第三方开发,实现代小程序备案申请

大家好&#xff0c;我是小悟 微信小程序备案整体流程总共分为五个环节&#xff1a;备案信息填写、平台初审、工信部短信核验、通管局审核和备案成功。 服务商可以代小程序发起备案申请。在申请小程序备案之前&#xff0c;需要确保小程序基本信息已填写完成、小程序至少存在一个…...

设计模式——11. 享元模式

1. 说明 享元模式(Flyweight Pattern)是一种结构型设计模式,它旨在减少系统中相似对象的内存占用或计算开销,通过共享相同的对象来达到节省资源的目的。 享元模式的核心思想是将对象的状态分为内部状态(Intrinsic State)和外部状态(Extrinsic State): 内部状态是对象…...

【LLM】主流大模型体验(文心一言 科大讯飞 字节豆包 百川 阿里通义千问 商汤商量)

note 智谱AI体验百度文心一言体验科大讯飞大模型体验字节豆包百川智能大模型阿里通义千问商汤商量简要分析&#xff1a;仅从测试“老婆饼为啥没有老婆”这个问题的结果来看&#xff0c;chatglm分点作答有条理&#xff08;但第三点略有逻辑问题&#xff09;&#xff1b;字节豆包…...

CSS小计

1&#xff1a;设置图片随窗缩放 使用百分比 width: 100%;height: 100%; 使用vmin: 将可视区域分为100vmin width: 100vmin;height: 100vmin; 2:设置字体颜色与背景色融合 mix-blend-mode: difference 3: 设置宽度自适应 width:fit-content 4:外边距合并 当两个相领的两个容…...

机器学习:决策树

决策树 决策树是一种基于树形结构的模型&#xff0c;决策树从根节点开始&#xff0c;一步步走到叶子节点&#xff08;决策&#xff09;&#xff0c;所有的数据最终都会落到叶子节点&#xff0c;既可以做分类也可以做回归。 特征选择 根节点的选择该用哪一个特征呢&#xff…...

xxl-job的原理(2)—调度中心管理注册信息

一、调度中心管理注册信息 1.JobApiController 执行器调用调度中心的url来实现注册、下线、回调等操作&#xff1b;其主要的实现类是JobApiController&#xff0c;调用/api/registry接口注册执行器信息&#xff0c;调用/api/registryRemove接口下线执行器信息&#xff0c;调用…...

小白入门pytorch(二)----神经网络

本文为&#x1f517;[小白入门Pytorch]学习记录博客 文章目录 前言一、神经网络的组成部分1.神经元2.神经网络层3.损失函数4.优化器 二、Pytorch构建神经网络中的网络层全连接层2.卷积层3.池化层4.循环神经网络5.转置卷积层6.归一化层7.激活函数层 三、数据加载与预处理1.数据加…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...