1 概述
1.1 介绍
Minio
是个基于Golang
编写的开源对象存储套件,基于Apache License v2.0开源协议,虽然轻量,却拥有着不错的性能。它兼容亚马逊S3云存储服务接口。可以很简单的和其他应用结合使用,例如 NodeJS、Redis、MySQL
等。
官网:
英文官网:https://min.io/
中文官网:http://www.minio.org.cn/
1.2 应用场景
MinIO 的应用场景除了可以作为私有云的对象存储服务来使用,也可以作为云对象存储的网关层,无缝对接 Amazon S3 或者 MicroSoft Azure 。
1.3 特点
- 高性能:作为一款高性能存储,在标准硬件条件下,其读写速率分别可以达到55Gb/s 和35Gb/s。并且MinIO 支持一个对象文件可以是任意大小,从几kb到最大5T不等。
- 可扩展:不同MinIO集群可以组成联邦,并形成一个全局的命名空间,并且支持跨越多个数据中心。
- 云原生:容器化、基于K8S的编排、多租户支持。
- Amazon S3兼容:使用 Amazon S3 v2 / v4 API。可以使用Minio SDK,Minio Client,AWS SDK 和 AWS CLI 访问Minio服务器。
- SDK支持:
- GO SDK:https://github.com/minio/minio-go
- JavaSDK:https://github.com/minio/minio-java
- PythonSDK:https://github.com/minio/minio-py
- 图形化界面:有操作页面
- 支持纠删码:MinIO使用纠删码、Checksum来防止硬件错误和静默数据污染。在最高冗余度配置下,即使丢失1/2的磁盘也能恢复数据。
2. 使用
2.1 部署方式
2.1.1 单机部署
minio server
的standalone
模式,即要管理的磁盘都在host本地,该启动模式一般仅用于实验环境、测试环境的验证和学习使用。在standalone模式下,还可以分为non-erasure code mode
和erasure code mode
。
- non-erasure code mode
在此启动模式下,对于每一份对象数据,minio直接在data下面存储这份数据,不会建立副本,也不会启用纠删码机制。因此,这种模式无论是服务实例还是磁盘都是"单点”,无任何高可用保障,磁盘损坏就表示数据丢失。 - erasure code mode
此模式为minio server
实例传入多个本地磁盘参数。一旦遇到多于一个磁盘参数,minio server会自动启用erasure code mode
。该对磁盘的个数是有要求的,如不满足要求,实例启动将失败。erasure code
启用后,要求传给minio server
的endpoint
(standalone
模式下,即本地磁盘上的目录)至少为4个 。
2.1.2 分部署集群部署
分布式Minio可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式Minio避免了单点故障。
2.1.2.1 分布式存储可靠性常用方法
分布式存储,很关键的点在于数据的可靠性,即保证数据的完整,不丢失,不损坏。只有在可靠性实现的前提下,才有了追求一致性、高可用、高性能的基础。而对于在存储领域,一般对于保证数据可靠性的方法主要有两类,一类是冗余法
,一类是校验法
。
- 冗余
冗余法最简单直接,即对存储的数据进行副本备份,当数据出现丢失,损坏,即可使用备份内容进行恢复,而副本 备份的多少,决定了数据可靠性的高低。这其中会有成本的考量,副本数据越多,数据越可靠,但需要的设备就越多,成本就越高。可靠性是允许丢失其中一份数据。当前已有很多分布式系统是采用此种方式实现,如 Hadoop 的文件系统(3个副本),Redis 的集群,MySQL 的主备模式等。 - 校验
校验法即通过校验码的数学计算的方式,对出现丢失、损坏的数据进行校验、还原。注意,这里有两个作用,一个校验,通过对数据进行校验和(cheksum 进行计算,可以检查数据是否完整,有无损坏或更改,在数据传输和保存时经常用到,如 TCP 协议,二是恢复还原.通过对数据结合校验码,通过数学计算,还原丢失或损坏的数据,可以在保证数据可的前提下,降低几余,如单机硬盘存储中的 RAID技术,纠删码 (Erasure Code) 技术等。Minio 采用的就是纠删码技术。
2.1.2.2 分布式MinIO的优势
- 数据保护
分布式Minio采用纠删码来防范多个节点宕机和位衰减bit rot
分布式Minio至少需要4个硬盘,使用分布式Minio自动引入了纠删码功能。 - 高可用
单机Minio服务存在单点故障,相反,如果是一个有N块硬盘的分布式Minio,只要有N/2硬盘在线,你的数据就是安全的。不过你需要至少有N/2+1个硬盘来创建新的对象。
例如,一个16节点的Minio集群,每个节点16块硬盘,就算8台服务器宕机,这个集群仍然是可读的,不过你需要9台服移器才能写数据 - 一致性
Minio在分布式和单机模式下,所有读写操作都严格遵守read-after-write一致性模型。
2.1.2.3 分布式Minio注意事项
- 启动一个分布式Minio实例,你只需要把硬盘位置做为参数传给minio server命令即可,然后,你需要在所有其它节点运行同样的命令。
- 分布式Minio里所有的节点需要有同样的
access
秘钥和secret
秘钥,这样这些节点才能建立联接。为了实现这个,你需要在执行minio server
命令之前,先将access
秘钥和secret
秘钥export成环境变量
。新版本使用MINIO_ROOT_USER
和MINIO_ROOT_PASSWORD
。 - 分布式Minio使用的磁盘里必须是干净的,里面没有数据。
- 分布式Minio里的节点时间差不能超过3秒,你可以使用NTP 来保证时间一致。
- 在Windows下运行分布式Minio处于实验阶段,不建议使用。
2.2 部署
2.2.1 单机部署
基于docker
- 获取镜像
docker pull minio/minio
- 启动镜像
# docker 挂载的目录
mkdir /mnt/dockerData
docker run \
-p 9000:9000 \
-p 9090:9090 \
--name minio \
-v /mnt/dockerData:/data \
-e "MINIO_ROOT_USER=ROOTNAME" \
-e "MINIO_ROOT_PASSWORD=ROOTNAME" \
quay.io/minio/minio server /data --console-address ":9090"
基于centos
# 获取minio
wget -q http://dl.minio.org.cn/server/minio/release/linux-amd64/minio
# 授予文件权限
chmod +x minio
# 启动minio server服务,指定数据存储目录/mnt/data,最好是指定控制台端口,我使用的这个版本是去访问9000端口,它会自己跳转到控制台端口(比如34292),这个跳转的端口是随机的,不方便后面nginx做转发,我刚开始是懒得做控制台端口映射,到后面吃亏了。
./minio server /mnt/data --console-address :9090
默认账号密码:minioadmin
分块文件BLOCK
在minio中,如果你的文件小于10M的话,那么就按照文件分块,如果大于10M的话,那么就是按照10M进行分块。
使用Minio Docker镜像,在8块盘中中启动MinIO服务:
docker run \
-p 9000:9000 \
-p 9090:9090 \
--name minio \
-v /mnt/data1:/data1 \
-v /mnt/data2:/data2 \
-v /mnt/data3:/data3 \
-v /mnt/data4:/data4 \
-v /mnt/data5:/data5 \
-v /mnt/data6:/data6 \
-v /mnt/data7:/data7 \
-v /mnt/data8:/data8 \
-e "MINIO_ROOT_USER=ROOTNAME" \
-e "MINIO_ROOT_PASSWORD=ROOTNAME" \
quay.io/minio/minio server /data{1...8} --console-address ":9090"
启动后,文件将会被分别存储在八块不同的磁盘里。
2.2.2 集群部署(基于centos)
- 8个节点,每节点1块盘
启动分布式Minio实例,8个节点,每节点1块盘,需要在8个节点上都运行下面的命令:
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
minio server \
http://192.68.0.1/export1 \
http://192.68.0.2/export1 \
http://192.68.0.3/export1 \
http://192.68.0.4/export1 \
http://192.68.0.5/export1 \
http://192.68.0.6/export1 \
http://192.68.0.7/export1 \
http://192.68.0.8/export1 \
--console-address ":9090"
-
4 节点,每节点4个盘
启动分布式MinIO示例,4节点,每个节点4块盘,需要在4个节点下都运行下面的命令;
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
minio server \
http://192.68.0.1/export1 \
http://192.68.0.1/export2 \
http://192.68.0.1/export3 \
http://192.68.0.1/export4 \
http://192.68.0.2/export1 \
http://192.68.0.2/export2 \
http://192.68.0.2/export3 \
http://192.68.0.2/export4 \
http://192.68.0.3/export1 \
http://192.68.0.3/export2 \
http://192.68.0.3/export3 \
http://192.68.0.3/export4 \
http://192.68.0.4/export1 \
http://192.68.0.4/export2 \
http://192.68.0.4/export3 \
http://192.68.0.4/export4 \
--console-address ":9090"
- 停止minio
pid=`ps -ef | grep minio | grep server | awk '{print $2}'` && kill -9 $pid
2.3 图形界面操作
安装成功后直接访问地址:http:/ip:9000/login,并使用用户名和密码登陆后如下:
创建一个Buckets
MinIO到此已经安装设置成功了。
3. Spring Boot整合MinIO
虽然MinIO在图形界面提供了手动上传的操作,但是也可以通过SDK的方式去上传,下面介绍一下Spring Boot 整合MinIO上传文件。
3.1 添加依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
3.2 获取accessKey和secretKey
这里的accessKey
和secretKey
并不是图形界面登录名和密码,获取很简单,直接在图形界面中操作,如下图:
3.3 yaml配置
minio:
# 访问的url
endpoint: http://xxx.xxx.xxx.xxx
# API的端口
port: 9001
# 秘钥
accessKey: xxxxxxxxx
secretKey: xxxxxxxxxxxxxxxxxxxxxx
secure: false
bucket-name: test # 桶名
image-size: 10485760 # 图片文件的最大大小
file-size: 1073741824 # 文件的最大大小
3.4 新建上传文件接口
@RequestMapping("/minio")
@RestController
public class MinioController {
@Autowired
private MinioService minioService;
@PostMapping("/upload")
public String uploadFile(MultipartFile file, String bucketName) {
String fileType = FileTypeUtils.getFileType(file);
if (fileType != null) {
return minioService.putObject(file, bucketName, fileType);
}
return "不支持的文件格式。请确认格式,重新上传!!!";
}
}