Minio 是个基于 Golang 编写的开源对象存储套件,基于Apache License v2.0开源协议,虽然轻量,却拥有着不错的性能。它兼容亚马逊S3云存储服务接口。可以很简单的和其他应用结合使用,例如 NodeJS、Redis、MySQL等。
对象存储是用于存储非结构化数据的数据存储架构,它将一个数据单元称为一个对象,每个对象都包含数据本身、元数据(描述数据的信息)和一个唯一标识符(通常是一个URL地址)。
在2001年,亚马逊推出了Simple Storage Service(简称S3),这是第一个商业化的、面向互联网的对象存储服务。随后国内众多云服务厂商也都推出了自己的对象存储服务,例如阿里云的OSS,华为云的OBS,百度云的BOS等等。
MinIO是一个开源的对象存储方案,兼容亚马逊S3协议。
对于对象存储,我们可以选择直接购买各大云厂商提供的服务,也可以选择使用开源的服务,自行安装和维护。本项目采用开源的对象存储Minio来存储图片信息。
对象(Object)
对象是实际的数据单元,例如我们上传的一个图片。
存储桶(Bucket)
存储桶是用于组织对象的命名空间,类似于文件夹。每个存储桶可以包含多个对象。
端点(Endpoint)
端点是MinIO服务器的网络地址,用于访问存储桶和对象,例如http://192.168.10.101:9000
注意:9000
为MinIO的API的默认端口
Access Key 和 Secret Key
Access Key是用于标识和验证访问者身份的唯一标识符,相当于用户名。
Secret Key是与Access Key关联的密码,用于验证访问者的身份。
获取MinIO安装包
下载地址如下:https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20230809233022.0.0.x86_64.rpm,通过以下命令可直接将安装包下载至服务器
wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20230809233022.0.0.x86_64.rpm
注:由于服务器在国外,所以下载会比较慢,可以直接使用在网上找对应资源
安装MinIO
rpm -ivh minio-20230809233022.0.0.x86_64.rpm
集成Systemd
Systemd概述
Systemd
是一个广泛应用于Linux系统的系统初始化和服务管理器,其可以管理系统中的各种服务和进程,包括启动、停止和重启服务,除此之外,其还可以监测各服务的运行状态,并在服务异常退出时,自动拉起服务,以保证服务的稳定性。系统自带的防火墙服务firewalld
,我们自己安装的mysqld
和redis
均是由Systemd
进行管理的,此处将MinIO服务也交给Systemd管理。
编写MinIO服务配置文件
Systemd所管理的服务需要由一个配置文件进行描述,这些配置文件均位于/etc/systemd/system/
或者/usr/lib/systemd/system/
目录下,下面创建MinIO服务的配置文件。
执行以下命令创建并打开minio.service
文件
vim /etc/systemd/system/minio.service
内容如下,具体可参考MinIO官方文档。
[Unit]
Description=MinIO
Documentation=https://min.io/docs/minio/linux/index.html
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
WorkingDirectory=/usr/local
ProtectProc=invisible
EnvironmentFile=-/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
LimitNOFILE=65536
TasksMax=infinity
TimeoutStopSec=infinity
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
注意:
重点关注上述文件中的以下内容即可
EnvironmentFile
,该文件中可配置MinIO服务所需的各项参数ExecStart
,该参数用于配置MinIO服务的启动命令,其中$MINIO_OPTS
、$MINIO_VOLUMES
,均引用于EnvironmentFile
中的变量。
MINIO_OPTS
用于配置MinIO服务的启动选项,可省略不配置。MINIO_VOLUMES
用于配置MinIO服务的数据存储路径。Restart
,表示自动重启编写EnvironmentFile
文件
执行以下命令创建并打开/etc/default/minio
文件
vim /etc/default/minio
内容如下,具体可参考官方文档。
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
MINIO_VOLUMES=/data
MINIO_OPTS="--console-address :9001"
注意
MINIO_ROOT_USER
和MINIO_ROOT_PASSWORD
为用于访问MinIO的用户名和密码,密码长度至少8位。
MINIO_VOLUMES
用于指定数据存储路径,需确保指定的路径是存在的,可执行以下命令创建该路径。
mkdir /data
MINIO_OPTS
中的console-address
,用于指定管理页面的地址。
启动MinIO
执行以下命令启动MinIO
systemctl start minio
执行以下命令查询运行状态
systemctl status minio
设置MinIO开机自启
systemctl enable minio
访问MinIO管理页面
管理页面的访问地址为:http://192.168.10.101:9001
注意:ip需要根据实际情况做出修改
登录
管理页面的地址为http://主机ip地址:9001,登录的用户名和密码为部署时在EnvironmentFile
文件中配置的如下参数
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
创建存储桶
设置访问权限
如上图所示,可选的访问权限共有三个选项,分别是Private
、Public
和Custom
,具体说明如下
Private
只允许桶的所有者对该桶进行读写。
Public
允许所有人对该桶进行读写。
Custom
自定义访问权限。
若想将权限设置为只允许所有者写,但允许所有人读,就需要自定义访问权限。自定义访问权限,需要使用一个规定格式的JSON字符串进行描述,具体格式可参考官方文档。
例如以下JSON字符串表达的含义是:允许(Allow
)所有人(*
)读取(s3:GetObject
)指定桶(test
)的所有内容。
{
"Statement" : [ {
"Action" : "s3:GetObject",
"Effect" : "Allow",
"Principal" : "*",
"Resource" : "arn:aws:s3:::test/*"
} ],
"Version" : "2012-10-17"
}
上传图片
访问图片
由于MinIO提供了HTTP访问功能,所以可以通过浏览器直接访问对象。对象URL为MinIO的Endpoint
+对象的存储路径
,例如下图中的图片对象的URL为http://192.168.204.141:9000/test/image-20240531192616741.png。
MinIO提供了多种语言的SDK供开发者使用下面通过一个简单案例熟悉一下其基本用法,具体内容可参考官方文档。
添加依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.3</version>
</dependency>
编写代码进行上传
public class test {
public static void main(String[] args) {
//获取minio客户端
String endpoint = "http://192.168.204.141:9000";
String accessKey = "minioadmin";
String secretKey = "minioadmin";
String bucketName = "hello-minio";
MinioClient minioClient = MinioClient.builder().endpoint(endpoint)
.credentials(accessKey, secretKey).build();
//创建bucket
try {
//判断bucket名字是否存在
boolean exists = minioClient.bucketExists(BucketExistsArgs.builder()
.bucket(bucketName).build());
//如果不存在则创建
if (!exists){
minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName).build());
//设置bucket访问权限
String policy = "{"
+ "\"Statement\": [ {"
+ "\"Action\": \"s3:GetObject\","
+ "\"Effect\": \"Allow\","
+ "\"Principal\": \"*\","
+ "\"Resource\": \"arn:aws:s3:::"+bucketName+"/*\""
+ "} ],"
+ "\"Version\": \"2012-10-17\""
+ "}";
minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
.bucket(bucketName).config(policy).build());
}
//上传文件
minioClient.uploadObject(UploadObjectArgs.builder()
.filename("D:\\file\\笔记\\1.png").bucket(bucketName)
.object("1.png").build());
System.out.println("上传成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行测试