Docker部署高性能分布式存储MinIO

文件存储系统,相比FastDFS使用MinIO易上手,可扩展,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
优势:

1.Minio 有良好的存储机制
2.Minio 有很好纠删码的算法与擦除编码算法
3.可向大数据方面过渡
4.docker搭建非常方便

适用场景:

1.对象存储
2. 文件服务器

原理:

MinIO分布式集群是指在多个服务器节点均部署MinIO服务,并将其组建为分布式存储集群,对外提供标准S3接口以进行统一访问。
Docker部署高性能分布式存储MinIO_第1张图片
MinIO集群采用去中心化无共享架构,各节点间为对等关系,连接至任一节点均可实现对集群的访问。在我们的方案中还选择了Nginx的轮询实现各个节点的负载均衡。

docker部署minio

docker pull minio/minio:latest

Docker部署高性能分布式存储MinIO_第2张图片
Docker 启动Minio镜像

docker run -d  -p 9000:9000 -p 9001:9001 --name minio1  -v /mnt/data:/data -e "MINIO_ROOT_USER=minioadmin" -e "MINIO_ROOT_PASSWORD=minioadmin"   minio/minio  server /data --console-address ":9001"
# 命令详解
# -e MINIO_ROOT_USER 指定用户名
# -e MINIO_ROOT_PASSWORD 指定密码
# -v 挂载目录,持久化minio目录
#  新版minio有两个端口注意 9000给客户端使用,9001登录服务端使用

开放端口浏览器进行访问:http://ip:9000 (账号密码:minioadmin)
Docker部署高性能分布式存储MinIO_第3张图片
Object:存储到 Minio 的基本对象,如文件、字节流,Anything…

Bucket:用来存储 Object 的逻辑空间。每个 Bucket 之间的数据是相互隔离的。对于客户端而言,就相当于一个存放文件的顶层文件夹。
创建一个Buckets:
Docker部署高性能分布式存储MinIO_第4张图片
去服务器上看一下:
Docker部署高性能分布式存储MinIO_第5张图片

SpringBoot整合minio

Docker部署高性能分布式存储MinIO_第6张图片

导入最新依赖:

        <dependency>
		    <groupId>io.minio</groupId>
		    <artifactId>minio</artifactId>
		    <version>8.2.0</version>
		</dependency>

项目中minio配置application.yml:

server:
  port: 8080

logging:
  config: classpath:log4j2.xml

spring:
  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 1000MB
      
#minio配置
minio:
  url: http://120.48.54.67:9000  #对象存储服务的URL
  accessKey: minioadmin #Access key账户
  secretKey: minioadmin  #Secret key密码
  bucketName: test #minio空间名

MinioConfig:

package boot.spring.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import io.minio.MinioClient;

@Configuration
public class MinioConfig {
	
	@Value("${minio.url}")
    private String url;
    @Value("${minio.accessKey}")
    private String accessKey;
    @Value("${minio.secretKey}")
    private String secretKey;
    
    @Bean
    public MinioClient getMinioClient() {
        MinioClient minioClient = MinioClient.builder().endpoint(url)
				.credentials(accessKey, secretKey).build();
        return minioClient;
    }
    
}

MinioUtil:

package boot.spring.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import boot.spring.domain.Fileinfo;
import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.ListObjectsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveBucketArgs;
import io.minio.RemoveObjectArgs;
import io.minio.Result;
import io.minio.messages.Bucket;
import io.minio.messages.Item;

@Component
public class MinioUtil {
	@Autowired
    private MinioClient minioClient;
	
	/**
	 * 创建一个桶
	 */
	public void createBucket(String bucket) throws Exception {
		boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
		if (!found) {
			minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
		}
	}
	
