MinIO介绍部署与springboot集成
进入新的项目团队,在文件存储方面使用minio工具,因此网上查找相关资料以及结合项目对minio使用情况,学习minio相关知识、特性、应用场景、存储架构以及基础概念,并在此基础上,本地实际部署搭建minio服务,并集成进springboot项目进行使用,于此进行记录,以便后续深入学习,同时也为后来者提供参考借鉴,文中不免疏漏之处,望读者给予指正!
1. MinIO基本信息
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从数KB到最大5TB都能很好的支持。开源并且用Go语言开发,有web操作界面,我们可以用它来搭建兼容S3协议的存储云服务。相比 hadoop hdfs 分布式存储服务轻量很多,且支持单节点部署。
对象存储:
对象存储服务OSS(Object Storage Service)是一种海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件。容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本。
2. MinIO特性
1)高性能
MinIO 是全球领先的对象存储先锋,目前在全世界有数百万的用户. 在标准硬件上,读/写速度上高达183 GB / 秒 和 171 GB / 秒。
对象存储可以充当主存储层,以处理Spark、Presto、TensorFlow、H2O.ai等各种复杂工作负载以及成为Hadoop HDFS的替代品。
MinIO用作云原生应用程序的主要存储,与传统对象存储相比,云原生应用程序需要更高的吞吐量和更低的延迟。而这些都是MinIO能够达成的性能指标。
2)可扩展性
MinIO利用了Web缩放器的来之不易的知识,为对象存储带来了简单的缩放模型。 这是我们坚定的理念 “简单可扩展.” 在 MinIO, 扩展从单个群集开始,该群集可以与其他MinIO群集联合以创建全局名称空间, 并在需要时可以跨越多个不同的数据中心。 通过添加更多集群可以扩展名称空间, 更多机架,直到实现目标。
3)云的原生支持
MinIO 是在过去4年的时间内从0开始打造的一款软件 ,符合一切原生云计算的架构和构建过程,并且包含最新的云计算的全新的技术和概念。 其中包括支持Kubernetes 、微服和多租户的的容器技术。使对象存储对于 Kubernetes更加友好。
4)与Amazon S3 兼容
亚马逊云的 S3 API(接口协议) 是在全球范围内达到共识的对象存储的协议,是全世界内大家都认可的标准。 MinIO 在很早的时候就采用了 S3 兼容协议,并且MinIO 是第一个支持 S3 Select 的产品. MinIO对其兼容性的全面性感到自豪, 并且得到了 750多个组织的认同, 包括Microsoft Azure使用MinIO的S3网关 - 这一指标超过其他同类产品的总和。
5)简单
极简主义是MinIO的指导性设计原则。简单性减少了出错的机会,提高了正常运行时间,提供了可靠性,同时简单性又是性能的基础。 只需下载一个二进制文件然后执行,即可在几分钟内安装和配置MinIO。 配置选项和变体的数量保持在最低限度,这样让失败的配置概率降低到接近于0的水平。 MinIO升级是通过一个简单命令完成的,这个命令可以无中断的完成MinIO的升级,并且不需要停机即可完成升级操作 - 降低总使用和运维成本。
3. 应用场景
MinIO 的应用场景除了可以作为私有云的对象存储服务来使用,也可以作为云对象存储的网关层,无缝对接 Amazon S3 或者 MicroSoft Azure 。
4. 存储架构
Minio针对不同应用场景也设置了对应的存储架构:
4.1 单主机,单硬盘模式
该模式下,Minio只在一台服务器上搭建服务,且数据都存在单块磁盘上,该模式存在单点风险,主要用作开发、测试等使用
启动的命令为:
minio --config-dir ~/tenant1 server --address :9001 /disk1/data/tenant1
4.2 单主机,多硬盘模式
该模式下,Minio在一台服务器上搭建服务,但数据分散在多块(大于4块)磁盘上,提供了数据上的安全保障
minio --config-dir ~/tenant1 server --address :9001 /disk1/data/tenant1 /disk2/data/tena
4.3 多主机、多硬盘模式(分布式)
该模式是Minio服务最常用的架构,通过共享一个access_key和secret_key,在多台(2-32)服务器上搭建服务,且数据分散在多块(大于4块,无上限)磁盘上,提供了较为强大的数据冗余机制(Reed-Solomon纠删码)。
export MINIO_ACCESS_KEY=<TENANT1_ACCESS_KEY>
export MINIO_SECRET_KEY=<TENANT1_SECRET_KEY>
minio --config-dir ~/tenant1 server --address :9001 http://192.168.10.11/data/tenant1 ht
分布式优点:
在大数据领域,通常的设计理念都是无中心和分布式。Minio分布式模式可以帮助搭建一个高可用的对象存储服务,你可以使用这些存储设备,而不用考虑其真实物理位置。
1)数据保护
分布式Minio采用 纠删码来防范多个节点宕机和位衰减bit rot。
分布式Minio至少需要4个硬盘,使用分布式Minio自动引入了纠删码功能。
2)高可用
单机Minio服务存在单点故障,相反,如果是一个有N块硬盘的分布式Minio, 只要有N/2硬盘在线,你的数据就是安全的。
不过你需要至少有N/2+1个硬盘来创建新的对象。
例如,一个16节点的Minio集群,每个节点16块硬盘,就算8台服務器宕机,这个集群仍然是可读的,不过你需要9台服務器才能写数据。
注意,只要遵守分布式Minio的限制,你可以组合不同的节点和每个节点几块硬盘。
比如,你可以使用2个节点,每个节点4块硬盘,也可以使用4个节点,每个节点两块硬盘,诸如此类。
3)一致性
Minio在分布式和单机模式下,所有读写操作都严格遵守read-after-write一致性模型。
4)MinIO的数据高可靠
Minio使用了Erasure Code 纠删码和 Bit Rot Protection 数据腐化保护这两个特性,所以MinIO的数据可靠性做的高。
5. 基础概念
1)Object:存储到 Minio 的基本对象,如文件、字节流,Anything…
2)Bucket:用来存储 Object 的逻辑空间。每个 Bucket 之间的数据是相互隔离的。对于客户端而言,就相当于一个存放文件的顶层文件夹。
3)Drive:即存储数据的磁盘,在 MinIO 启动时,以参数的方式传入。Minio 中所有的对象数据都会存储在 Drive 里。
4)Set
即一组 Drive 的集合,分布式部署根据集群规模自动划分一个或多个 Set ,每个 Set 中的 Drive 分布在不同位置。一个对象存储在一个 Set 上。(For example: {1…64} is divided into 4 sets each of size 16.)
一个对象存储在一个Set上
一个集群划分为多个Set
一个Set包含的Drive数量是固定的,默认由系统根据集群规模自动计算得出
一个SET中的Drive尽可能分布在不同的节点上
Set /Drive 的关系:
Set /Drive 这两个概念是 MINIO 里面最重要的两个概念,一个对象最终是存储在 Set 上面的。
一个节点机器可以包含多个硬盘,Drive为节点里的一块可以简单理解为一个硬盘,Set是一组跨节点的多个Drive 的集合.
5)Minio写入对象过程:
MINIO 是通过数据编码,将原来的数据编码成 N 份,N 就是一个 Set 上面 Drive 的数量,后面多次提到的 N 都是指这个意思。
对象被编码成N份之后,把每一份,写到对应的 Drive 上面,这就是把一个对象存储在整个 Set 上。
一个集群包含多个 Set,每个对象最终存储在哪个 Set 上是根据对象的名称进行哈希,然后影射到唯一的 Set 上面,这个方式从理论上保证数据可以均匀的分布到所有的 Set 上。
根据的观测,数据分布的也非常均匀,一个 Set 上包含多少个 Drive 是由系统自动根据集群规模算出来的,当然,也可以自己去配置。
一个 Set 的 Drive 系统会考虑尽可能把它放在多的节点上面,保证它的可靠性。
6. 部署
MinIO支持单机部署、多租户部署、分布式部署。支持原始文件存储已经纠删码模式存储。单机部署时,可使用minio的客户端工具进行备份。
6.1 二进制方式部署
部署环境:Ubuntu 20.04.2 LTS
系统架构:amd64(uname -a或arch命令可查看系统架构,注:x86_64,x64,AMD64基本上是同一个东西)
使用以下命令在运行 64 位 Intel/AMD 架构的 Linux 主机上运行独立的 MinIO 服务器。将/data 替换为您希望 MinIO 存储数据的驱动器或目录的路径。
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
./minio server /data
64-bit Intel/AMD、64-bit ARM、64-bit PowerPC LE (ppc64le)、IBM Z-Series (S390X)不同架构对应的安装包在https://dl.min.io/server/minio/release/下自行查找
参数–console-address “:9001” 可指定浏览器访问端口
6.2 Docker方式部署
1)拉取镜像
docker pull minio/minio
2)运行镜像MinIO:
docker run -p 9000:9000 -p 9001:9001 --name minio \
-v /etc/localtime:/etc/localtime \
-v /data/minio/data:/data \
-v /data/minio/config:/root/.minio \
-d minio/minio server /data --console-address ":9001"
6.3 控制台访问设置
浏览器访问 http://192.168.109.130:44561/ 账户密码 minioadmin/minioadmin
1)创建桶:进入系统后,我们先要点击右下角的“+”按钮,创建一个文件桶(输入名称后,回车即可),在上传文件到这个文件桶中。Create bucket(创建文件桶)、Upload file(上传文件),这里我创建了一个桶test,上传了一张图片
2)上传的文件,在文件列表界面有一个分享按钮,点击分享将生成文件的访问URL地址,以指定链接的有效时间,有效时间最多7天,最小的单位是分钟。在有效时间过期后在访问图片时,会提示失效。
3)bucket访问策略
桶默认可以有三种Access Policy策略:public、custom、private
策略public:不经过任何认证可以直接访问资源
策略private:未经授权不能进行任何操作
策略customer:通过如下自定义Access Rules出现的,readonley/writeonly/readwrite
增加customer后 Access Policy自动设置为customer,customer全都删除后,Access Policy自动设置为private;
7. Springboot集成使用
7.1 引入jar包
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.0.2</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.6</version>
</dependency>
7.2 增加配置
platform:
oss:
endpoint: http://192.168.109.130:9000
accessKeyId: minioadmin
accessKeySecret: minioadmin
bucketName: tduck-cloud
domain: http://192.168.109.130:9000/tduck-cloud
7.3 代码集成
@Data
@Component
@Slf4j
@ConfigurationProperties(prefix = "platform.oss")
public class OssStorageConfig {
/**
* oss 类型
* 参考 OssTypeEnum.java
*/
private OssTypeEnum ossType;
/**
* 阿里云:endpoint
*/
private String endpoint;
/**
* accessKeyId
*/
private String accessKeyId;
/**
* accessKeySecret
*/
private String accessKeySecret;
/**
* 桶名
*/
private String bucketName;
/**
* 预览域名
*/
private String domain;
/**
* 本地存储文件存放地址
*/
private String uploadFolder;
/**
* 本地存储文件访问路径
*/
private String accessPathPattern;
}
@Component
public class MIniOStorageService {
private MinioClient client;
public MIniOStorageService(OssStorageConfig config) {
this.config = config;
//初始化
init();
}
private void init() {
try {
client = new MinioClient(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret(), false);
} catch (InvalidEndpointException e) {
e.printStackTrace();
} catch (InvalidPortException e) {
e.printStackTrace();
}
}
@Override
public String upload(InputStream inputStream, String path) {
try {
PutObjectOptions poo = new PutObjectOptions(inputStream.available(), -1);
poo.setContentType(MimeTypeEnum.getContentType(path));
client.putObject(config.getBucketName(), path, inputStream, poo);
} catch (Exception e) {
throw new StorageException("上传文件失败,请检查配置信息", e);
}
return config.getDomain() + "/" + path;
}
@Override
public String upload(byte[] data, String path) {
try {
PutObjectOptions poo = new PutObjectOptions(data.length, -1);
poo.setContentType(MimeTypeEnum.getContentType(path));
client.putObject(config.getBucketName(), path, new ByteArrayInputStream(data), poo);
} catch (Exception e) {
throw new StorageException("上传文件失败,请检查配置信息", e);
}
return config.getDomain() + "/" + path;
}
@Override
public void delete(String path) {
try {
client.removeObject(config.getBucketName(), path);
} catch (Exception e) {
throw new StorageException("删除文件失败", e);
}
}
}
@Autowired
private MIniOStorageService mIniOStorageService;
/**
* 上传用户文件
* <p>
* 用户Id MD5加密 同一个用户的文件放在一个目录下
*
* @param file
* @param userId
* @return
* @throws IOException
*/
@PostMapping("/user/file/upload")
public Result<String> uploadUserFile(@RequestParam("file") MultipartFile file, @RequestAttribute Long userId) throws IOException {
String path = new StringBuffer(SecureUtil.md5(String.valueOf(userId)))
.append(CharUtil.SLASH)
.append(IdUtil.simpleUUID())
.append(CharUtil.DOT)
.append(FileUtil.extName(file.getOriginalFilename())).toString();
String url = mIniOStorageService.upload(file.getInputStream(),path);
return Result.success(url);
}
8. 参考资料
http://www.minio.org.cn/
http://docs.minio.org.cn/docs/
https://blog.youkuaiyun.com/lj15559275886/article/details/121441031
https://blog.youkuaiyun.com/crazymakercircle/article/details/120855464