本文版本环境
- minio服务器:minio version RELEASE.2022-07-08T00-05-23Z
历史版本下载地址
此处简单放置一个下载方式
1 2 3 4
| curl -X GET -o minio.rpm https://meethigher.top/cloud/download/0/sh/19a5fd77a60dc33ecfb22bbbe6247585 rpm -Uvh --force --nodeps *.rpm rm -rf minio.rpm minio --version
|
一、部署
下载Minio直接Github搜索即可,minio/minio: Multi-Cloud Object Storage
1.1 单机部署
单机部署命令,指定静态端口9001。
一般会占用两个端口,9000和指定的9001,实际访问是9001。
1 2 3 4 5
| mkdir data
chmod +x minio
MINIO_ROOT_USER=minioadmin MINIO_ROOT_PASSWORD=minioadmin nohup ./minio server data/ --console-address=:9001 >log 2>&1 &
|
建议将启动命令创建成bash脚本,方便执行
我的本机ip是10.0.0.10,所以直接访问10.0.0.10:9000即可,会自动跳转到9001。
1.2 集群部署
集群部署,多台机器使用同一套启动命令即可。
硬性要求:至少4个driver,此处我就理解成分区。
至少4个driver,是由于分布式Minio启用了纠删码算法来保证数据的安全,这个算法保证了,只要不超过N/2块分区坏掉,数据就不会丢失。
部署集群,我可以选用2个节点,每节点2个driver,或者4个节点,每节点1个driver
我采用的方式是后者。
准备4台服务器
1 2 3 4
| 10.0.0.10 10.0.0.11 10.0.0.12 10.0.0.13
|
每台机器执行下面的命令。
1 2 3 4 5 6 7 8 9 10 11
| mkdir /minio
fdisk -l
mount /dev/sda1 /minio
export MINIO_ROOT_USER=xiangwan export MINIO_ROOT_PASSWORD=xiangwan
nohup /root/minio server http://10.0.0.10/minio http://10.0.0.11/minio http://10.0.0.12/minio http://10.0.0.13/minio --console-address=:9001 >log 2>&1 &
|
四台机器都执行后,可通过cat log
查看日志,如下图。
任意访问其中一台即可,我就直接访问10.0.0.10:9000,可以查看节点监控信息
二、使用官方SDK
示例demo是纯maven项目,meethigher/minio-usage: 对象存储minio使用
2.1 基础配置
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>top.meethigher</groupId> <artifactId>minio-usage</artifactId> <version>1.0.0</version>
<properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties>
<dependencies> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>7.1.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> </dependencies> </project>
|
创建配置文件application.properties
1 2 3
| endpoint=http://10.0.0.10:9000 accessKey=xiangwan secretKey=xiangwan
|
创建配置类MinioConfig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package top.meethigher.config;
import java.io.IOException; import java.util.Properties;
public class MinioConfig { public static String endpoint; public static String accessKey; public static String secretKey;
static { Properties prop = new Properties(); try { prop.load(MinioConfig.class.getClassLoader().getResourceAsStream("application.properties")); endpoint=prop.getProperty("endpoint"); accessKey=prop.getProperty("accessKey"); secretKey=prop.getProperty("secretKey"); } catch (IOException e) { e.printStackTrace(); } } }
|
创建MinioClientBuilder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package top.meethigher.utils;
import io.minio.MinioClient; import top.meethigher.config.MinioConfig;
public class MinioClientBuilder {
private static MinioClient minioClient = null;
private MinioClientBuilder() { minioClient = MinioClient.builder() .endpoint(MinioConfig.endpoint) .credentials(MinioConfig.accessKey, MinioConfig.secretKey) .build(); }
private static final class MinioClientBuilderHolder { static final MinioClientBuilder minioClientBuilder = new MinioClientBuilder(); }
public static MinioClient build() { MinioClientBuilder minioClientBuilder = MinioClientBuilderHolder.minioClientBuilder; return minioClientBuilder.getMinioClient(); }
private MinioClient getMinioClient() { return minioClient; } }
|
2.2 api使用
上传功能
1 2 3 4 5 6 7 8 9
| MinioClient minioClient = MinioClientBuilder.build(); UploadObjectArgs args = UploadObjectArgs.builder() .bucket("xiangwan") .object("wuhuang.jpg") .filename("C:\\Users\\14251\\Desktop\\吾皇.png") .build(); minioClient.uploadObject(args);
|
下载功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| MinioClient minioClient = MinioClientBuilder.build(); GetObjectArgs args = GetObjectArgs.builder() .bucket("xiangwan") .object("wuhuang.jpg") .build(); InputStream is = minioClient.getObject(args); FileOutputStream fos = new FileOutputStream("xiangwan.jpg"); int len; byte[] b=new byte[1024]; while((len=is.read(b))!=-1) { fos.write(b,0,len); } fos.close(); is.close();
|
查询功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| MinioClient minioClient = MinioClientBuilder.build(); ListObjectsArgs args= ListObjectsArgs.builder() .bucket("xiangwan") .build(); Iterable<Result<Item>> results = minioClient.listObjects(args); for (Result<Item> next : results) { Item item = next.get(); boolean dir = item.isDir(); if (dir) { System.out.printf("文件名:%s,文件修改时间:0,文件大小:0,文件类型:%s\n", item.objectName(), item.isDir()); } else { System.out.printf("文件名:%s,文件修改时间:%s-%s-%s %s:%s:%s,文件大小:%s,文件类型:%s\n", URLDecoder.decode(item.objectName(), "utf-8"), item.lastModified().getYear(), item.lastModified().getMonthValue(), item.lastModified().getDayOfMonth(), item.lastModified().getHour(), item.lastModified().getMinute(), item.lastModified().getSecond(), item.size(), item.isDir()); } }
|
运行结果如图
删除功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| MinioClient minioClient = MinioClientBuilder.build();
RemoveObjectArgs args= RemoveObjectArgs.builder() .bucket("xiangwan") .object("log") .build(); minioClient.removeObject(args);
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder() .bucket("xiangwan") .prefix("test/") .build()); List<DeleteObject> deleteObjects=new LinkedList<>(); for (Result<Item> result : results) { Item item = result.get(); deleteObjects.add(new DeleteObject(URLDecoder.decode(item.objectName(),"utf-8"))); } RemoveObjectsArgs argss= RemoveObjectsArgs.builder() .bucket("xiangwan") .objects(deleteObjects) .build();
Iterable<Result<DeleteError>> removeObjects = minioClient.removeObjects(argss); for (Result<DeleteError> removeObject : removeObjects) { DeleteError error = removeObject.get(); System.out.printf("minio删除错误->bucketName=%s,objectName=%s,message=%s\n", error.bucketName(), error.objectName(), error.message()); }
|
删除文件夹没有提供直接方式
如有需求就走删除多个对象
三、配置权限
3.1 用户和组
直接创建用户或者组即可,最终用户的权限=用户权限+组权限。
3.2 密钥
具体参照MinIO多用户快速入门指南 | Minio中文文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| { "Version": "2012-10-17", "Statement": [
{ "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListAllMyBuckets", "s3:ListBucket", "s3:PutObject", "s3:DeleteObject", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::*" ] } ] }
|
比如我授权一个token,只能调用删除。只需要添加动作DeleteObject即可。
会发现,只能删除,连查询都做不了。
3.3 通过桶名和文件名访问
配置资源可以通过ip:端口/桶名/资源路径访问单个资源。
就如桶管理,找到Access Rules。
放行所有,都有readOnly权限即可。
通过ip:端口/桶名/资源路径即可访问。
四、参考致谢
MinIO Quickstart Guide| Minio中文文档
Issues · minio/minio
Minio(一) | 搭建Minio服务器(单节点)_Ruby丶彬的博客-CSDN博客_minio单节点
Minio(二) | Minio多用户权限控制_Ruby丶彬的博客-CSDN博客_minio权限控制
Minio(三) | Minio分布式集群搭建_Ruby丶彬的博客-CSDN博客_minio集群搭建
搭建minio分布式测试环境_wdtmn的博客-CSDN博客
文档服务器minio 可通过文件路径进行访问_领风者的博客-CSDN博客_minio 文件访问路径
Minio 批量删除文件失效的问题分析 (Java SDK) - 简书
MinIO关闭公开桶的列表展示_李硕硕的博客-CSDN博客_minio 数据泄露
Linux中挂载到底什么意思!!!为你解答_404~的博客-CSDN博客_linux挂载是什么意思