引入Minio

前置条件

官网:https://www.minio.org.cn/download.shtml#/kubernetes

命令

# 查看系统上的网络连接和监听端口信息
netstat -tpnl
# 检查系统的指定端口占用情况
sudo netstat -tuln | grep 9000

systemctl status firewalld
# 临时关闭
systemctl stop firewalld
# 永久关闭
systemctl disable firewalld

安装

官网有不同系统的下载安装方式

Linux

注意:./是当前目录

# 下载
wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio
# 修改权限
chmod +x minio
# 启动
MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password ./minio server /mnt/data --console-address ":9001"
#也可以下面这样,他会默认用户名和密码
./minio server /mnt/data --console-address ":9001"
  • MINIO_ROOT_USER 指定 MinIO 的用户名;
  • MINIO_ROOT_PASSWORD 指定 MinIO 的密码;
  • /mnt/data 指定 MinIO 服务器用于存储数据的目录;
  • console-address “:9001” 指定 MinIO 控制台的监听地址和端口

后台启动(&结束):./minio server /mnt/data --console-address “:9001” &

docker

# 安装前查看系统是否已经安装了Docker
yum list installed | grep docker
# 卸载Docker  把查出来的都卸载就行了
yum remove docker.x86_64 -y
# 安装    这种方式安装的Docker版本比较旧;(查看版本:docker -v)
yum install docker -y
# 安装最新版的Docker
yum install yum-utils -y
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

安装启动

# 搜索MinIO镜像
docker search minio
# 拉取MinIO镜像
docker pull minio/minio
# 启动MinIO容器  不指定的话默认最新  这个启动命令官网是 podman 改成docker
docker run -p 9000:9000 -p 9001:9001 minio/minio server /data --console-address :9001

没有指定用户名和密码,默认是 minioadmin

  • p (映射端口) 虚拟机 : 容器
  • minio/minio 镜像名
  • server 启动参数
  • /data 数据文件存放的路径
  • console-address :9001 web 访问地址和端口

windows

下载 minio:https://dl.min.io/server/minio/release/windows-amd64/minio.exe

进入到 minio.exe 所在的目录
执行 minio.exe server D:\minio\data 启动 minio 服务,其中 D:\minio\data 是 MinIO 存储数据的目录路径

在浏览器输入:http://localhost:9000/ ,登录 MinIO 服务器 web 管理后台,默认用户名密码都是 minioadmin

springboot 集成

Bucket 是存储 Object 的逻辑空间,每个 Bucket 之间的数据是相互隔离的,对用户而言,相当于存放文件的顶层文件夹;

Object 是存储到 MinIO 的基本对象,对用户而言,相当于文件;

添加依赖

https://min.io/docs/minio/linux/developers/minio-drivers.html#java

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

配置类 MinioClientConfig

@Configuration
public class MinioClientConfig {
	@Bean
	public MinioClient minioClient() {
		return MinioClient.builder()
				.endpoint("http://192.168.64.100:9000")
				.credentials("minioadmin", "minioadmin")
				.build();
	}
}

测试连接

@SpringBootTest
public class TestMain {
	@Autowired
	private MinioClient minioClient;
	@Test
	public void test() {
		System.out.println(minioClient);
	}
}

MinioClient 的常用 API:

  • bucketExists():用于检查指定的存储桶是否存在,返回布尔值,表示存储桶是否存在;

  • makeBucket():用于创建一个新的存储桶(bucket),需要指定存储桶的名称;

  • listBuckets():用于列出用户有权访问的所有存储桶,返回存储桶的列表;

  • removeBucket():用于删除一个已存在的存储桶(bucket),删除失败会抛出异常;

  • putObject():用于上传文件到指定的存储桶;

  • statObject():用于检查指定的对象(文件)的状态;

  • getPresignedObjectUrl():用于生成一个对象(文件)的签名 URL,以便可以通过 HTTP 访问;

  • getObject():用于从指定的存储桶中下载文件;

  • listObjects():用于列出指定存储桶中的所有对象(文件);

  • removeObject():用于删除指定存储桶中的对象,需要指定存储桶名称和对象键;

Buckets 代码实现

