MinIO

1、基本概念


1.1、MinIO介绍


  • MinIO 是在 Apache License v2.0 下发布的对象存储服务器

  • MinIO 服务器足够轻,可以与应用程序堆栈捆绑在一起,类似于 NodeJS,Redis 和 MySQL

  • MinIO 是一种高性能的分布式对象存储服务器,用于大型数据基础设施

1.2、基础概念


  • Object:存储到MinIO的基本对象,就是每个上传的文件

  • Bucket:用来存储Object的逻辑空间,每个Bucket之间的数据是相互隔离的。对于客户端而言,相当于一个存放文件的顶层文件夹

  • Drive:存储数据的磁盘,在MinIO启动时,以参数的方式传入。MinIO中所有的对象数据都存储在Drive里

  • Set:一组Drive的集合,分布式部署根据集群规模自动划分一个或多个Set,每个Set中的Drive分布在不同位置

  • 一个对象存储在一个Set上

  • 一个集群划分为多个Set

  • 一个Set包含的Drive数量是固定的,默认由系统根据集群规模自动计算得出

  • 一个Set中的Drive尽可能分布在不同节点上

1.3、MinIO优点


  • 部署简单,支持各种平台

  • minio支持海量存储,支持单个对象最大5TB

  • 低冗余且磁盘损坏高容忍,标准且最高的数据冗余系数为2(即存储一个1M的数据对象,实际占用磁盘空间为2M)。但在任意n/2块disk损坏的情况下依然可以读出数据(n为一个纠删码集合(Erasure Coding Set)中的disk数量)。并且这种损坏恢复是基于单个对象的,而不是基于整个存储卷的

  • 读写性能好

1.4、纠删码EC


  • Erasure Code,MinlO使用纠删码机制来保证高可靠性,使用highwayhash来处理数据损坏

  • 纠删码是一种恢复丢失和损坏数据的数学算法,MinIO采用Reed-Solomon code将对象拆分为N/2奇偶校验块。比如若是12块盘,一个对象会被分为6个数据块和6个奇偶校验块,可以任意丢失6块盘,仍可以从剩下的盘中的数据进行恢复

  • 纠删码可通过数学计算,把丢失的数据进行还原,它可以将n份原始数据,增加m份数据,并能通过n+m份中的任意n份数据,还原为原始数据

  • 若有任意小于等于m份的数据失效,仍然能通过剩下的数据还原出来

1.5、存储形式


  • 文件上传到MinIO,会在对应的数据磁盘中,以Bucket名为目录,文件名为下一级目录,文件名下是part.1(编码数据块及检验块)和xl.meta(元数据文件)

2、常用API


2.1、判断桶是否存在


  • boolean bucketExists()

minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());

2.2、创建桶


  • void makeBucket()

minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());

2.3、显示所有桶信息


  • List listBuckets()

minioClient.listBuckets();

2.4、列出桶的对象信息


  • Iterable listObjects()

minioClient.listObjects(ListObjectsArgs.builder()

.bucket(bucketName)

.startAfter("2022")

.prefix("2") // 指定前缀

.maxKeys(100) // 最大数量

.recursive(true) //递归显示桶下的对象

.build()

);

2.5、删除桶


  • void removeBucket()

minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());

2.6、通过流上传文件


  • ObjectWriteResponse putObject()

minioClient.putObject(PutObjectArgs.builder()

.bucket(bucketName)

.object(fileName)

.stream(file.getInputStream(), file.getSize(), -1)

.contentType(file.getContentType())

.build()

);

  • 添加的Object大小不能超过 5GB

  • 若添加的Object和已有的同名,会进行覆盖

  • OSS没有文件夹的概念,所有资源都是以文件来存储,可通过“/”模拟文件夹

2.7、上传文件内容


  • void uploadObject()(不常用,一般适合上传磁盘文件)

minioClient.uploadObject(UploadObjectArgs

.builder()

.bucket(bucketName)

.object(fileName) //上传到minio的对象名

.filename(fileName) //要上传的文件

.build()

);

2.8、获取对象数据


  • GetObjectResponse getObject()

minioClient.getObject(GetObjectArgs

.builder()

.bucket(bucketName)

.object(fileName)

.build()

);

2.9、下载文件


  • void downloadObject()

minioClient.downloadObject(DownloadObjectArgs

.builder()

.bucket(bucketName)

.object(fileName) //minio中的对象名(目录用"/"隔开)

.filename("D:\\test.txt") //下载到磁盘的路径

.build()

);

2.10、删除文件


  • void removeObject()

minioClient.removeObject(

RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());

2.11、复制文件


  • ObjectWriteResponse copyObject()

