分布式文件存储系统MinIO笔记
一、MinIO介绍
1、文件系统应用场景
对象存储服务(Object Storage Service,OSS)是一种海量、安全、低成本、高可靠的云存储服
务,适合存放任意类型的文件。容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成
本
互联网海量非结构化数据的存储需求
-
电商网站:海量商品图片
-
视频网站:海量视频文件
-
网盘 : 海量文件
-
社交网站:海量图片
2、MinIO介绍
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。
文档地址
-
官方文档:https://min.io/(推荐,更新快)
-
官方中文文档:http://www.minio.org.cn/
3、MinIO优点
-
部署简单: 一个single二进制文件即是一切,还可支持各种平台
-
minio支持海量存储,可按zone扩展(原zone不受任何影响),支持单个对象最大5TB
-
兼容Amazon S3接口,充分考虑开发人员的需求和体验
-
低冗余且磁盘损坏高容忍,标准且最高的数据冗余系数为2(即存储一个1M的数据对象,实际占用
磁盘空间为2M)。但在任意n/2块disk损坏的情况下依然可以读出数据(n为一个纠删码集合(Erasure
Coding Set)中的disk数量)。并且这种损坏恢复是基于单个对象的,而不是基于整个存储卷的
-
读写性能优异
4、MinIO的基础概念
-
Object:存储到 Minio 的基本对象,如文件、字节流,Anything…
-
Bucket:用来存储 Object 的逻辑空间。每个 Bucket 之间的数据是相互隔离的。对于客户端而
言,就相当于一个存放文件的顶层文件夹。
-
Drive:即存储数据的磁盘,在 MinIO 启动时,以参数的方式传入。Minio 中所有的对象数据都会
存储在 Drive 里。
-
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尽可能分布在不同的节点上
-
5、纠删码EC(Erasure Code)
MinIO 使用纠删码机制来保证高可靠性,使用 highwayhash 来处理数据损坏( Bit Rot Protection )
关于纠删码,简单来说就是可以通过数学计算,把丢失的数据进行还原,它可以将n份原始数据,增加m份数据,并能通过n+m份中的任意n份数据,还原为原始数据。即如果有任意小于等于m份的数据失效,仍然能通过剩下的数据还原出来。
6、存储形式
文件对象上传到 MinIO ,会在对应的数据存储磁盘中,以 Bucket 名称为目录,文件名称为下一级目
录,文件名下是 part.1 和 xl.meta(老版本,最新版本如下图),前者是编码数据块及检验块,后者是元数据文件。
7、存储方案
二、Minio环境搭建
1、介绍
官方文档:https://docs.min.io/docs/
中文文档:http://docs.minio.org.cn/docs/ (没有及时更新,容易被坑)
minio支持多种server启动模式
-
单机模式(无EC码)
-
单机模式(有EC码)
-
集群且有EC码
2、单机部署
2.1 单机部署
minio server的standalone模式,即要管理的磁盘都在host本地。该启动模式一般仅用于实验环境、测试环境的验证和学习使用。在standalone模式下,还可以分为non-erasure code mode和erasure code
-
modenon-erasure code mode
在此启动模式下,对于每一份对象数据,minio直接在data下面存储这份数据,不会建立副本,也不会启用纠删码机制。因此,这种模式无论是服务实例还是磁盘都是“单点”,无任何高可用保障,磁盘损坏就表示数据丢失
-
erasure code mode此模式为minio server实例传入多个本地磁盘参数。一旦遇到多于一个磁盘参数,minio server会自动启用erasure code mode。erasure code对磁盘的个数是有要求的,如不满足要求,实例启动将失败。 erasure code启用后,要求传给minio server的endpoint(standalone模式下,即本地磁盘上的目录)至少为4个
2.2 基于Linux部署
1 | ## 国外资源,龟速下载 |
2.3 基于docker部署(推荐)
1 | docker pull minio/minio |
非root启动,MINIO_ROOT_USER
是新版本的变量定义,MINIO_ACCESS_KEY
是老版本
1 | docker run \ |
3、minio 纠删码模式
Minio 使用纠删码erasure code
和校验和checksum
来保护数据免受硬件故障和无声数据损坏。 即便您丢失一半数量(N/2)的硬盘,您仍然可以恢复数据。
纠删码是一种恢复丢失和损坏数据的数学算法, Minio 采用 Reed-Solomon code 将对象拆分成 N/2 数据和 N/2 奇偶校验块。 这就意味着如果是 12 块盘,一个对象会被分成 6 个数据块、6 个奇偶校验块,你可以丢失任意 6 块盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的盘中的数据进行恢复
使用 Minio Docker 镜像,在 8 块盘中启动 Minio 服务,默认账号密码是minioadmin/minioadmin
1 | docker run -d -p 9000:9000 -p 9001:9001 --name minio \ |
4、分布式集群搭建
4.1 介绍
分布式 Minio 可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式 Minio 避免了单点故障
4.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 一致性模型
4.3 Linux运行分布式 Minio
启动一个分布式 Minio 实例,你只需要把硬盘位置做为参数传给 minio server 命令即可(这里必须要四块及以上硬盘,模拟路径会报错),然后你需要在所有其它节点运行同样的命令。
可以参考官网:https://docs.min.io/docs/distributed-minio-quickstart-guide.html
-
分布式 Minio 里所有的节点需要有同样的 access 秘钥和 secret 秘钥,这样这些节点才能建立联接。为了实现这个,你需要在执行 minio server 命令之前,先将 access 秘钥和 secret 秘钥 export 成环境变量。新版本使用 MINIO_ROOT_USER&MINIO_ROOT_PASSWORD
-
分布式 Minio 使用的磁盘里必须是干净的,里面没有数据
-
分布式 Minio 里的节点时间差不能超过 3 秒,可以使用NTP 来保证时间一致
-
在 Windows 下运行分布式 Minio 处于实验阶段
1 | # 下载minio |
配置为系统服务vim /usr/lib/systemd/system/minio.service
1 | [Unit] |
移动可执行文件以及启动
1 | # 给所有涉及到的文件或目录添加权限 |
最后生产环境需要使用Nginx将集群地址进行代理,对外统一入口,可以参考下面docker的nginx配置
1 | upstream minio{ |
4.4 Docker Compose 部署 MinIO
参考:https://docs.min.io/docs/deploy-minio-on-docker-compose.html
要在 Docker Compose 上部署分布式 MinIO,请下载docker-compose.yaml和nginx.conf到你当前的工作目录
vim docker-compose.yaml
1 | version: '3.7' |
vim nginx.conf
1 | user nginx; |
最后docker-compose pull
和docker-compose up
启动
4.5 扩展现有的分布式集群
例如我们是通过区的方式启动 MinIO 集群,命令行如下
1 | export MINIO_ROOT_USER=admin |
MinIO 支持通过命令,指定新的集群来扩展现有集群(纠删码模式),命令行如下:
1 | export MINIO_ROOT_USER=admin |
现在整个集群就扩展了 1024 个磁盘,总磁盘变为 2048 个,新的对象上传请求会自动分配到最少使用的集群上。通过以上扩展策略,您就可以按需扩展您的集群。重新配置后重启集群,会立即在集群中生效,并对现有集群无影响。如上命令中,我们可以把原来的集群看做一个区,新增集群看做另一个区,新对象按每个区域中的可用空间比例放置在区域中。在每个区域内,基于确定性哈希算法确定位置。
说明: 您添加的每个区域必须具有与原始区域相同的磁盘数量(纠删码集)大小,以便维持相同的数据冗余 SLA。 例如,第一个区有 8 个磁盘,您可以将集群扩展为 16 个、32 个或 1024 个磁盘的区域,您只需确保部署的 SLA 是原始区域的倍数即可。
三、Minio 客户端使用
1、介绍
参考:https://docs.min.io/docs/minio-client-quickstart-guide.html
MinIO Client (mc)为 ls,cat,cp,mirror,diff,find 等 UNIX 命令提供了一种替代方案。它支持文件系统和兼容 Amazon S3 的云存储服务(AWS Signature v2 和 v4)
mc客户端的安装
1 | wget https://dl.min.io/client/mc/release/linux-amd64/mc |
mc全部命令
1 | ls 列出文件和文件夹。 |
2、mc配置与基本操作
mc
将所有的配置信息都存储在~/.mc/config.json
文件中
1 | # 查询mc host配置 |
3、mc admin 使用
3.1 基本介绍
minIO Client(mc)提供了“ admin”子命令来对您的 MinIO 部署执行管理任务
1 | service 服务重启并停止所有MinIO服务器 |
3.2 用户管理
1 | mc admin user --help |
3.3 策略管理
policy 命令,用于添加,删除,列出策略,获取有关策略的信息并为 MinIO 服务器上的用户设置策略(创建用户之后还不能进行登录,必须绑定对应的策略)
1 | mc admin policy --help |
3.4 添加用户权限自定义策略
AWS Identity and Access Management (IAM) 是一种 Web 服务,可以帮助您安全地控制对 AWS 资源的访问。您可以使用 IAM 控制对哪个用户进行身份验证 (登录) 和授权 (具有权限) 以使用资源。
权限 | 解释 |
---|---|
consoleAdmin | 控制台管理员 |
diagnostics | 诊断 |
readonly | 只读 |
readwrite | 读写 |
writeonly | 只写 |
编写自己的自定义策略vim mytest.json
,这里只能操作test桶,做到了资源隔离
1 | { |
参数 | 说明 |
---|---|
Version | 标识策略的版本号,Minio中一般为"2012-10-17" |
Statement | 策略授权语句,描述策略的详细信息,包含Effect(效果)、Action(动作)、Principal(用户)、Resource(资源)和Condition(条件)。其中Condition为可选 |
Effect | Effect(效果)作用包含两种:Allow(允许)和Deny(拒绝),系统预置策略仅包含允许的授权语句,自定义策略中可以同时包含允许和拒绝的授权语句,当策略中既有允许又有拒绝的授权语句时,遵循Deny优先的原则 |
Action | Action(动作)对资源的具体操作权限,格式为:服务名:资源类型:操作,支持单个或多个操作权限,支持通配符号*,通配符号表示所有。例如 s3:GetObject ,表示获取对象 |
Resource | Resource(资源)策略所作用的资源,支持通配符号*,通配符号表示所有。在JSON视图中,不带Resource表示对所有资源生效。Resource支持以下字符:-_0-9a-zA-Z*./\,如果Resource中包含不支持的字符,请采用通配符号*。例如:arn:aws:s3:::my-bucketname/myobject*\,表示minio中my-bucketname/myobject目录下所有对象文件 |
Condition | Condition(条件)您可以在创建自定义策略时,通过Condition元素来控制策略何时生效。Condition包括条件键和运算符,条件键表示策略语句的Condition元素,分为全局级条件键和服务级条件键。全局级条件键(前缀为g:)适用于所有操作,服务级条件键(前缀为服务缩写,如obs:)仅适用于对应服务的操作。运算符与条件键一起使用,构成完整的条件判断语句 |
最后把权限给与用户,发现该用户只能操作对应的桶,实现权限分离。同时在Web界面也可以快速编辑授权用户
1 | # 添加新的策略 |
4、桶策略(匿名访问策略)
4.1 桶策略简介
桶策略和IAM用户权限不同,用户权限管理的是用户的登录/可读/可写等操作,桶策略管理的是匿名用户的访问与上传,也可以自定义操作。
参考文章:Minio 小技巧 | 通过编码设置桶策略,实现永久访问和下载
mc的命令行客户端,在mc种对桶策略设置对应分别是 none, download, upload, public
,与minio的匿名访问策略一一对应:
-
download
(read only )允许未经认证的访问 -
upload
(write only)允许未经认证的上传 -
public
(read+write)允许读写 -
none
(none) 默认值,必须经过认证
1 | #更改桶权限为public(简单操作,对桶进行全局操作,无论桶中文件名前缀是什么),也可以对其中一个路径 |
4.2 自定义桶策略
-
Version:版本
-
Actions– 对于每个资源,Amazon S3 支持一组操作。您可以使用操作关键字标识将允许(或拒绝)的资源操作
-
Principal :被允许访问语句中的操作和资源的帐户或用户。在存储桶策略中,委托人是作为此权限接收者的用户、账户、服务或其他实体
-
Condition– 政策生效的条件。您可以使用
AWS
范围的密钥和Amazon S3
特定的密钥来指定Amazon S3
访问策略中的条件 -
Resource– 存储桶、对象、访问点和作业是您可以允许或拒绝权限的 Amazon S3 资源。在策略中,您使用 Amazon 资源名称 (ARN) 来标识资源
-
Effect:对于每个资源,Amazon S3 支持一组操作。您可以使用操作关键字标识将允许(或拒绝)的资源操作
如:该
s3:ListBucket
权限允许用户使用 Amazon S3 GET Bucket (List Objects)操作
下面是自定义的桶策略,支持可读可写,完成后赋予相应的桶即可,mc policy set-json /path/to/policy.json minio-server/test/images
1 | { |
4.3 集成SpringBoot,编码设置桶策略
第一种是json转string
1 | public class PolicyJsonUtils { |
运行,当然在管理后台也可以设置
1 | public class PolicyService { |
5、其他桶操作API
其他桶策略可以参考:JAVA集成Minio之存储桶操作API使用详解
官方参考文档:https://docs.min.io/docs/java-client-api-reference.html
-
桶是否存在
-
桶创建
-
查询存储桶信息列表
-
删除存储桶
-
加密桶
-
桶生命周期设置
-
桶的通知配置
-
桶的策略配置
-
桶的复制配置
-
存储桶标签
-
桶的多版本设置
-
桶的常用配置删除
四、Java整合Minio使用
1、Minio Java Client 使用
MinIO Java Client SDK 提供简单的 API 来访问任何与 Amazon S3 兼容的对象存储服务。
官方 demo: https://github.com/minio/minio-java
官方文档:https://docs.min.io/docs/java-client-api-reference.html
博客参考:https://blog.csdn.net/lemon_TT/article/details/124675675
其他Minio对象操作可以参考:JAVA集成Minio之对象操作API使用详解
引入依赖
1 | <dependency> |
文件上传
1 | public class FileUploader { |
文件下载
1 | public class DownLoadDemo { |
2、Spring boot 整合 minio
构建 MinioClient 对象,并交给 spring 管理
1 |
|
实现文件上传,下载,删除操作
1 |
|
3、其他对象操作API使用详解
官方文档:https://docs.min.io/docs/java-client-api-reference.html
上传对象
-
PutObject
-
uploadObject
获取对象
-
getObject
-
downloadObject
-
getPresignedObjectUrl
-
selectObjectContent
-
getPresignedPostFormData
复制对象
删除对象
对象信息查询及设置
参考文章