分布式文件存储系统MinIO实战
这份笔记是摘抄B站视频图灵课堂出品的Minio视频,视频链接如下
【MinIO很强-让我放弃FastDFS拥抱MinIO的8大理由】https://www.bilibili.com/video/BV1AY411N7te?p=12&vd_source=980fae9339fdf81599b0d192bd40fc67
观看视频的时候没有找到笔记,所以自己把笔记记下来分享,笔记中很多步骤是根据我自己的实际情况来的,和视频中不一致。
1 分布式文件系统应用场景
互联网海量非结构化数据的存储需求,因为很多数据是非结构化的,非关系型的。
- 电商网站:海量商品图片
- 视频网站:海量视频文件
- 网盘:海量文件
- 社交网站:海量图片
1.1 MinIO介绍
Min0 是一个基于Apache license v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。Minio是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。
官网:
英文官网:https://min.io/
中文官网:http://www.minio.org.cn/
建议直接看英文文档,中文文档更新不及时。
对象存储服务(Object Storage Service,OSS) 是一种海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件。容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本。
对于中小型企业,如果不选择存储上云,那么 MinIO是个不错的选择,麻雀虽小,五脏俱全。当然 MinIO除了直接作为对象存储使用还可以作为云上对象存储服务的网关层,无缝对接到Amazon S3、MicroSoft Azure。
在中国:阿里巴巴、腾讯、百度、中国联通、华为、中国移动等等9000多家企业也都在使用MinlO产品。
MinIO优点
-
部署简单:一个single二进制文件及是一切,还可以支持各种平台。
-
minio支持海量存储,可按zone扩展(原zone不受任何影响),支持单个对象最大5TB;
-
兼容Amazon S3接口,充分考虑开发人员的需求和体验;
-
低冗余且磁盘损坏高容忍,标准且最高的数据冗余系数为2(即存储一个1M的数据对象,实际占用磁盘空间为2M)。但在任意n/2块disk损坏的情况下依然可以读出数据(n为一个纠删码集合(Erasure Coding Set)中的disk数量)。并且这种损坏恢复是基于单个对象的而不是基于整个存储卷的。
-
读写性能优异
基准测试
1.2 MinIO的基础概念
- object::存储到 Minio 的基本对象,如文件、字节流,Anything…,比如存储一个文件到MinIO中,这个文件就成为一个object
- 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尽可能分布在不同的节点上
1.3 纠删码EC(Erasure Code)
MinIO 使用纠删码机制来保证高可靠性,使用 highwayhash 来处理数据损坏(Bit Rot Protection)。关于纠删码,简单来说就是可以通过数学计算,把丢失的数据进行还原,它可以将n份原始数据,增加m份数据,并能通过n+m份中的任意n份数据,还原为原始数据。即如果有任意小于等于m份的数据失效,仍然能通过剩下的数据还原出来。
举例:
比如此时存一个文件,存在六个盘中,四个盘存储数据(n=4),两个盘存储纠删码加密之后的文件(m=2)。如果这个时候丢失两个盘(2 <= m),这个时候数据是可以恢复的,但是如果损坏了3(3>m),此时数据不可恢复。
所以MinIO是推荐一半一半分的,一半数据盘,一半纠删码加密的盘。如果此时坏掉的盘刚好坏掉一半,此时是不允许写的,只允许读,只有当没受损磁盘数量大于 n/2 + 1的时候才可以上传,因为这个时候才能保证至少有一块盘是纠删码加密过后的文件盘。
1.4 存储形式
文件对象上传到 MinlO,会在对应的数据存储盘中,以 Bucket 名称为目录,文件名称为下一级目录,文件名下是 part.1和xl.meta(老版本,最新版本如下图),前者是编码数据块及检验块,后者是元数据文件。
比如有四块盘,两块存数据,两块存纠删码加密后的文件。
一般来说是奇数盘存纠删码加密后的文件,偶数盘存元数据。
图中的754开头的是文件的hash。
1.5 存储方案
2 MinIO环境搭建
MinIO支持多种部署方式
单机部署
单机部署示意图
分布式
分布式部署示意图
2.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 modeerasure code对磁盘的个数是有要求的,如不满足要求,实例启动将失败。erasure code启用后,要求传给minio server的endpoint(standalone模式下,即本地磁盘上的目录)至少为4个
基于centos7
# 获取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
我用的这个版本启动之后是不会有日志的
基本账号密码
RootUser: minioadmin
RootPass: minioadmin
可以指定控制台的端口,具体的可以看官网,官网比较详细。
单机启动的话,此时是只有一块磁盘,没有办法使用纠删码,所以数据目录下存的就是元数据。
基于docker
去官网看命令
# 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"
启动成功之后界面,这是非后台启动。这里摁住ctrl + c
就能取消docker运行。
其它的一模一样。
minio纠删码模式
Minio使用纠删码 erasure code
和校验和checksum
来保护据免受硬件故障和声数据损坏。即便您丢失一半数量 (N/2) 的硬盘您仍然可以恢复数据。
纠删码是一种恢复丢失和损坏数的数学算法,Minio采用Reed-Solomon ode将对象拆分成N/2数据和N/2 奇校验块。这就意味着如果是12块盘,一个对象会被分成6个数据块、6个奇偶校验块,你可以丢失任意6块盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的盘中的数据进行恢复。
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"
启动之后增加文件
可以在/mnt目录下看到被存储的文件
2.2 分部署集群部署
分布式Minio可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式Minio避免了单点故障。
分布式存储可靠性常用方法
分布式存储,很关键的点在于数据的可靠性,即保证数据的完整,不丢失,不损坏。只有在可靠性实现的前提下,才有了追求一致性、高可用、高性能的基础。而对于在存储领域,一般对于保证数据可靠性的方法主要有两类,一类是冗余法,一类是校验法。
冗余
冗余法最简单直接,即对存储的数据进行副本备份,当数据出现丢失,损坏,即可使用备份内容进行恢复,而副本 备份的多少,决定了数据可靠性的高低。这其中会有成本的考量,副本数据越多,数据越可靠,但需要的设备就越多,成本就越高。可靠性是允许丢失其中一份数据。当前已有很多分布式系统是采用此种方式实现,如 Hadoop 的文件系统(3个副本),Redis 的集群,MySQL 的主备模式等。
校验
校验法即通过校验码的数学计算的方式,对出现丢失、损坏的数据进行校验、还原。注意,这里有两个作用,一个校验,通过对数据进行校验和(cheksum 进行计算,可以检查数据是否完整,有无损坏或更改,在数据传输和保存时经常用到,如 TCP 协议,二是恢复还原.通过对数据结合校验码,通过数学计算,还原丢失或损坏的数据,可以在保证数据可的前提下,降低几余,如单机硬盘存储中的 RAID技术,纠删码 (Erasure Code) 技术等。Minio 采用的就是纠删码技术。
分布式MinIO的优势
数据保护
分布式Minio采用纠删码来防范多个节点宕机和位衰减bit rot
分布式Minio至少需要4个硬盘,使用分布式Minio自动引入了纠删码功能。
高可用
单机Minio服务存在单点故障,相反,如果是一个有N块硬盘的分布式Minio,只要有N/2硬盘在线,你的数据就是安全的。不过你需要至少有N/2+1个硬盘来创建新的对象。
例如,一个16节点的Minio集群,每个节点16块硬盘,就算8台服务器宕机,这个集群仍然是可读的,不过你需要9台服移器才能写数据
一致性
Minio在分布式和单机模式下,所有读写操作都严格遵守read-after-write一致性模型。
运行分布式Minio
启动一个分布式Minio实例,你只需要把硬盘位置做为参数传给minio server命令即可,然后,你需要在所有其它节点运行同样的命令。
- 分布式Minio里所有的节点需要有同样的access秘钥和secret秘钥,这样这些节点才能建立联接。为了实现这个,你需要在执行minio server命令之前,先将access秘钥和secret秘钥export成环境变量。新版本使用MINIO_ROOT_USER&MINIO_ROOT_PASSWORD。
- 分布式Minio使用的磁盘里必须是干净的,里面没有数据。
- 下面示例里的IP仅供示例参考,你需要改成你真实用到的IP和文件夹路径。
- 分布式Minio里的节点时间差不能超过3秒,你可以使用NTP 来保证时间一致。
- 在Windows下运行分布式Minio处于实验阶段,不建议使用。
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"
下面是部署示意图
我的机器没有那么大的内存,所以采用四个节点,每个节点两个盘的配置。
(实际)配置4节点,每节点2个盘
这个是我实际配置的情况,我起了四台虚拟机,每台1G运行内存,20G硬盘。
具体步骤如下:
1、配置4个服务器,4个服务器的ip如下
minio01 192.168.246.162
minio02 192.168.246.163
minio03 192.168.246.164
minio03 192.168.246.165
2、服务器分别下载minio
如果下载很慢需要更换下载源
wget -q http://dl.minio.org.cn/server/minio/release/linux-amd64/minio
# 赋予权限
chmod +x minio
3、4台服务器建立好数据目录
如果你的虚拟机只有一个硬盘的话,会提示不能挂载在根目录,无法使用,所以要多挂载一个磁盘,挂载磁盘的操作可以在这篇文章看到
https://blog.csdn.net/weixin_41352552/article/details/127878574
此时我将第二个盘挂载到/data下,然后分别在各个机器新建文件夹
mkdir /data/export1
mkdir /data/export2
mkdir /data/export3
mkdir /data/export4
mkdir /data/export5
mkdir /data/export6
mkdir /data/export7
mkdir /data/export8
4、分别在4个节点启动minio
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
nohup ./minio server \
http://192.168.246.162/data/export1 \
http://192.168.246.162/data/export2 \
http://192.168.246.163/data/export3 \
http://192.168.246.163/data/export4 \
http://192.168.246.164/data/export5 \
http://192.168.246.164/data/export6 \
http://192.168.246.165/data/export7 \
http://192.168.246.165/data/export8 \
--console-address :9090 \
1>nohup.log 2>&1 &
5、停止minio的命令
如果有启动错误的,可以停止服务,直接在linux的终端运行即可。
pid=`ps -ef | grep minio | grep server | awk '{print $2}'` && kill -9 $pid
6、查看启动日志
每台机器都启动成功。
随后在浏览器访问http://192.168.246.162:9090
就可以访问到minio管理界面。
7、测试扩展集群
先停止集群
pid=`ps -ef | grep minio | grep server | awk '{print $2}'` && kill -9 $pid
本次测试使用的区方法启动服务,4台机器上执行启动命令,需要建立export100~103四个文件夹。得使用这种方法的才能够扩展集群,使用之前方法,ip一个一个写好的,不能扩展集群,会提示磁盘空间已经使用过,这就不能达到扩展集群的初衷。
用区方法启动的话,要保证阶段大于等于4,磁盘大于等于4(四个文件夹即可),否则在启动的时候,它会提示 “{N…M},M-N>=4 ” 之类的提示。
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
nohup ./minio server \
http://192.168.246.16{2...5}/data/export{100...103} \
--console-address :9090 \
1>nohup.log 2>&1 &
这个时候服务已经启动了。
此时来测试扩展集群,先停掉集群服务。再来添加一个集群,我使用伪集群,同台机器的不同文件夹,使用文件夹export200~203
nohup ./minio server \
http://192.168.246.16{2...5}/data/export{100...103} \
http://192.168.246.16{2...5}/data/export{200...203} \
--console-address :9090 \
1>nohup.log 2>&1 &
此时启动成功。
我总共起了四台机器,每台机器8个文件夹,所以4台服务器,32个驱动器。
8、重启集群
重启服务器之后,需要重新挂载磁盘,可以按照上面文章提到的直接设置开机启动挂载,我这边没有设置。
mount /dev/sdb /data
然后执行启动命令,启动命令就是跟刚开始启动集群的命令一致。
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
nohup ./minio server \
http://192.168.246.162/data/export1 \
http://192.168.246.162/data/export2 \
http://192.168.246.163/data/export3 \
http://192.168.246.163/data/export4 \
http://192.168.246.164/data/export5 \
http://192.168.246.164/data/export6 \
http://192.168.246.165/data/export7 \
http://192.168.246.165/data/export8 \
--console-address :9090 \
1>nohup.log 2>&1 &
使用Docker Compose部署MinIO
这部分我只摘抄笔记,并未实践。
要在Docker Compose上部署分布式MinIO,请下载docker-compose.yaml和nginx.conf到你的工作目录。
docker-compose pull
docker-compose up
扩展现有的分布式集群
这个跟上面一致。
例如我们是通过区的方式启动MinIO集群,命令行如下:
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
minio server http://host{1...32}/export{1...32}
MinIO支持通过命令,指定新的集群来扩展现有集群(纠删码模式),命令行如下:
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
minio server http://host{1...32}/export{1...32} http://host{33...64}/export{33...64}
现在整个集群就扩展了1024个磁盘,总磁盘变为2048个,新的对象上传请求会自动分配到最少使用的集群上。通过以上扩展策略,您就可以按需扩展您的集群。重新配置后重启集群,会立即在集群中生效,并对现有集群无影响。如上命令中,我们可以把原来的集群看做一个区,新增集群看做另一个区,新对象按每个区域中的可用空间比例放置在区域中。在每个区域内,基于确定性哈希算法确定位置。
基于nginx实现
因为我们起了多台服务器,为了使集群的性能发挥最大化,我们配置负载均衡。
配置nginx的负载均衡就可以,对于9090的端口进行负载均衡,要添加对webSocket的支持才可以。
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream minio{
server 192.168.246.162:9090;
server 192.168.246.163:9090;
server 192.168.246.164:9090;
server 192.168.246.165:9090;
}
server {
listen 9001;
server_name localhost;
location / {
proxy_pass http://minio/;
# 添加了websocket支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
配置好了之后启动nginx,浏览器输入nginx的地址和端口就可以了。
2.3 MinIO客户端使用
MinlO Client(mc为ls,cat,cp,mirror,dif,find等UNIX命令提供了一种替代方案。它支持文件系统和兼容Amazon S3的云存储服务(AWS Signature v2和v4) 。
部署客户端mc
平台 | cpu | url |
---|---|---|
linux | 64 intel | https://min.io/docs/minio/linux/reference/minio-mc.html |
可以在官网找到下载的地址,我在linux平台上使无法使用mc的,输入mc --help会卡住,具体的原因还没有查清楚。所以我下载了windows版本的,windows版本的可以直接使用。
linux版本
curl https://dl.min.io/client/mc/release/linux-amd64/mc \
--create-dirs \
-o $HOME/minio-binaries/mc
chmod +x $HOME/minio-binaries/mc
export PATH=$PATH:$HOME/minio-binaries/
mc --help
windows版本
https://dl.min.io/client/mc/release/windows-amd64/mc.exe
配置mc
因为没有使用linux的mc,所以以下的实操都是在windows上。
mc将所有的配置信息都存储在~/.mc/config.json
中
# 查看mchost配置
mc config host ls
# 添加minio服务
mc config host add minio-server http://192.168.246.162:9000 admin 12345678
# 删除host
mc config host remove minio-server
mc命令使用
官网里面有
举例使用cp命令
# 查询minio服务上所有的bukets
mc ls minio-server
# 上传文件
mc cp D:\programfile\MinIOClient\1.jpg minio-server/test/
# 下载文件
mc cp minio-server/test/1.jpg D:\programfile\MinIOClient\1\
# 删除文件
mc rm minio-server/test/1.jpg
Bucket管理
# 创建bucket
mc mb minio-server/bucket01
# 删除bucket,不加--force的话,那么如果有数据就无法删除。
mc rb --force minio-server/bucket02
# bucket不为空,可以强制删除 慎用
mc rb --force minio-server/bucket01
# 查询bucket03磁盘的使用情况
mc du minio-server/bucket03
mc admin 使用
Minio Client (mc)提供了”admin”子命来对您的Minlo部署执行管理任务
命令 | 说明 |
---|---|
service | 服务重启并停止所有MinIO服务器 |
update | 更新更新所有MinIO服务器 |
info | 信息显示MinIO服务器信息 |
user | 用户管理用户 |
group | 小组管理小组 |
policy | MinIO服务器中定义的策略管理策略 |
config | 配置管理MinIO服务器配置 |
heal | 修复MinIo服务器上的磁盘,存储桶和对象 |
profile | 概要文件生成概要文件数据以进行调试 |
top | 顶部提供MinIo的顶部统计信息 |
trace | 跟踪显示MinIO服务器的http跟踪 |
console | 控制台显示MinTo服务器的控制台日志 |
prometheus | Prometheus管理Prometheus配贸 |
kms | kms执行KMS管理操作 |
用户管理
mc admin user --help
# 新建用户
mc admin user add minio-server fox
mc admin user add minio-server fox02 12345678
#查看用户
mc admin user list minio-server
#禁用用户
mc admin user disable minio-server fox02
#启用用户
mc admin user enable minio-server fox02
#查看用户信息
mc admin user info minio-server fox
#删除用户
mc admin user remove minio-server fox02
策略管理
policy命令,用于添加,删除,列出策略,获取有关策略的信息并为MiniO服务器上的用户设置策略.
mc admin policy --help
#列出MinIo上的所有固定策略
mc admin policy list minio-server
# 查看policy信息
mc admin policy info minio-server readwrite
添加新的策略
编写策略文件/root/tulingmall.json
这个脚本规定是允许获取test下的buket和对象的策略。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::test/*"
]
}
]
}
这个脚本是可以对于test进行所有操作。
tulingmall1.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::test/*"
]
}
]
}
将脚本添加到策略数据库
# 添加新的策略,/root/tulingmall.json取决于自己文件存放的位置,我直接把json放在了跟mc.exe同级目录下,所以我使用的命令是:mc admin policy add minio-server tulingmall-admin tulingmall.json
mc admin policy add minio-server tulingmall-admin /root/tulingmall.json
# 查看所有的策略
mc admin policy list minio-server
# 设置用户访问策略
mc admin policy set minio-server tulingmall-admin user=fox
使用fox用户登录
只能查看
使用tulingmall1.json新建角色tulingmall-admin1,新建用户fox02,该用户可以对于test进行任何操作。
3 MinIO Java Client使用
MinioJava Client SDK提供简单的API来访问任何与Amazon S3兼容的对象存储服务。
官方文档地址:https://min.io/docs/minio/linux/developers/java/minio-java.html
可以参照官方代码上传
引入依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.1</version>
</dependency>
3.1 文件上传
编码
package pers.lgq.util;
/**
* @author linguiquan
* @date 2023-02-10 15:52
*/
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.UploadObjectArgs;
import io.minio.errors.MinioException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class FileUploader {
public static void main(String[] args)
throws IOException, NoSuchAlgorithmException, InvalidKeyException {
try {
// 链接客户端
MinioClient minioClient =
MinioClient.builder()
.endpoint("http://192.168.246.162:9000")
.credentials("admin", "12345678")
.build();
// 判断桶是否存在
boolean found =
minioClient.bucketExists(BucketExistsArgs.builder().bucket("test").build());
if (!found) {
// Make a new bucket called 'asiatrip'.
minioClient.makeBucket(MakeBucketArgs.builder().bucket("test").build());
} else {
System.out.println("Bucket 'asiatrip' test exists.");
}
// Upload '/home/user/Photos/asiaphotos.zip' as object name 'asiaphotos-2015.zip' to bucket
// 'asiatrip'.
minioClient.uploadObject(
UploadObjectArgs.builder()
.bucket("test")
// 上传文件名,即minio要存储的名称
.object("test.jpg")
// 本地文件的位置
.filename("1.jpg")
.build());
System.out.println(
"'/home/user/Photos/asiaphotos.zip' is successfully uploaded as "
+ "object 'asiaphotos-2015.zip' to bucket 'asiatrip'.");
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
System.out.println("HTTP trace: " + e.httpTrace());
}
}
}
3.2 文件下载
public class FileDownloader {
public static void main(String[] args)
throws IOException, NoSuchAlgorithmException, InvalidKeyException {
try {
// 链接客户端
MinioClient minioClient =
MinioClient.builder()
.endpoint("http://192.168.246.162:9000")
.credentials("admin", "12345678")
.build();
minioClient.downloadObject(
DownloadObjectArgs.builder()
.bucket("test")
// 下载文件名称
.object("test.jpg")
// 下载文件位置和保存名称
.filename("2.jpg")
.build()
);
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
System.out.println("HTTP trace: " + e.httpTrace());
}
}
}
3.3 Spring boot整合minio
1 pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.3.7</version>
</dependency>
2 配置文件
application.properties
minio.host=127.0.0.1
minio.port=9002
minio.username=admin
minio.password=12345678
server.port=8089
MinioProperties.java
@Data
@ConfigurationProperties(prefix = "minio")
@Component
public class MinioProperties {
private String host;
private Integer port;
private String username;
private String password;
}
MinioConfig.java
@Configuration
public class MinioConfig {
private final MinioProperties minioProperties;
public MinioConfig(MinioProperties minioProperties) {
this.minioProperties = minioProperties;
}
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint("http://" + minioProperties.getHost() + ":" + minioProperties.getPort())
.credentials(minioProperties.getUsername(), minioProperties.getPassword())
.build();
}
}
3 主启动
@EnableConfigurationProperties
@SpringBootApplication
public class SpringBootMinioApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMinioApplication.class, args);
}
}
4 nginx配置
这里我采用的是连接集群的方式,nginx配置在本地,所以我的host配置成127.0.0.1。
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream minio{
server 192.168.246.162:9090;
server 192.168.246.163:9090;
server 192.168.246.164:9090;
server 192.168.246.165:9090;
}
upstream api{
server 192.168.246.162:9000;
server 192.168.246.163:9000;
server 192.168.246.164:9000;
server 192.168.246.165:9000;
}
server {
listen 9001;
server_name localhost;
#必须 防止请求头丢失
underscores_in_headers on;
location / {
proxy_pass http://minio/;
# 添加了websocket支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 9002;
server_name localhost;
#必须 防止请求头丢失
underscores_in_headers on;
location / {
proxy_pass http://api/;
# 添加了websocket支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
5 逻辑代码
这些部分由读者自己写,加深印象,可以把官方的demo下载下来看。