【minio学习笔记】

minio学习笔记

  • 一、Minio相关介绍
    • 1、相关网址
    • 2、Minio介绍
    • 3、Minio基础概念
    • 4、纠删码EC(Erasure Code)
    • 5、存储方案
  • 二、环境搭建
    • 1、单机部署介绍
      • 1.1 概念
      • 1.2 2单机部署(无纠删码模式)
      • 1.3 使用Docker单机部署(无纠删码模式)
      • 1.4 使用Docker单机部署(纠删码模式)
    • 2、分布式集群部署介绍
      • 2.1 分布式集群概念
      • 2.2 分布式集群部署
  • 三、Minio客户端使用
    • 1、mc的使用
      • 1.1 下载客户端mc:
      • 1.2 配置mc:
      • 1.3 命令汇总
      • 1.4 命令演示:
    • 2、Bucket管理:
    • 3、mc admin使用
  • 四、Minio Java Client使用
    • 1、文件上传
    • 2、文件下载
    • 3、Spring Boot整合minio
      • 3.1 新建配置类MinioConfig
      • 3.2下载功能代码
      • 3.3上传功能代码
      • 3.4删除功能代码

一、Minio相关介绍

1、相关网址

官网:https://min.io/
中文:http://www.minio.org.cn
官方文档:https://docs.min.io/docs
中文文档(滞后):http://docs.minio.org.cn/docs
官方demo:https://github.com/minio/minio-java

2、Minio介绍

(1)Minlo是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
(2)MinlO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似NodeJS,Redis或者MySQL.
(3)优点:
1)部署简单:一个single二进制文件即是一切,还可支持各种平台。
2)minio支持海量存储,可按zone扩展(原zone不受任何影响),支持单个对象最大5TB;
兼容Amazon S3接口,充分考虑开发人员的需求和体验;
3)低冗余且磁盘损坏高容忍,标准且最高的数据冗余系数为2(即存储一个1M的数据对象,实际占用磁盘空间为2M)。但在任意n/2块disk损坏的情况下依然可以读出数据(n为一个纠删码集合(Erasure Coding Set)中的disk数量)。并且这种损坏恢复是基于单个对象的,而不是基于整个存储卷的。
4)读写性能优异

3、Minio基础概念

(1)Object: 存储到Minio的基本对象,如文件、字节流,Anything…
(2)Bucket: 来存储Object的逻辑空间。每个Bucket之间的数据是相互隔离的。对于客户端而言,就相当于一个存放文件的顶文件夹。
(3)Drive: 即存储数据的磁盘,在MinlO启动时,以参数的方式传入。Minio 中所有的对象数据都会存储在Drive里。
(4)Set: 即一组Drive的集合,分布式部署根据集群规模自动划分一个或多个Set,每个Set中的Drive分布在不同位置。一个对象存储在一个Set上。(For example: {1…64} is divided into 4 sets each of size 16.)
1)一个对象存储在一个Set上
2)一个集群划分为多个Set
3)一个Set包含的Drive数量是固定的,默认由系统根据集群规模自动计算得出
4)一个SET中的Drive尽可能分布在不同的节点上

4、纠删码EC(Erasure Code)

MinlO使用纠删码机制来保证高可靠性,使用highwayhash来处理数据损坏( Bit Rot Protection)。关于纠删码,简单来说就是可以通过数学计算,把丢失的数据进行还原,它可以将n份原始数据,增加m份数据,并能通过n+m份中的任意n份数据,还原为原始数据。
即如果有任意小于等于m份的数据失效,仍然能通过剩下的数据还原出来。

5、存储方案

【minio学习笔记】_第1张图片

二、环境搭建

1、单机部署介绍

1.1 概念

(1)minio server的standalone模式,即要管理的磁盘都在host本地。该启动模式一般仅用于实验环境、 测试环境的验证和学习使用。在standalone模式下,还可以分为non-erasure code mode(无纠删码模式)和erasure code mode(纠删码模式)。
(2)non-erasure code mode
在此启动模式下,对于每一份对象数据, minio直接在data 下面存储这份数据,不会建立副本,也不会启用纠删码机制。因此,这种模式无论是服务实例还是磁盘都是“单点”,无任何高可用保障,磁盘损坏就表示数据丢失。
(3)erasure code mode
此模式为minio server实例传入多个本地磁盘参数。一旦遇到多于一个磁盘参数,minio server会自动启用erasure code mode.
erasure code对磁盘的个数是有要求的,如不满足要求,实例启动将失败。erasure code启后,要求传给minio server的endpoint(standalone模式下,即本地磁盘上的目录)至少为4个