minioClient.copyObject(CopyObjectArgs

.builder()

.source(CopySource.builder()

.bucket(bucketName1)

.object(fileName1)

.build()

)

.bucket(bucketName2)

.object(fileName2)

.build()

);

  • 在 bucketName2 中创建一个和 bucketName1 中的 fileName1 一样的对象 fileName2

3、整合SpringBoot(单机版)


3.1、配置文件


minio:

endpoint: http://127.0.0.1:9000

accessKey: minioadmin

secretKey: minioadmin

bucketName: bucket-1

3.2、配置类


@Configuration

publicclassMinioConfig {

@Value("${minio.endpoint}")

privateStringendpoint;

@Value("${minio.accessKey}")

privateStringaccessKey;

@Value("${minio.secretKey}")

privateStringsecretKey;

@Bean

publicMinioClientminioClient(){

returnMinioClient

.builder()

.endpoint(endpoint)

.credentials(accessKey,secretKey)

.build();

}

}

3.3、Controller层


@Autowired

privateMinioClientminioClient;

@Value("${minio.bucketName}")

privateStringbucketName;

3.3.1、显示所有桶

@GetMapping("/list")

publicList<Object>list() throwsException {

//获取bucket列表

Iterable<Result<Item>>buckets=minioClient.listObjects(

ListObjectsArgs.builder().bucket(bucketName).build()

);

Iterator<Result<Item>>iterator=buckets.iterator();

List<Object>list=newArrayList<>();

while (iterator.hasNext()) {

Itemitem=iterator.next().get();//文件对象

list.add(JSON.parse(String.format(

"{'fileName':'%s','fileSize':'%s'}",

item.objectName(),//文件名

formatFileSize(item.size()))));//文件大小

}

returnlist;

}

//格式化文件大小

privatestaticStringformatFileSize(longfileSize) {

DecimalFormatdf=newDecimalFormat("#.00");

if (fileSize==0) {

return"0B";

}

StringfileSizeString;

if (fileSize<1024) {

fileSizeString=df.format((double) fileSize) +"B";

} elseif (fileSize<1048576) {

fileSizeString=df.format((double) fileSize/1024) +"KB";

} elseif (fileSize<1073741824) {

fileSizeString=df.format((double) fileSize/1048576) +"MB";

} else {

fileSizeString=df.format((double) fileSize/1073741824) +"GB";

}

returnfileSizeString;

}

3.3.2、文件上传

@PostMapping("/upload")

publicStringupload(

@RequestParam(name="file", required=false) MultipartFilefile) {

if (file==null) {

return"上传失败,文件为空";

}

StringfileName=file.getOriginalFilename();

try {

minioClient.putObject(PutObjectArgs.builder()

.bucket(bucketName)

.object(fileName)

.stream(file.getInputStream(), file.getSize(), -1)

.contentType(file.getContentType())

.build()

);

} catch (Exceptione) {

e.printStackTrace();

}

return"bucketName:"+bucketName+",fileName:"+fileName;

}

3.3.3、文件下载

@GetMapping("/download/{fileName}")

publicStringdownload(HttpServletResponseres, @PathVariable("fileName") StringfileName) {

try {

//获取对象信息

StatObjectResponsestatObject=minioClient.statObject(

StatObjectArgs.builder().bucket(bucketName).object(fileName).build());

res.setContentType(statObject.contentType());

res.setHeader(

"Content-Disposition",

"attachment;fileName"+URLEncoder.encode(fileName, "utf-8")

);

//下载

minioClient.downloadObject(DownloadObjectArgs.builder()

.bucket(bucketName)

.object(fileName)

.filename(fileName)

.build()

);

return"下载成功";

} catch (Exceptione) {

e.printStackTrace();

}

return"下载失败";

}

3.3.4、文件删除

@DeleteMapping("/delete/{fileName}")

publicStringdelete(@PathVariable("fileName") StringfileName) {

try {

minioClient.removeObject(

RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());

return"删除成功";

} catch (Exceptione) {

e.printStackTrace();

}

return"删除失败";

}

3.3.5、文件批量上传

@PostMapping("/uploadBatch")

publicStringuploadBatch(

@RequestParam(name="file", required=false) MultipartFile[] files) {

if (files==null||files.length==0) {

return"上传失败,文件为空";

}

List<String>fileNames=newArrayList<>(files.length);

for (MultipartFilefile : files) {

StringoriginalFilename=file.getOriginalFilename();

fileNames.add(originalFilename);

try {

minioClient.putObject(PutObjectArgs.builder()

.bucket(bucketName)

.object(originalFilename)

.stream(file.getInputStream(), file.getSize(), -1)

.contentType(file.getContentType())

.build()

);

} catch (Exceptione) {

e.printStackTrace();

}

}

return"bucketName:"+bucketName+",fileNames:"+fileNames;

}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值