赞
踩
前面我们做了分布式文件存储系统FastDFS的部署应用,其安装还是比较繁琐的,而且实际生产的应用限制较大,下面,介绍一款开源的文件系统——MinIO,它是一种对象存储解决方案,提供与 Amazon Web Services S3 兼容的 API 并支持所有核心 S3 功能,同时有完善的官网几文档,在实际生产中也有较多应用。
首先,我们从官网下载MinIO的二进制文件,下载地址,然后上传到我们的服务器上,修改权限chmod +x minio
,然后设置用户名和密码,注意,用户名长度至少3位,密码长度至少8位,export MINIO_ACCESS_KEY=minio
,export MINIO_SECRET_KEY=minioadmin
,然后可以通过nohup ./minio server --address :9000 --console-address :9001 /tools/MinIO/minio_server/data > /tools/MinIO/minio_server/data/minio.log &
命令进行后台启动,这里address对应的是服务端口,而console-address对应的是控制台端口,这样,我们就完成了单机的部署,访问下控制台服务器ip:9001
根据提示创建bucket,注意命名需要符合规则
确认当前bucket的权限是读写权限
通过控制台测试上传文件
由于这里账号密码是通过export声明的,因此每次重启服务都需要重新执行,所以我们将其设为开机自启服务,创建启动脚本miniostart.sh,添加如下内容
export MINIO_ACCESS_KEY=minio
export MINIO_SECRET_KEY=minioadmin
/tools/MinIO/minio_server/minio server --address :9000 --console-address :9001 /tools/MinIO/minio_server/data > /tools/MinIO/minio_server/data/minio.log &
修改权限chmod 777 miniostart.sh
,编辑文件vi /etc/rc.d/rc.local
,将本启动脚本的完整路劲添加进去即可。
minio集群部署,官方建议至少4个节点,因为只有n/2个节点存活才能保证读业务,n/2+1个节点存货才能保证写业务,因此我们这里配置了四台机器,同时需要保证每个节点间的时间保持一致,因此先开启时间同步,我们这里采用ntp的方式,安装yum -y install ntp
,设置开机启动systemctl enable ntpd,systemctl start ntpd
,设置时间同步timedatectl set-ntp yes
,然后更新时间ntpdate -u cn.pool.ntp.org
,设置国内的时区ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
,操作完成后我们可以通过data
命令查看时间是否一致。接下来我们开始部署集群,请注意,暂停操作,先看本文档。创建相关的目录mkdir /home/ysgs/tools/minio/{config,data,logs} -p
,然后上传二进制文件或者执行下载命令wget https://dl.min.io/server/minio/release/linux-amd64/minio 执行安装chmod +x minio
,接着我们创建启动脚本,如下所示
#用户名
export MINIO_ACCESS_KEY=minio
#密码
export MINIO_SECRET_KEY=minioadmin
#minio启动路径,设置配置路径,服务端口9000,控制台端口9001,数据存储路径对应四个节点
/home/ysgs/tools/minio/minio server --config-dir /home/ysgs/tools/minio/config --address ":9000" --console-address ':9001' \
http://192.168.136.128/home/ysgs/tools/minio/data \
http://192.168.136.131/home/ysgs/tools/minio/data \
http://192.168.136.132/home/ysgs/tools/minio/data \
http://192.168.136.133/home/ysgs/tools/minio/data > /home/ysgs/tools/minio/logs/minio.log &
然后我们尝试启动,结果发现日志有报错Drive
/mnt/data1is part of root drive, will not be used (*errors.errorString)
,这是因为minio集群需要单独的磁盘挂载,不能使用文件夹代替,因此,需要先挂载磁盘,先关掉虚拟机,进入设置,添加硬盘(从这里开始操作)
启动虚拟机,切换root用户,查看分区信息lsblk
sdb是未挂在的磁盘,新建目录data2,mkdir /data2
,挂载磁盘mount /dev/sdb /data2
,如果出现错误,执行mkfs.ext4 /dev/sdb
格式化磁盘,再重新挂载,然后通过df -h
查看
这只是临时挂载,我们需要设置自动挂载,编辑挂载配置vim /etc/fstab
,在文件末尾追加如下内容/dev/sdb /data2 ext4 defaults 0 0
,重启虚拟机查看挂载,正常,然后我们更改启动脚本,将其数据目录换成我们的单独挂载磁盘,如下
export MINIO_ACCESS_KEY=minio
export MINIO_SECRET_KEY=minioadmin
/home/ysgs/tools/minio/minio server --config-dir /home/ysgs/tools/minio/config --address ":9000" --console-address ':9001' \
http://192.168.136.128/data2/minio/data \
http://192.168.136.131/data2/minio/data \
http://192.168.136.132/data2/minio/data \
http://192.168.136.133/data2/minio/data > /home/ysgs/tools/minio/logs/minio.log &
然后我们逐个启动,启动成功,我们可以尝试访问任意ip:9001,可以发现都能访问成功,我们在任意一台机器上创建bucket之后,其他控制台都能访问到
然后我们测试控制台上传文件,看其他节点能否查看到
至此,集群搭建成功,然后我们可以通过一台nginx代理我们的集群,修改nginx配置文件,在http块中添加如下内容
#服务端节点 upstream minio{ server 192.168.136.128:9000; #server 192.168.136.131:9000; server 192.168.136.132:9000; server 192.168.136.133:9000; } #控制台节点,采取ip_hash策略 upstream minio_client{ ip_hash; server 192.168.136.128:9001; #server 192.168.136.131:9001; server 192.168.136.132:9001; server 192.168.136.133:9001; } #监听服务端请求,主要是springboot项目应用 server{ listen 9000; server_name localhost; ignore_invalid_headers off; client_max_body_size 0; proxy_buffering off; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 300; #nginx代理console后查看数据报错Couldn't establish WebSocket connection. #需要在nginx增加配置,使nginx代理支持长连接 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; chunked_transfer_encoding off; proxy_pass http://minio; } } #监听控制台请求 server{ listen 9001; server_name localhost; ignore_invalid_headers off; client_max_body_size 0; proxy_buffering off; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-NginX-Proxy true; proxy_connect_timeout 300; #nginx代理console后查看数据报错Couldn't establish WebSocket connection. #需要在nginx增加配置,使nginx代理支持长连接 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; chunked_transfer_encoding off; proxy_pass http://minio_client; } }
配置好之后,重启nginx,访问nginx的ip:9001,访问成功,可以看到节点信息
至此,minio的集群搭建完成。
首先,添加对应的依赖
<!--minio-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.4</version>
</dependency>
然后,创建minio的相关配置类,我这里并没有做SpringBoot项目启动,因此写的默认值,且没有交给Spring管理,作为参考即可
import io.minio.MinioClient;
public class MinioConfig {
private String ip ="192.168.136.135";
private int port = 9000;
private String accessKey = "minio";
private String secretKey = "minioadmin";
public MinioClient minioClient(){
return MinioClient.builder()
.endpoint(ip,port,false)
.credentials(accessKey,secretKey)
.build();
}
}
可以看到,我们的ip信息是nginx的ip,这样,我们可以操控集群操作。接下来,进行API的相关测试,这里先给一个官方的QuickStart文档和API地址,我们可以参靠API文档,来进行操作,例如,我们创建bucket,我们找到对应的API
点击该方法,可以看到详细的调用
下面是一些调用示例:
package com.example.test.minio; import io.minio.BucketExistsArgs; import io.minio.MakeBucketArgs; import io.minio.MinioClient; public class test { public static MinioClient getMinioClient () { MinioConfig minioConfig = new MinioConfig(); return minioConfig.minioClient(); } /** * 创建bucket * @param bucketName * @throws Exception */ public static void createBucket(String bucketName) throws Exception{ BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build(); if(!getMinioClient().bucketExists(bucketExistsArgs)){ MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build(); getMinioClient().makeBucket(makeBucketArgs); } } public static void main(String[] args) throws Exception { createBucket("cluster"); } }
我们创建名为cluster的bucket,然后,我们去nginx代理的控制台查看,如下
/** * 根据已有输入流上传文件 * @param bucketName * @param objectName * @param inputStream * @param objectSize * @param contentType * @return * @throws Exception */ public static ObjectWriteResponse putObject(String bucketName, String objectName, InputStream inputStream,long objectSize,String contentType) throws Exception{ if(StringUtils.isEmpty(bucketName)){ throw new RuntimeException("bucketName为空"); } //调用创建bucket方法,主要判断是否存在 createBucket(bucketName); //objectSize已知,partSize设为-1意为自动设置 long partSize = -1; PutObjectArgs putObjectArgs = PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(inputStream,objectSize,partSize) .contentType(contentType) .build(); ObjectWriteResponse response = getMinioClient().putObject(putObjectArgs); return response; } public static void main(String[] args) throws Exception { InputStream inputStream = new FileInputStream("C:\\Users\\zy_ys\\Desktop\\壁纸\\富士山.png"); putObject("cluster","富士山.png",inputStream,137920,"image/png"); }
其中contentType为文件类型,下面是一些常见的文件后缀和contentType对照
#图片 jpg=image/jpeg gif=image/gif png=image/png ico=image/x-icon jpeg=image/jpeg wbmp=image/vnd.wap.wbmp #视频&音频 mp3=audio/mp3 mp4=video/mp4 #文档 doc=application/msword pdf=application/pdf ppt=application/x-ppt txt=text/plain xls=application/x-xls .xml=text/xml #证书文件 p10=application/pkcs10 p12=application/x-pkcs12
下载minio集群的文件,创建下载流下载
/** * 创建下载流 * @param bucketName * @param objectName * @return * @throws Exception */ public static InputStream getObject(String bucketName,String objectName) throws Exception{ GetObjectArgs getObjectArgs = GetObjectArgs.builder() .bucket(bucketName) .object(objectName) .build(); return getMinioClient().getObject(getObjectArgs); } public static void main(String[] args) throws Exception { InputStream inputStream = getObject("cluster", "富士山.png"); File file = new File("C:\\Users\\zy_ys\\Desktop\\富士山.png"); OutputStream outputStream = new FileOutputStream(file); byte[] bytes = new byte[1024]; int length; while((length = inputStream.read(bytes))!=-1){ outputStream.write(bytes,0,length); } outputStream.close(); inputStream.close(); }
获取临时访问连接,可设置有效期,过期后自动失效,如下
/** * 获取对象的临时访问url,有效期1分钟 * @param bucketName * @param objectName * @return * @throws Exception */ public static String getObjectURL(String bucketName,String objectName) throws Exception{ GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder() .bucket(bucketName) .object(objectName) .expiry(1, TimeUnit.MINUTES) .method(Method.GET) .build(); return getMinioClient().getPresignedObjectUrl(args); } public static void main(String[] args) throws Exception { System.out.println(getObjectURL("cluster","富士山.png")); }
删除文件后,在集群控制台可以发现文件不存在
/** * 删除文件 * @param bucketName * @param objectName * @throws Exception */ public static void removeObject(String bucketName,String objectName) throws Exception{ RemoveObjectArgs args = RemoveObjectArgs.builder() .bucket(bucketName) .object(objectName) .build(); getMinioClient().removeObject(args); } public static void main(String[] args) throws Exception { removeObject("cluster","富士山.png"); System.out.println("文件已删除"); }
上面是一些常用API的操作,我们可以按照API文档给出的示例进行操作,至此,MinIO的部署和简单使用就搞定了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。