1.2 2单机部署(无纠删码模式)

(1)基于ceentos7
使用以下命令在运行 64 位 Intel/AMD 架构的 Linux 主机上运行独立的 MinIO 服务器。将/data 替换为您希望 MinIO 存储数据的驱动器或目录的路径。

# 下载minio执行文件
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
# 启动,注意这个每次启动的端口号都会改变,可以进行固定,还可以对用户名和密码进行固定
./minio server /mnt/miniodata

(2)指定端口以及用户密码启动:

# 注意,密码要大于等于8位!!
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
# 更改配置文件默认路径 (可以不进行修改)
./minio server --config-dir /mnt/config /mnt/data
# 指定端口号(默认是随机的)
./minio server --console-address ":50000" /mnt/miniodata

(3)开启服务器防火墙端口号(不开启,本机访问不了该端口)

# 配置防火墙开放9000端口
firewall-cmd --zone=public --add-port=9000/tcp --permanent
# 更新防火墙配置
firewall-cmd --reload
# 查看已经开放的端口号
firewall-cmd --zone=public --list-ports

(4)通过url访问,如图所示
【minio学习笔记】_第2张图片
(4)通过URL地址对文件进行访问
例如图片或视频资源等,在上传到minio服务器之后。
可以通过 http://ip:port/桶名/文件名 的形式访问。
例如:http://8.142.121.122:9000/avatars/123456789.jpg
注意:使用URL访问前,一定要把该桶的访问权限改成public.

1.3 使用Docker单机部署(无纠删码模式)

(1)首先拉取minio/minio

docker pull minio/minio

(2)使用docker启动

docker run -d -p 9000:9000 -p 50000:50000 --name minio \
  -e "MINIO_ROOT_USER=admin" \
  -e "MINIO_ROOT_PASSWORD=12345678" \
  -v /mnt/miniodata:/data \
  -v /mnt/minioconfig:/root/.minio \
  minio/minio server --console-address ":50000" /data

(3)注意:中文文档过期,要以英文文档进行配置

1.4 使用Docker单机部署(纠删码模式)

(1)Minio使用纠删码erasure code和校验和checksum来保护数据免受硬件故障和无声数据损坏。即便您丢失一半数量(N/2)的硬盘,您仍然可以恢复数据。

纠删码是一种恢复丢失和损坏数据的数学算法,Minio采用Reed-Solomon code将对象拆分成N/2数据和N/2奇偶校验块。这就意味着如果是8块盘,一个对象会被分成8个数据块、8个奇偶校验块,你可以丢失任意6块盘〈不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的盘中的数据进行恢复。

(2)使用Minio Docker镜像,在八块盘中启动Minio服务

docker run -d -p 9000:9000 -p 50000:50000 --name minioec \
  -e "MINIO_ROOT_USER=admin" \
  -e "MINIO_ROOT_PASSWORD=12345678" \
  -v /mnt/miniodataec/data1:/data1 \
  -v /mnt/miniodataec/data2:/data2 \
  -v /mnt/miniodataec/data3:/data3 \
  -v /mnt/miniodataec/data4:/data4 \
  -v /mnt/miniodataec/data5:/data5 \
  -v /mnt/miniodataec/data6:/data6 \
  -v /mnt/miniodataec/data7:/data7 \
  -v /mnt/miniodataec/data8:/data8 \
  minio/minio server /data{1...8} --console-address ":50000"

2、分布式集群部署介绍

2.1 分布式集群概念

(1)分布式Minio可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式Minio避免了单点故障。