@SpringBootTest
public class TestBucket {
	@Autowired
	private MinioClient minioClient;
	@Test
	public void removeBucket() throws Exception {
		// 删除bucket
		minioClient.removeBucket(RemoveBucketArgs.builder().bucket("test").build());
	}
	@Test
	public void listBuckets() throws Exception {
		// 列出所有有权访问的 bucket
		minioClient.listBuckets().forEach(bucket -> {
			System.out.println(bucket.name()+bucket.creationDate());
		});
	}
	@Test
	public void createBucket() throws Exception {
		// 创建bucket
		minioClient.makeBucket(MakeBucketArgs.builder().bucket("test").build());
	}
	@Test
	public void bucketExists() throws Exception {
		boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket("test").build());
		System.out.println("test目录是否存在:"+bucketExists);
	}
	@Test
	public void test() {
		System.out.println(minioClient);
	}
}

Object 代码实现

@SpringBootTest
public class TestObject {
	@Autowired
	private MinioClient minioClient;
	@Test
	public void removeObject() throws Exception {
		//用于删除指定存储桶中的指定对象(文件)
		minioClient.removeObject(RemoveObjectArgs.builder()
				.bucket("test")
				.object("1.jpg")
				.build());
	}
	@Test
	public void listObjects() {
		//用于列出指定存储桶中的所有对象(文件)
		Iterable<Result<Item>> test = minioClient.listObjects(ListObjectsArgs.builder()
				.bucket("test").build());
		test.forEach(result -> {
			try {
				Item item = result.get();
				System.out.println(item.objectName());
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		});
	}
	@Test
	public void getObject() throws Exception {
		//用于从指定的存储桶中下载文件
		GetObjectResponse response = minioClient.getObject(GetObjectArgs.builder()
				.bucket("test")
				.object("1.jpg")
				.build());
		//io.minio.GetObjectResponse@6a5dd083
		System.out.println(response);
		System.out.println(response.transferTo(new FileOutputStream("D:\\Desktop\\projects\\springoot3-vues\\minio\\day01\\src\\main\\resources\\static\\1.jpg")));
	}
	@Test
	public void getPresignedObjectUrl() throws Exception {
		//用于生成一个对象(文件)的签名URL,以便可以通过HTTP访问
		String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
				.bucket("test")
				.expiry(3, TimeUnit.MINUTES)//设置过期时间
				.object("1.jpg").method(Method.GET).build());
		System.out.println("url = " + url);
	}
	@Test
	public void statObject() throws Exception {
		StatObjectResponse test = minioClient.statObject(StatObjectArgs.builder()
				.bucket("test").object("1.jpg").build());
		//用于检查指定的对象(文件)的状态;
		//ObjectStat{bucket=test, object=1.jpg, last-modified=2024-05-10T08:30:35Z, size=1145359}
		System.out.println(test);
	}
	@Test
	public void putObject() throws Exception {
		File file = new File("D:\\Pictures\\0.jpg");
		ObjectWriteResponse test = minioClient.putObject(PutObjectArgs.builder()
				.bucket("test").object("1.jpg")//上传到minio后的文件名
				.stream(new FileInputStream(file), file.length(), -1).build());
		//test = io.minio.ObjectWriteResponse@1815577b
		System.out.println("test = " + test);
		ObjectWriteResponse test1 = minioClient.uploadObject(UploadObjectArgs.builder()
				.bucket("test").object("1.jpg").filename("D:\\Pictures\\0.jpg").build());
	}
}

集群

纠删码模式部署

纠删码(Erasure Code)简称 EC,是一种数据保护方法,也是一种算法;

MinIO 对纠删码模式的算法进行了实现,采用 Reed-Solomon code(简称 RScode)纠错码将对象拆分成 N/2 数据和 N/2 奇偶校验块,Reed Solomon 利用范德蒙矩阵(Vandermonde matrix)、柯西矩阵(Cauchy matrix)的特性来实现;

即将数据拆分为多个数据块和多个校验块,分散存储在不同的磁盘上,即使在部分磁盘损坏或丢失的情况下,也可以通过剩余的数据块和校验块恢复出原始数据;

举个例子,现在有 12 块磁盘,一个对象数据会被分成 6 个数据块、6 个奇偶校验块,你可以损坏或丢失任意 6 块磁盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的磁盘中恢复数据

linux 启动纠删码模式

wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio
# 修改权限
chmod +x minio
# 单机多磁盘的部署   记得执行上行命令 在/usr/local/minio下  /opt/minio/data 数据卷目录
MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password /usr/local/minio/minio server --console-address ":9001" /opt/minio/data/data{1...12}

单机多磁盘的部署,会报错

执行命令:lsblk
lsblk 是 Linux 中的一个命令,用于列出所有可用的块设备(数据存储设备,如硬盘、闪存驱动器)的信息,如设备名称、大小、挂载点等;
执行命令:lsblk
lsblk 是 Linux 中的一个命令,用于列出所有可用的块设备(数据存储设备,如硬盘、闪存驱动器)的信息,如设备名称、大小、挂载点等;


