文件存储方式对比

常见的分布式文件系统

1, MinIO简介

MinIO基于Apache License v2.0开源协议的对象存储服务,可以做为云存储的解决方案用来保存海量的图片,视频,文档。

  • 由于采用Golang实现,服务端可以工作在Windows,Linux, OS X和FreeBSD上。配置简单,基本是复制可执行程序,单行命令可以运行起来。
  • MinIO兼容亚马逊S3( Simple Storage Service简单存储服务)云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
  • 官网文档:http://docs.minio.org.cn/docs/

基本概念

  • bucket – 类比于文件系统的目录
  • Object – 类比文件系统的文件
  • Keys – 类比文件名

2 MinIO特点

  • 数据保护
    Minio使用Minio Erasure Code(纠删码)来防止硬件故障。即便损坏一半以上的driver,但是仍然可以从中恢复。
  • 高性能
    作为高性能对象存储,在标准硬件条件下它能达到55GB/s的读、35GB/s的写速率
  • 可扩容
    不同MinIO集群可以组成联邦,并形成一个全局的命名空间,并跨越多个数据中心
  • SDK支持
    基于Minio轻量的特点,它得到类似Java、Python或Go等语言的sdk支持
  • 有操作页面
    面向用户友好的简单操作界面,非常方便的管理Bucket及里面的文件资源
  • 功能简单
    这一设计原则让MinIO不容易出错、更快启动
  • 丰富的API
    支持文件资源的分享连接及分享链接的过期策略、存储桶操作、文件列表访问及文件上传下载的基本功能等。
  • 文件变化主动通知
    存储桶(Bucket)如果发生改变,比如上传对象和删除对象,可以使用存储桶事件通知机制进行监控,并通过以下方式发布出去:AMQP、MQTT、Elasticsearch、Redis、NATS、MySQL、Kafka、Webhooks等。

3 开箱使用

3.1 安装启动

我们提供的镜像中已经有minio的环境

我们可以使用docker进行环境部署和启动

docker run -p 9000:9000 -p 9090:9090 \--net=host \--name minio \-d --restart=always \-e "MINIO_ACCESS_KEY=username" \-e "MINIO_SECRET_KEY=password" \-v /mydata/minio/data:/mydata/minio/data \-v /mydata/minio/config:/mydata/minio/config \minio/minio server \/data --console-address ":9090" -address ":9000"

3.2 管理控制台

我们在地址栏输入:http://192.168.200.130:9000/即可进入登录界面。

Access Key为minio ,Secret_key 为minio123 进入系统后可以看到主界面

基本概念

  • bucket – 类比于文件系统的目录
  • Object – 类比文件系统的文件
  • Keys – 类比文件名

点击右下角的“+”号 ,点击下面的图标,创建一个桶

4 快速入门

4.1 创建工程,导入依赖

创建minio-demo,对应pom如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>minio-test</artifactId><groupId>com.test</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>minio-demo</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>7.1.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies></project>

4.2 上传文件

SpringBoot引导类:

 package com.test.minio;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class MinIOApplication {public static void main(String[] args) {SpringApplication.run(MinIOApplication.class,args);}}