(2)分布式存储可靠性常用方法:
分布式存储,很关键的点在于数据的可靠性,即保证数据的完整,不丢失,不损坏。只有在可靠性实现的前提下,才有了追求一致性、高可用、高性能的基础。而对于在存储领域,一般对于保证数据可靠性的方法主要有两类, 一类是冗余法,一类是校验法 。
冗余
冗余法最简单直接,即对存储的数据进行副本备份,当数据出现丢失,损坏,即可使用备份内容进行恢复,而副本备份的多少,决定了数据可靠性的高低。这其中会有成本的考量,副本数据越多,数据越可靠,但需要的设备就越多,成本就越高。可靠性是允许丢失其中份数据。当前已有很多分布式系统是采用此种方式实现,如Hadoop的文件系统(3个副本),Redis的集群,MySQL的主备模式等。
校验
校验法即通过校验码的数学计算的方式,对出现丢失、损坏的数据进行校验、还原。注意,这里有两个作用,一个校验,通过对数据进行校验和( checksum )进行计算,可以检查数据是否完整,有无损坏或更改,在数据传输和保存时经常用到,如TCP协议;二是恢复还原,通过对数据结合校验码,通过数学计算,还原丢失或损坏的数据,可以在保证数据可靠的前提下,降低冗余,如单机硬盘存储中的RAID技术,纠删码(Erasure Code)技术等。MinlO采用的就是纠删码技术。

(3)分布式Minio优势
1)数据保护
分布式Minio采用纠删码来防范多个节点宕机和位衰减bit rot 。
分布式Minio至少需要4个硬盘,使用分布式Minio自动引入了纠删码功能。
2)高可用
单机Minio服务存在单点故障,相反,如果是一个有N块硬盘的分布式Minio,只要有N/2硬盘在线,你的数据就是安全的。不过你需要至少有N/2+1个硬盘来创建新的对象。
例如,一个16节点的Minio集群,每个节点16块硬盘,就算8台服务器宕机,这个集群仍然是可读的,不过你需要9台服务器才能写数据。
3)一致性
Minio在分布式和单机模式下,所有读写操作都严格遵守read-after-write一致性模型。
运行分布式Minio

2.2 分布式集群部署

(1)启动一个分布式Minio实例,只需要把硬盘位置做为参数传给minio server命令即可,然后,你需要在所有其它节点运行同样的命令。
1)分布式Minio里所有的节点需要有同样的access秘钥和secret秘钥,这样这些节点才能建立连接。为了实现这个,你需要在执行minio server命令之前,先将access秘钥和secret秘钥export成环境变量。新版本使用MINIO_ROOT_USER和MINIO_ROOT_PASSWORD。
2)分布式Minio使用的磁盘里必须是干净的,里面没有数据。
3)分布式Minio里的节点时间差 不能超过3秒 ,可以使用 NTP 来保证时间一致。
(2)启动分布式Minio实例,8个节点,每个节点1块盘,需要在8个节点上都运行下面命令。
该模块没有深入去写,目前了解即可。

export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
minio server http://192.168.244.131/export1 http://192.168.244.132/export2 \
			http://192.168.244.133/export3 http://192.168.244.134/export4 \
			http://192.168.244.135/export5 http://192.168.244.136/export6 \
			http://192.168.244.137/export7 http://192.168.244.138/export8

三、Minio客户端使用

1、mc的使用

MinIO Client(mc)为ls,cat,cp,mirror,diff,find等UNIX命令提供了一种替代方案。它支持文件系统和兼容Amazon S3的云存储服务(AWS Signature v2和v4)。

1.1 下载客户端mc:

wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
./mc --help
# 可以添加到sbin下,以后该命令可以直接使用
mv mc /usr/local/sbin

1.2 配置mc:

将所有的配置信息都存储在~/.mc/config.json中

# 查询mc host配置
mc config host ls
# 添加minio服务(重要)
mc config host add 服务名字 http://ip:port username password
mc config host add minio-server http://128.128.7.254:9000 admin 12345678
# 删除host
mc config host remove minio-server

注意: 我在做这一步时,mc始终连不上minio服务器,是因为没有配置用户及密码。通过浏览器的console界面配置一个admin用户及赋予相应权限即可。

1.3 命令汇总

ls		# 列出文件和文件夹。
mb		# 创建一个存储桶或一个文件夹。
cat		# 显示文件和对象内容。
pipe	# 将一个STDIN重定向到一个对象或者文件或者STDOUT。
share	# 生成用于共享的URL。
cp		# 拷贝文件和对象。
mirror	# 给存储桶和文件夹做镜像。
find	# 基于参数查找文件。
diff	# 对两个文件夹或者存储桶比较差异。
rm		# 删除文件和对象。
events	# 管理对象通知。
watch	# 监视文件和对象的事件。
policy	# 管理访问策略。
config	# 管理mc配置文件。
update	# 检查软件更新。
version	# 输出版本信息。