添加一块磁盘,上图是没加磁盘

# 不重启,直接刷新磁盘数据总线,获取新加的磁盘
for host in $(ls /sys/class/scsi_host) ; do echo "- - -" > /sys/class/scsi_host/$host/scan; done

再次执行 lsblk


启动纠删码

MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password /usr/local/minio/minio server --console-address ":9001" /opt/minio/data/data{1...12}

登录 minio 查看

上传一个文件查看数据目录发现每个目录都存了文件

linux 启动纠删码模式-后台启动

# 这样就不能设置用户名和密码了,咱也不知道为啥一会必须设置一会不能设置,默认用户名密码 minioadmin   不知道是不是版本原因
nohup /usr/local/minio/minio server --console-address ":9001" /opt/minio/data/data{1...12} > /opt/minio/data/minio.log 2>&1 &
  • nohup: 这是一个 Unix 命令,用于运行另一个命令在后台,并且忽略挂起(HUP)信号,也就是即使你退出了终端或关闭了会话,该命令也会继续运行;
  • > /opt/minio/data/minio.log: 这部分是将标准输出(stdout)重定向到 /opt/minio/data/minio.log 文件,这意味着 MinIO 服务器的所有正常输出(如启动信息、状态更新等)都会被写入到这个日志文件中;
  • 2>&1: 这部分是将标准错误输出(stderr)重定向到标准输出(stdout),即输出到 /opt/minio/data/minio.log 文件,这样,无论是标准输出还是错误输出,都会被写入到同一个日志文件中;
  • &: 这个符号是在命令的末尾,用于将命令放到后台执行,也就是即使你启动了 MinIO 服务器,你的终端或 shell 会话也不会被阻塞,你可以继续执行其他命令;

docker 启动纠删码模式

docker logs minio

# 这里的密码也不能少于八位 不然容器就会一直处于重启状态(查看日志就会说密码少于八位了)
docker run -d \
-p 9000:9000 \
-p 9001:9001 \
--name=minio \
--restart=always \
-e "MINIO_ROOT_USER=root" \
-e "MINIO_ROOT_PASSWORD=password" \
-v /home/minio/data1:/data1 \
-v /home/minio/data2:/data2 \
-v /home/minio/data3:/data3 \
-v /home/minio/data4:/data4 \
-v /home/minio/data5:/data5 \
-v /home/minio/data6:/data6 \
-v /home/minio/data7:/data7 \
-v /home/minio/data8:/data8 \
--privileged=true \
minio/minio server /data{1...8} \
--console-address ":9000" \
--address ":9001"

上传个文件并使用 tree 命令查看目录 /home/minio
安装 tree:yum install tree

集群部署-Linux

纠删码模式是单机多磁盘方式,如果这台机器宕机了,那么 minio 就不能对外提供服务了
准备 4 台机器;(根据 MinIO 的架构设计,至少需要 4 个节点来构建集群,这是因为在一个 N 节点的分布式 MinIO 集群中,只要有 N/2 节点在线,数据就是安全的,同时,为了确保能够创建新的对象,需要至少有 N/2+1 个节点,因此,对于一个 4 节点的集群,即使有两个节点宕机,集群仍然是可读的,但需要有 3 个节点才能写数据;)

准备四台虚拟机—下面的操作四台都需要执行

192.168.64.100
192.168.64.102
192.168.64.103
192.168.64.104

minio 集群需要独占磁盘块,不能使用 Linux 的 root 磁盘块
都添加一块硬盘去目录看–> linux 启动纠删码模式

# 不重启,直接刷新磁盘数据总线,获取新加的磁盘
for host in $(ls /sys/class/scsi_host) ; do echo "- - -" > /sys/class/scsi_host/$host/scan; done

将添加的磁盘格式化为 xfs 格式:

mkfs.xfs /dev/sdb

将磁盘挂载到 minio 的存储目录:

# 递归创建文件夹 若文件夹不存在
mkdir -p /opt/minio/data
mount /dev/sdb /opt/minio/data

开机自动挂载-Linux

开机自动挂载,不配置自动挂载的话,重启之后需要手动进行挂载
一、修改 /etc 下的 fstab 文件

vim /etc/fstab
source /etc/fstab

在最后一行加入以下内容

/dev/sdb                /opt/minio/data         xfs      defaults       0 0
  • /dev/sdb 是设备的路径。
  • /opt/minio/data 是挂载点。
  • xfs 是文件系统类型。
  • defaults 是一组默认选项。
  • 0 0 是用于文件系统检查的选项。