创建测试类,上传html文件

  package com.test.minio.test;import io.minio.MinioClient;import io.minio.PutObjectArgs;import java.io.FileInputStream;public class MinIOTest {public static void main(String[] args) {FileInputStream fileInputStream = null;try {fileInputStream =  new FileInputStream("D:\\list.html");;//1.创建minio链接客户端MinioClient minioClient = MinioClient.builder().credentials("minio", "minio123").endpoint("http://192.168.200.130:9000").build();//2.上传PutObjectArgs putObjectArgs = PutObjectArgs.builder().object("list.html")//文件名.contentType("text/html")//文件类型.bucket("leadnews")//桶名词  与minio创建的名词一致.stream(fileInputStream, fileInputStream.available(), -1) //文件流.build();minioClient.putObject(putObjectArgs);System.out.println("http://192.168.200.130:9000/leadnews/ak47.jpg");} catch (Exception ex) {ex.printStackTrace();}}}
   # 如果文件上传成功后不能访问,则需要设置bucket的访问权限

5 封装MinIO为starter

5.1 创建模块minio-file-starter

模块名称:minio-file-starter

导入依赖

  <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>7.1.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies>

5.2 配置类

MinIOConfigProperties

package com.test.file.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;import java.io.Serializable;@Data
@ConfigurationProperties(prefix = "minio")  // 文件上传 配置前缀file.oss
public class MinIOConfigProperties implements Serializable {private String accessKey;private String secretKey;private String bucket;private String endpoint;private String readPath;
}

MinIOConfig

   package com.test.file.config;import com.test.file.service.FileStorageService;import io.minio.MinioClient;import lombok.Data;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Data@Configuration@EnableConfigurationProperties({MinIOConfigProperties.class})//当引入FileStorageService接口时//@ConditionalOnClass(FileStorageService.class)public class MinIOConfig {@Autowiredprivate MinIOConfigProperties minIOConfigProperties;@Beanpublic MinioClient buildMinioClient(){return MinioClient.builder().credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey()).endpoint(minIOConfigProperties.getEndpoint()).build();}}

5.3 封装操作minIO类

FileStorageService

   package com.test.file.service;import java.io.InputStream;/*** @author test*/public interface FileStorageService {/***  上传图片文件* @param prefix  文件前缀* @param filename  文件名* @param inputStream 文件流* @return  文件全路径*/public String uploadImgFile(String prefix, String filename,InputStream inputStream);/***  上传html文件* @param prefix  文件前缀* @param filename   文件名* @param inputStream  文件流* @return  文件全路径*/public String uploadHtmlFile(String prefix, String filename,InputStream inputStream);/*** 删除文件* @param pathUrl  文件全路径*/public void delete(String pathUrl);/*** 下载文件* @param pathUrl  文件全路径* @return**/public byte[]  downLoadFile(String pathUrl);}

MinIOFileStorageService

package com.test.file.service.impl;import com.test.file.config.MinIOConfig;
import com.test.file.config.MinIOConfigProperties;
import com.test.file.service.FileStorageService;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;
import org.springframework.util.StringUtils;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;@Slf4j
@EnableConfigurationProperties(MinIOConfigProperties.class)
@Import(MinIOConfig.class)
public class MinIOFileStorageService implements FileStorageService {@Autowiredprivate MinioClient minioClient;@Autowiredprivate MinIOConfigProperties minIOConfigProperties;private final static String separator = "/";/*** @param dirPath* @param filename  yyyy/mm/dd/file.jpg* @return*/public String builderFilePath(String dirPath,String filename) {StringBuilder stringBuilder = new StringBuilder(50);if(!StringUtils.isEmpty(dirPath)){stringBuilder.append(dirPath).append(separator);}SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");String todayStr = sdf.format(new Date());stringBuilder.append(todayStr).append(separator);stringBuilder.append(filename);return stringBuilder.toString();}/***  上传图片文件* @param prefix  文件前缀* @param filename  文件名* @param inputStream 文件流* @return  文件全路径*/@Overridepublic String uploadImgFile(String prefix, String filename,InputStream inputStream) {String filePath = builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath).contentType("image/jpg").bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1).build();minioClient.putObject(putObjectArgs);StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separator+minIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString();}catch (Exception ex){log.error("minio put file error.",ex);throw new RuntimeException("上传文件失败");}}/***  上传html文件* @param prefix  文件前缀* @param filename   文件名* @param inputStream  文件流* @return  文件全路径*/@Overridepublic String uploadHtmlFile(String prefix, String filename,InputStream inputStream) {String filePath = builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath).contentType("text/html").bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1).build();minioClient.putObject(putObjectArgs);StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separator+minIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString();}catch (Exception ex){log.error("minio put file error.",ex);ex.printStackTrace();throw new RuntimeException("上传文件失败");}}/*** 删除文件* @param pathUrl  文件全路径*/@Overridepublic void delete(String pathUrl) {String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/","");int index = key.indexOf(separator);String bucket = key.substring(0,index);String filePath = key.substring(index+1);// 删除ObjectsRemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();try {minioClient.removeObject(removeObjectArgs);} catch (Exception e) {log.error("minio remove file error.  pathUrl:{}",pathUrl);e.printStackTrace();}}/*** 下载文件* @param pathUrl  文件全路径* @return  文件流**/@Overridepublic byte[] downLoadFile(String pathUrl)  {String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/","");int index = key.indexOf(separator);String bucket = key.substring(0,index);String filePath = key.substring(index+1);InputStream inputStream = null;try {inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build());} catch (Exception e) {log.error("minio down file error.  pathUrl:{}",pathUrl);e.printStackTrace();}ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buff = new byte[100];int rc = 0;while (true) {try {if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;} catch (IOException e) {e.printStackTrace();}byteArrayOutputStream.write(buff, 0, rc);}return byteArrayOutputStream.toByteArray();}
}

5.4 对外加入自动配置

在resources中新建META-INF/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.test.file.service.impl.MinIOFileStorageService

5.5 其他微服务使用

第一,minio-demo模块中导入minio-file-starter的依赖

<dependency><groupId>com.test</groupId><artifactId>minio-file-starter</artifactId><version>1.0-SNAPSHOT</version>
</dependency>

第二,在微服务中添加minio所需要的配置

  minio:accessKey: miniosecretKey: minio123bucket: testendpoint: http://192.168.200.130:9000readPath: http://192.168.200.130:9000

第三,在对应使用的业务类中注入FileStorageService,样例如下:

 package com.test.minio.test;import com.test.file.service.FileStorageService;import com.test.minio.MinioApplication;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import java.io.FileInputStream;import java.io.FileNotFoundException;@SpringBootTest(classes = MinioApplication.class)@RunWith(SpringRunner.class)public class MinioTest {@Autowiredprivate FileStorageService fileStorageService;@Testpublic void testUpdateImgFile() {try {FileInputStream fileInputStream = new FileInputStream("E:\\tmp\\ak47.jpg");String filePath = fileStorageService.uploadImgFile("", "ak47.jpg", fileInputStream);System.out.println(filePath);} catch (FileNotFoundException e) {e.printStackTrace();}}}

分布式文件系统MinIO相关推荐

  1. fastdfs 吗 支持windows_从零搭建分布式文件系统MinIO比FastDFS要更合适

    前两天跟大家分享了一篇关于如何利用FastDFS组件来自建分布式文件系统的文章,有兴趣的朋友可以阅读下<用asp.net core结合fastdfs打造分布式文件存储系统>.通过留言发现大 ...

  2. 从零搭建分布式文件系统MinIO比FastDFS要更合适

    前两天跟大家分享了一篇关于如何利用FastDFS组件来自建分布式文件系统的文章,有兴趣的朋友可以阅读下<用asp.net core结合fastdfs打造分布式文件存储系统>.通过留言发现大 ...

  3. fastdfs windows部署_从零搭建分布式文件系统MinIO比FastDFS要更合适

    前两天跟大家分享了一篇关于如何利用FastDFS组件来自建分布式文件系统的文章,有兴趣的朋友可以阅读下<用asp.net core结合fastdfs打造分布式文件存储系统>.通过留言发现大 ...

  4. 分布式文件系统 -- Minio

    Minio是什么? MinIO 是一款高性能.分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件.即X86等低成本机器也能够很好的运行MinIO. MinIO与传统的存储和其他的 ...

  5. 静态化freemarker,分布式文件系统minIO

    前言 #博学谷IT学技术支持# 一.freemarker 1.1freemarker 介绍 ​ FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网 ...

  6. 【Minio】新一代自建文件系统——Minio

    一.前言 说到文件,我们做技术开发,经常会把文件放到文件服务.常用的文件服务我们一般会用自建的,或者是云文件服务.常见的自建文件服务,一般我们会做机器挂载.自建文件服务器:而云文件服务,我们一般会用到 ...

  7. 分布式文件系统选型小记

    分布式文件系统选型小记 Q&A 分布式文件系统是什么? 分布式文件系统(Distributed File System,DFS)是指文件系统管理的物理存储资源不一定直接连接在本地节点上,是通过 ...

  8. 【网课平台】Day3.网关与分布式文件系统

    文章目录 一 .媒资模块环境搭建 1. 网关gateway 2.Nacos 3.搭建gateway 二.分布式文件系统 2.1 文件系统 2.2 分布式文件系统 2.3 MinIO 四.上传图片 4. ...

  9. 2021年大数据Hadoop(七):HDFS分布式文件系统简介

    2021大数据领域优质创作博客,带你从入门到精通,该博客每天更新,逐渐完善大数据各个知识体系的文章,帮助大家更高效学习. 有对大数据感兴趣的可以关注微信公众号:三帮大数据 目录 HDFS分布式文件系统 ...

  10. 分布式文件系统(FastDFS)安装 配置

    [TOC] 百度百科: FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文 ...

最新文章

  1. 腾讯AI种番茄双丰收:参赛AI全胜专家,辽宁试点净利增千元
  2. ROW_NUMBER() OVER()函数用法;(分组,排序),partition by
  3. Unity 游戏开发技巧集锦之创建透明的材质
  4. 360漏洞更新后系统进不去
  5. 【.Net基础02】XML序列化问题
  6. 权威预测:未来一年,企业云服务将会如何发展?
  7. css @语法,@规则 @import @charset @font-face @fontdef @media @page
  8. Pandas 文本数据方法 strip( ) lstrip( ) rstrip( )
  9. inspect python模块_Python inspect模块:仅限关键字参数
  10. 著名线性代数教授 85岁麻省理工学院教授,给2020本科生教授《线性代数入门》
  11. 数字信号处理课程设计---带通滤波器的设计及其matlab实,数字信号处理课程设计---带通滤波器的设计及其MATLAB实现...
  12. 如何安装SQL server2005的查询分析器(绝对原创)
  13. LaTeX:斜线表头的表格制作
  14. 剑指offe题解(二叉树中和为某一值的路径)
  15. python圣斗士修炼(十八):访问mysql数据库
  16. 王者荣耀服务器维护多久12.4,王者荣耀12月4日维护新活动介绍 王者荣耀维护到几点...
  17. RN路由-React Navigation组件5.x-基本原理(中文文档)
  18. 5种RS485切换方向的方法及优劣势分析
  19. 服务端使用c++实现websocket协议解析及通信
  20. 看涨期权和看跌期权的图解

热门文章

  1. python counter怎么用_Counter的基本用法
  2. 安卓系统加速_真就这么简单让你的安卓手机变流畅?
  3. android棒棒糖,Android L正式定名Lollipop(棒棒糖)
  4. ie11找不到java_IE11桌面图标不见了怎么办 IE11桌面图标不见了的两种解决方法
  5. 网店营销忌讳效应:要知道别人不喜欢什么
  6. 多核芯片间的核间通信IPC机制
  7. 计算机检索系统功能,文学多功能计算机自动检索系统研究
  8. sqlserver修改主键id自增
  9. 2010计算机系助学金,计算机系贫困生助学金申请书范文
  10. shell 值判断,大于0,等于0,小于0,大于等于0,小于等于0,不等于0