1.4 命令演示:

# 下载文件
mc cp minio-server/test1/7.jpg /mnt/data/
# 删除文件
mc rm minio-server/test1/03.jpg
# 上传文件
mc cp /mnt/data/7.jpg minio-server/test1/ 

2、Bucket管理:

# 创建bucket
mc mb minio-server/bucket01
# 删除bucket
mc rb minio-server/bucket01
# bucket不为空,可以强制删除 (慎用)
mc rb --force minio-server/bucket01

3、mc admin使用

(1)MinIO Client(mc)提供了“ admin”子命令来对您的MinIO部署执行管理任务。

service		# 服务重启并停止所有MinIO服务器
update      # 更新更新所有MinIO服务器
info        # 信息显示MinIO服务器信息
user        # 用户管理用户
group       # 小组管理小组
policy      # MinIO服务器中定义的策略管理策略
config      # 配置管理MinIO服务器配置
heal        # 修复MinIO服务器上的磁盘,存储桶和对象
profile     # 概要文件生成概要文件数据以进行调试
top         # 顶部提供MinIO的顶部统计信息
trace       # 跟踪显示MinIO服务器的http跟踪
console     # 控制台显示MinIO服务器的控制台日志
prometheus  # Prometheus管理Prometheus配置
kms         # kms执行KMS管理操作

(2)用户管理:(重要)

mc admin user --help
# 新建用户
mc admin user add minio-server huige
mc admin user add minio-server huige02 12345678
# 查看用户信息
mc admin user list minio-server
# 禁用用户
mc admin user disable minio-server huige
# 启用用户
mc admin user enable minio-server huige
# 删除用户
mc admin user remove minio-server huige

(3)策略管理(重要)
有了用户之后,还要有权限才能访问 policy,查看策略的相关命令

mc admin policy --help
# 列出MinIO上所有的固定策略,主要有consoleAdmin、diagnostics、readonly、readwrite、writeonly 
mc admin policy list minio-server
# 查看pllicy信息
mc admin policy info minio-server readonly

(4)添加新的策略
编写策略文件:/mnt/minio-user-policy-json/minio-huige.json

{
  "Version": "2012-10-17",
  "Statement": [
   {
    "Effect": "Allow",
    "Action": [
    "s3:GetBucketLocation",
    "s3:GetObject"
    ],
    "Resource":[
		"arn:aws:s3:::huige"
	]
   },{
    "Effect": "Allow",
    "Action": [
     "s3:*"
    ],
    "Resource": [
     "arn:aws:s3:::huige/*"
    ]
   }
  ]
}

(5)将minio-huige.json添加到策略数据库

mc admin policy add 服务名 策略名 json文件
# 举例:
mc admin policy add minio-server lwp-admin /mnt/minio-user-policy-json/minio-huige.json
# 可以进行查看,添加成功没
mc admin policy list minio-server
# 设置用户的访问策略
mc admin policy set minio-server huige-admin user=lwp

四、Minio Java Client使用

官方demo:https://github.com/minio/minio-java
官方文档:https://docs.min.io/docs/java-client-api-reference.html
引入依赖:



    io.minio
    minio
    8.3.0



    me.tongfei
    progressbar
    0.5.3



    com.squareup.okhttp3
    okhttp
    4.8.1

1、文件上传

具体写代码,进入github的官方demo或者官方文档,找到相应功能的代码即可。
如下是文件上传的代码举例:

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("https://192.168.244.131:9000")
              .credentials("admin", "12345678")
              .build();

      // 看桶存在不存在
      boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("桶名").build());
      if (!found) {
        // 不存在则创建一个该桶名的桶
        minioClient.makeBucket(MakeBucketArgs.builder().bucket("桶名").build());
      } 

      // 上传
      minioClient.uploadObject(
          UploadObjectArgs.builder()
              .bucket("桶名")
              .object("桶内对象名")
              .filename("/home/user/Photos/asiaphotos.zip(文件本地磁盘的地址)")
              .build());
     
    } catch (MinioException e) {
      System.out.println("Error occurred: " + e);
      System.out.println("HTTP trace: " + e.httpTrace());
    }
  }
}

2、文件下载

本部分仍为举例,具体其他功能请参考官网文档或者官方demo。