在这里插入图片描述

注意:不要写错和少写,我没有写文件系统类型和默认选项,重启后进入了紧急模式
二、修改 /etc 下的 rc.local 文件或者 /etc/rc.d 下的 rc.local 文件
这个配置文件会在用户登陆之前读取,这个文件中写入了什么命令,在每次系统启动时都会执行一次。

vim /etc/rc.local
# 加入 mount /dev/sdb /opt/minio/data
# 重新加载 rc.local 文件
source /etc/rc.local

在这里插入图片描述

每台机器上安装好 minio;(安装在 /usr/local/minio 目录下,版本统一)

# 下载
wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio
# 修改权限
chmod +x minio

在四台虚拟机的 /usr/local/minio 下编写 minio.sh 启动脚本

#!/bin/bash
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=password
/usr/local/minio/minio server --config-dir /etc/minio --address :9000 --console-address :9001 \
http://192.168.64.100/opt/minio/data/data1 http://192.168.64.100/opt/minio/data/data2 \
http://192.168.64.100/opt/minio/data/data3 http://192.168.64.100/opt/minio/data/data4 \
http://192.168.64.102/opt/minio/data/data1 http://192.168.64.102/opt/minio/data/data2 \
http://192.168.64.102/opt/minio/data/data3 http://192.168.64.102/opt/minio/data/data4 \
http://192.168.64.103/opt/minio/data/data1 http://192.168.64.103/opt/minio/data/data2 \
http://192.168.64.103/opt/minio/data/data3 http://192.168.64.103/opt/minio/data/data4 \
http://192.168.64.104/opt/minio/data/data1 http://192.168.64.104/opt/minio/data/data2 \
http://192.168.64.104/opt/minio/data/data3 http://192.168.64.104/opt/minio/data/data4 &

给脚本修改权限

 chmod 744 minio.sh

启动脚本

# 如果在 minio 的安装目录下 /usr/local/minio
./minio.sh
# 若不在安装目录下,则写全路径
/usr/local/minio/minio.sh

启动可能会报错


查看防火墙的状态关闭防火墙

systemctl status firewalld
# 临时关闭
systemctl stop firewalld
# 永久关闭
systemctl disable firewalld

脚本加入开机启动-Linux

在 /usr/lib/systemd/system 下编写服务

vim /usr/lib/systemd/system/minio.service

加入以下内容

#固定写法,换一下路径即可
#!/bin/sh
[Unit]
Description=xxx-service
Documentation=https://docs.minio.io/
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
# 脚本的位置
ExecStart=/usr/local/minio/minio.sh
WorkingDirectory=/opt/minio
PrivateTmp=true
[Install]
WantedBy=multi-user.target

添加权限

chmod +x /usr/lib/systemd/system/minio.service

可以一台一台的新建脚本,也可以用下列命令把建好的脚本拷贝给其他机器

# 先ssh连一下目标服务器
ssh 192.168.64.102
# 退出 192.168.64.102
exit
scp -r /usr/lib/systemd/system/minio.service 192.168.64.102:/usr/lib/systemd/system/minio.service

如果 ssh 由于秘钥问题连不上可用下面命令

ssh -o StrictHostKeyChecking=no 192.168.64.100
# 重新连接

启动

#将服务添加到开机自启服务中
systemctl enable minio.service
#系统服务刷新
systemctl daemon-reload
#启动服务
systemctl start minio.service
#查看服务状态
systemctl status minio
#停止服务
systemctl stop minio
#取消开机自启
systemctl disable minio

在这里插入图片描述

集群部署-Docker

看了好多人写的,都没成功,放着吧

Nginx 负载均衡

官网:https://nginx.org/en/download.html

Nginx 下载安装

# 下载 下载到当前目录
wget https://nginx.org/download/nginx-1.26.0.tar.gz
# 安装相关库
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel -y
# 解压
tar -zxvf nginx-1.26.0.tar.gz
# 切换至解压后的nginx主目录
cd nginx-1.26.0/
# 在nginx主目录nginx-1.26.0下执行命令  --prefix是指定nginx安装路径
./configure --prefix=/usr/local/nginx  
# 执行命令进行编译
make
# 执行命令进行安装
make install
# 安装完成建议删除 nginx-1.26.0  nginx 安装在了/usr/local
# 这个删除的是下载解压的文件
rm -rf nginx-1.26.0

Nginx 启动

# -c是指定配置文件
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
# 重启
/usr/local/nginx/sbin/nginx -s reload

Nginx 关闭