	/**
	 * 上传一个文件
	 */
	public void uploadFile(InputStream stream, String bucket, String objectName) throws Exception {
		minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName)
				.stream(stream, -1, 10485760).build());
	}
	
	/**
	 * 列出所有的桶
	 */
	public List<String> listBuckets() throws Exception {
		List<Bucket> list = minioClient.listBuckets();
		List<String> names = new ArrayList<>();
		list.forEach(b -> {
			names.add(b.name());
		});
		return names;
	}
	
	/**
	 * 列出一个桶中的所有文件和目录
	 */
	public List<Fileinfo> listFiles(String bucket) throws Exception {
		Iterable<Result<Item>> results = minioClient.listObjects(
			    ListObjectsArgs.builder().bucket(bucket).recursive(true).build());
			
			List<Fileinfo> infos = new ArrayList<>();
				results.forEach(r->{
					Fileinfo info = new Fileinfo();
					try {
						Item item = r.get();
						info.setFilename(item.objectName());
						info.setDirectory(item.isDir());
						infos.add(info);
					} catch (Exception e) {
						e.printStackTrace();
					}
				});
		return infos;
	}
	
	/**
	 * 下载一个文件
	 */
	public InputStream download(String bucket, String objectName) throws Exception {
		InputStream stream = minioClient.getObject(
		              GetObjectArgs.builder().bucket(bucket).object(objectName).build());
		return stream;
	}
	
	/**
	 * 删除一个桶
	 */
	public void deleteBucket(String bucket) throws Exception {
		minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());
	}
	
	/**
	 * 删除一个对象
	 */
	public void deleteObject(String bucket, String objectName) throws Exception {
		minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());
	}
}

FileController:

package boot.spring.controller;


import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import boot.spring.domain.AjaxResult;
import boot.spring.domain.Fileinfo;
import boot.spring.util.MinioUtil;
import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.GetObjectResponse;
import io.minio.ListObjectsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.Result;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(tags = "文件操作接口")
@Controller
public class FileController {
	
	@Autowired
	MinioUtil minioUtil;
	
	@ApiOperation("上传一个文件")
	@RequestMapping(value = "/uploadfile", method = RequestMethod.POST)
	@ResponseBody
	public AjaxResult fileupload(@RequestParam MultipartFile uploadfile, @RequestParam String bucket, 
			@RequestParam(required=false) String objectName) throws Exception {
		minioUtil.createBucket(bucket);
		if (objectName != null) {
			minioUtil.uploadFile(uploadfile.getInputStream(), bucket, objectName+"/"+uploadfile.getOriginalFilename());
		} else {
			minioUtil.uploadFile(uploadfile.getInputStream(), bucket, uploadfile.getOriginalFilename());
		}
		return AjaxResult.success();
	}
	
	@ApiOperation("列出所有的桶")
	@RequestMapping(value = "/listBuckets", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult listBuckets() throws Exception {
		return AjaxResult.success(minioUtil.listBuckets());
	}
	
	@ApiOperation("递归列出一个桶中的所有文件和目录")
	@RequestMapping(value = "/listFiles", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult listFiles(@RequestParam String bucket) throws Exception {
		return AjaxResult.success("200", minioUtil.listFiles(bucket));
	}
	
	@ApiOperation("下载一个文件")
	@RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
	@ResponseBody
	public void downloadFile(@RequestParam String bucket, @RequestParam String objectName,
			HttpServletResponse response) throws Exception {
		InputStream stream = minioUtil.download(bucket, objectName);
		ServletOutputStream output = response.getOutputStream();
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName.substring(objectName.lastIndexOf("/") + 1), "UTF-8"));
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("UTF-8");
		IOUtils.copy(stream, output);
	}
	
	
	@ApiOperation("删除一个文件")
	@RequestMapping(value = "/deleteFile", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult deleteFile(@RequestParam String bucket, @RequestParam String objectName) throws Exception {
		minioUtil.deleteObject(bucket, objectName);
		return AjaxResult.success();
	}
	
	@ApiOperation("删除一个桶")
	@RequestMapping(value = "/deleteBucket", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult deleteBucket(@RequestParam String bucket) throws Exception {
		minioUtil.deleteBucket(bucket);
		return AjaxResult.success();
	}	
}

访问一下:
Docker部署高性能分布式存储MinIO_第7张图片
Docker部署高性能分布式存储MinIO_第8张图片
Docker部署高性能分布式存储MinIO_第9张图片
去Dashboard查看一下:
Docker部署高性能分布式存储MinIO_第10张图片

你可能感兴趣的:(Linux运维,分布式架构,docker,分布式,java)