import io.minio.DownloadObjectArgs;
import io.minio.MinioClient;
import io.minio.ServerSideEncryptionCustomerKey;
import io.minio.errors.MinioException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;

public class DownloadObject {
  /** MinioClient.getObject() example. */
  public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
    try {
      MinioClient minioClient =
          MinioClient.builder()
              .endpoint("https://192.168.244.131:9000")
              .credentials("admin", "12345678")
              .build();

      /* Amazon S3: */
      // MinioClient minioClient =
      //     MinioClient.builder()
      //         .endpoint("https://s3.amazonaws.com")
      //         .credentials("YOUR-ACCESSKEY", "YOUR-SECRETACCESSKEY")
      //         .build();

		// (1)不加密的方式下载:
      {
        minioClient.downloadObject(
            DownloadObjectArgs.builder()
                .bucket("my-bucketname")
                .object("my-objectname")
                .filename("my-filename(到哪里)")
                .build());
      }
		// (2)加密的方式下载:
      {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256);
        ServerSideEncryptionCustomerKey ssec = new ServerSideEncryptionCustomerKey(keyGen.generateKey());

        minioClient.downloadObject(
            DownloadObjectArgs.builder()
                .bucket("my-bucketname")
                .object("my-objectname")
                .filename("my-filename")
                .ssec(ssec) // Replace with same SSE-C used at the time of upload.
                .build());
        }
        
    } catch (MinioException e) {
      System.out.println("Error occurred: " + e);
    }
  }
}

3、Spring Boot整合minio

3.1 新建配置类MinioConfig

(1)新建MinioConfig类

@Configuration
public class MinioConfig{
	// 这个部分可以用属性配置类去做,看下面(1)(2)两个部分代码就懂了
	@Autowired
	private MinioProperties minioProperties;

	@Bean
	public MinioClient minioClient(){
		 MinioClient minioClient = MinioClient.builder()
              .endpoint(minioProperties.getEndpoint())
              .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
              .build();
          return minioClient;
	}
}

(2)其中MinioProperties由yml统一管理。
新建一个类MinioProperties

@Data
@Component
@ConfigurationProperties(prefix="minio")
public class MinioProperties{
	private String endpoint;
	private String accessKey;
	private String secretKey;
}

(3)最后在yml配置文件中这么写:

minio:
  endpoint: http://192.168.244.131:9000
  accessKey: admin
  secretKey: 12345678

3.2下载功能代码

@RequestMapping("/download/{fileName}")
public void download(HttpServletResponse response, @PathVariable("fileName") String fileName){
	InputStream in = null;
	try={
		// 获取对象信息
		StatObjectResponse stat = minioClient.statObject(
			StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
		response.setContentType(stat.contentType());
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
		// 文件下载
		in = minioClient.getObject(
				GetObjectArgs.builder()
					.bucket(bucketName)
					.object(fileName)
					.build());
		IOUtils.copy(in, response.getOutputStream());
	}catch (Exception e) {
      System.out.println("Error occurred: " + e);
    }finally{
		if(in!=null){
			try{
				in.close();
			}catch(Exception e){
				log.error(e.getMessage());
			}
		}
	}
}

3.3上传功能代码

@PostMapping("/upload")
public Res delete(@RequestParam(name="file", required=false) MultipartFile[] file){
	if(file==null || file.length == 0){
		return Res.error("上传文件不能为空");
	}
	
	List orgfileNameList = new ArrayList<>(file.length);

	for(MultipartFile multipartFile : file){
		String orgfileName = multipartFile.getOriginalFilename();
		orgfileNameList.add(orgfileName);
		try{
			// 文件上传
			InputStream in = multipartFile.getInputStream();
			minioClient.putObject(
            	PutObjectArgs.builder().bucket(bucketName).object(orgfileName).stream(
                    in, multipartFile.getSize(), -1)
                .contentType(multipartFile.getContentType())
                .build());
            in.close();
		}catch(Exception e){
			log.error(e.getMessage());
			return Res.error("上传失败");
		}
	}
}

3.4删除功能代码

@RequestMapping("/delete/{fileName}")
public Res delete(@PathVariable("fileName") String fileName){
	try{
		minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());
	}catch(Exception e){
		log.error(e.getMessage());
		return Res.error("删除失败");
	}
	return Res.ok("删除成功");
}

你可能感兴趣的:(技术类,学习,java,开发语言)