# 会将已经进来的请求处理完后再关闭
# 找出nginx的进程号
ps -ef | grep nginx
# QUIT  必须是大写
kill -QUIT 主pid
# 快速关闭会直接关闭,已经进来的请求也不会处理
ps -ef | grep nginx
# TERM 必须是大写
kill -TERM 主pid

Nginx配置检查

# 当修改Nginx配置文件后,可以使用Nginx命令进行配置文件语法检查,用于检查Nginx配置文件是否正确
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf -t

Nginx 修改配置文件

1、在http模块配置upstream

upstream api {
    server  192.168.64.100:9000;
    server  192.168.64.102:9000;
    server  192.168.64.103:9000;
    server  192.168.64.104:9000;
}
upstream webui {
    server  192.168.64.100:9001;
    server  192.168.64.102:9001;
    server  192.168.64.103:9001;
    server  192.168.64.104:9001;
}

2、在server模块里配置

		location / {
            #root   html;
            #index  index.html index.htm;
            proxy_pass http://api;
            proxy_set_header Host $http_host;
            proxy_set_header Server MinIO;
            proxy_set_header Accept-Ranges bytes;
        
        }

再写个server 指定 webui

server {
    listen       50000;
    server_name  localhost;
    location / {
         proxy_pass http://webui;
    }
}

在这里插入图片描述
在这里插入图片描述

测试访问

在地址栏输入:http://192.168.64.100:50000/ 可以正常访问 minio 后台在这里插入图片描述

常见问题

服务器时间不同步

The difference between the request time and the server’s time is too large.
解决:

yum install ntpdate -y
ntpdate pool.ntp.org

上传的文件默认是不能访问的

http://ip:9000/存储桶/文件名

一、后台修改 bucke t 的访问策略

二、代码实现

@Test
	public void createBucket() throws Exception {
		String bucketName = "test1";
		boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
		if (!bucketExists) {
			// 创建bucket
			minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
		}
		//创建的时候设置访问策略  2012-10-17  不能改
		String policyJsonString = "{\n" +
				"    \"Version\": \"2012-10-17\",\n" +
				"    \"Statement\": [\n" +
				"        {\n" +
				"            \"Effect\": \"Allow\",\n" +
				"            \"Principal\": {\"AWS\": [\"*\"]},\n" +
				"            \"Action\": [\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\n" +
				"            \"Resource\": [\"arn:aws:s3:::"+bucketName+"\"]\n" +
				"        },\n" +
				"        {\n" +
				"            \"Effect\": \"Allow\",\n" +
				"            \"Principal\": {\"AWS\": [ \"*\"]},\n" +
				"            \"Action\": [\"s3:DeleteObject\",\"s3:GetObject\", \"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\n" +
				"            \"Resource\": [\"arn:aws:s3:::"+bucketName+"/*\"]\n" +
				"        }\n" +
				"    ]\n" +
				"}";
		minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
						.bucket(bucketName)
						.config(policyJsonString)
				.build());
	}
  • 17
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NestJS是一个基于Node.js的开发框架,它提供了许多有用的功能和工具,其中包括对Minio的支持。Minio是一个开源的对象存储服务器,它兼容Amazon S3 API,可以用于存储和检索大量数据。在NestJS中引入Minio可以通过安装minio-js库来实现。在NestJS中使用Minio需要创建一个MinioService类,该类需要使用minio-js库中的Minio.Client类来连接到Minio服务器。在MinioService类中,可以使用putObject方法将文件上传到Minio服务器。在上传文件之前,需要对已有的文件进行判断是否有相同文件名(或者使用时间戳),如果有重名的文件会对其进行覆盖操作。下面是一个示例代码,用于在NestJS中引入Minio: // minio.service.ts import { Injectable } from "@nestjs/common"; import * as Minio from "minio"; @Injectable() export class MinioService { private readonly minioClient: Minio.Client; constructor() { this.minioClient = new Minio.Client({ // 服务ip endPoint: "192.168.18.24", // 服务端口 port: 9000, useSSL: false, accessKey: "minioadmin", secretKey: "minioadmin", }); } async uploadFile(bucketName: string, objectName: string, stream: Buffer) { const res = await this.minioClient.bucketExists(bucketName); console.log(res); console.log(objectName, stream); await this.minioClient.putObject( bucketName, objectName, stream, function (e) { if (e) { console.log(e); return "error"; } else { // 如果重名也会成功 return "Successfully uploaded the buffer"; } }, ); } } --相关问题--: 1. Minio和Amazon S3有什么区别? 2. NestJS还支持哪些对象存储服务器? 3.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值