MInIO
1 基础
1.1 简介
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、
日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。
1.2 纠删玛
Minio使用纠删码erasure code 和校验和checksum 来保护数据免受硬件故障和无声数据损坏。 即便您丢失一半数量(N/2)的硬盘,您仍然可以恢复数据。
? 纠删码是一种恢复丢失和损坏数据的数学算法, Minio采用Reed-Solomon code将对象拆分成N/2数据和N/2 奇偶校验块。 这就意味着如果是12块盘,一个
对象会被分成6个数据块、6个奇偶校验块,你可以丢失任意6块盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的盘中的数据进行恢复
? 纠删码的工作原理和RAID或者复制不同,像RAID6可以在损失两块盘的情况下不丢数据,而Minio纠删码可以在丢失一半的盘的情况下,仍可以保证数据安
全。 而且Minio纠删码是作用在对象级别,可以一次恢复一个对象,而RAID是作用在卷级别,数据恢复时间很长。 Minio对每个对象单独编码,存储服务一经部
署,通常情况下是不需要更换硬盘或者修复。Minio纠删码的设计目标是为了性能和尽可能的使用硬件加速。
minio server /data1 /data2 /data3 /data4 /data5 /data6 /data7 /data8 /data9 /data10 /data11 /data12
docker run -p 9000:9000 --name minio \
-v /mnt/data1:/data1 \
-v /mnt/data2:/data2 \
-v /mnt/data3:/data3 \
-v /mnt/data4:/data4 \
-v /mnt/data5:/data5 \
-v /mnt/data6:/data6 \
-v /mnt/data7:/data7 \
-v /mnt/data8:/data8 \
minio/minio server /data1 /data2 /data3 /data4 /data5 /data6 /data7 /data8
单点minio需要配置纠删玛磁盘。分布式minio自动引入纠删玛功能
1.3 Minio服务限制
纠删码 (多块硬盘 / 服务)
项目 | 参数 |
---|
最大驱动器数量 | Unlimited | 最小驱动器数量 | Unlimited | 读仲裁 | N / 2 | 写仲裁 | N / 2+1 |
浏览器访问
1.4 MinIO配置指南
MinIO Server config.json (v18) 指南
MinIO server在默认情况下会将所有配置信息存到 ${HOME}/.minio/config.json 文件中。 以下部分提供每个字段的详细说明以及如何自定义它们。一个完整的 config.json 在 这里
配置目录
默认的配置目录是 ${HOME}/.minio ,你可以使用--config-dir 命令行选项重写之。MinIO server在首次启动时会生成一个新的config.json ,里面带有自动生成的访问凭据。
Copyminio server --config-dir /etc/minio /data
证书目录
TLS证书存在${HOME}/.minio/certs 目录下,你需要将证书放在该目录下来启用HTTPS 。如果你是一个乐学上进的好青年,这里有一本免费的秘籍传授一你: 如何使用TLS安全的访问minio.
以下是一个带来TLS证书的MinIO server的目录结构。
Copy$ tree ~/.minio
/home/user1/.minio
├── certs
│ ├── CAs
│ ├── private.key
│ └── public.crt
└── config.json
配置参数
版本
参数 | 类型 | 描述 |
---|
version | string | version 决定了配置文件的格式,任何老版本都会在启动时自动迁移到新版本中。 [请勿手动修改] |
凭据
参数 | 类型 | 描述 |
---|
credential | | 对象存储和Web访问的验证凭据。 | credential.accessKey | string | Access key长度最小是5个字符,你可以通过 MINIO_ACCESS_KEY 环境变量进行修改 | credential.secretKey | string | Secret key长度最小是8个字符,你可以通过MINIO_SECRET_KEY 环境变量进行修改 |
示例:
export MINIO_ACCESS_KEY=admin
export MINIO_SECRET_KEY=password
minio server /data
区域(Region)
参数 | 类型 | 描述 |
---|
region | string | region 描述的是服务器的物理位置,默认是us-east-1 (美国东区1),这也是亚马逊S3的默认区域。你可以通过MINIO_REGION_NAME 环境变量进行修改。如果不了解这块,建议不要随意修改 |
示例:
export MINIO_REGION_NAME="中国华北一区"
minio server /data
浏览器
参数 | 类型 | 描述 |
---|
browser | string | 开启或关闭浏览器访问,默认是开启的,你可以通过MINIO_BROWSER 环境变量进行修改 |
示例:
export MINIO_BROWSER=off
minio server /data
通知
1.5 MinIO多租户
1.5.1 单机部署
要在单台机器上托管多个租户,为每个租户运行一个MinIO server,使用不同的HTTPS端口、配置和数据目录。
示例1:单主机,单磁盘
以下示例在一块磁盘上托管三个租户。
minio --config-dir ~/tenant1 server --address :9001 /data/tenant1
minio --config-dir ~/tenant2 server --address :9002 /data/tenant2
minio --config-dir ~/tenant3 server --address :9003 /data/tenant3
示例2:单主机,多块磁盘 (erasure code)
以下示例在多块磁盘上托管三个租户。
minio --config-dir ~/tenant1 server --address :9001 /disk1/data/tenant1 /disk2/data/tenant1 /disk3/data/tenant1 /disk4/data/tenant1
minio --config-dir ~/tenant2 server --address :9002 /disk1/data/tenant2 /disk2/data/tenant2 /disk3/data/tenant2 /disk4/data/tenant2
minio --config-dir ~/tenant3 server --address :9003 /disk1/data/tenant3 /disk2/data/tenant3 /disk3/data/tenant3 /disk4/data/tenant3
1.5.2 分布式部署
要在分布式环境中托管多个租户,同时运行多个分布式MinIO实例。
示例3 : 多主机,多块磁盘 (erasure code)
以下示例在一个4节点集群中托管三个租户。在4个节点里都执行下列命令:
export MINIO_ACCESS_KEY=<TENANT1_ACCESS_KEY>
export MINIO_SECRET_KEY=<TENANT1_SECRET_KEY>
minio --config-dir ~/tenant1 server --address :9001 http://192.168.10.11/data/tenant1 http://192.168.10.12/data/tenant1 http://192.168.10.13/data/tenant1 http://192.168.10.14/data/tenant1
export MINIO_ACCESS_KEY=<TENANT2_ACCESS_KEY>
export MINIO_SECRET_KEY=<TENANT2_SECRET_KEY>
minio --config-dir ~/tenant2 server --address :9002 http://192.168.10.11/data/tenant2 http://192.168.10.12/data/tenant2 http://192.168.10.13/data/tenant2 http://192.168.10.14/data/tenant2
export MINIO_ACCESS_KEY=<TENANT3_ACCESS_KEY>
export MINIO_SECRET_KEY=<TENANT3_SECRET_KEY>
minio --config-dir ~/tenant3 server --address :9003 http://192.168.10.11/data/tenant3 http://192.168.10.12/data/tenant3 http://192.168.10.13/data/tenant3 http://192.168.10.14/data/tenant3
1.6 磁盘缓存
这里的磁盘缓存功能是指使用缓存磁盘来存储租户常用的一些数据。例如,假设你通过gateway azure 设置访问一个对象并下载下来进行缓存,那接下来的请求
都会直接访问缓存磁盘上的对象,直至其过期失效。此功能允许Minio用户:
- 对象的读取速度性能最佳。
- 任何对象的首字节时间得到显著改善。
使用
1.6.1 前期条件
安装Minio - Minio快速入门。
1.6.2. 运行Minio缓存
磁盘缓存可以通过修改Minio服务的cache 配置来进行开启。配置cache 设置需要指定磁盘路径、缓存过期时间(以天为单位)以及使用通配符方式指定的不需要进行缓存的对象。
"cache": {
"drives": ["/mnt/drive1", "/mnt/drive2", "/mnt/drive3"],
"expiry": 90,
"exclude": ["*.pdf","mybucket/*"]
},
缓存设置也可以通过环境变量设置。设置后,环境变量会覆盖任何cache 配置中的值。下面示例使用/mnt/drive1 , /mnt/drive2 和 /mnt/drive3 来做缓存,
90天失效,并且mybucket 下的所有对象 和 后缀名为.pdf 的对象不做缓存。
export MINIO_CACHE_DRIVES="/mnt/drive1,/mnt/drive2,/mnt/drive3"
export MINIO_CACHE_EXPIRY=90
export MINIO_CACHE_EXCLUDE="*.pdf,mybucket/*"
minio server /export{1...24}
1.6.3. 验证设置是否成功
要验证是否部署成功,你可以通过浏览器来访问刚刚部署的Minio服务。你应该可以看到上传的文件在所有Minio节点上都可以访问。
1.7 MinIO监控指南
MinIO服务器通过端点公开监视数据。监视工具可以从这些端点中选择数据。本文档列出了监视端点和相关文档。
健康检查探针
MinIO服务器具有两个与运行状况检查相关的未经身份验证的端点,一个活动性探针(指示服务器是否工作正常),一个就绪性探针(指示服务器是否由于重负载而未接受连接)。
- 可在以下位置获得活力探针
/minio/health/live - 可在以下位置获得就绪探针 /minio/health/ready
在MinIO healthcheck 指南中阅读有关如何使用这些端点的更多信息。
Prometheus 探测
MinIO服务器在单个端点上公开与Prometheus兼容的数据。默认情况下,对端点进行身份验证。
- Prometheus 数据可在
/minio/prometheus/metrics
要使用此端点,请设置Prometheus以从该端点抓取数据。在如何使用Prometheus监视MinIO服务器中阅读有关如何配置和使用Prometheus监视MinIO服务器的更多信息。
1.8 设置秘钥
MinIO自定义Access和Secret密钥
方式一 秘钥设置到环境变量中
要覆盖MinIO的自动生成的密钥,您可以将Access和Secret密钥设为环境变量
echo -e MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE"\n"MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY >> /etc/profile
source /etc/profile
方式二 自定义秘钥
MinIO允许常规字符串作为Access和Secret密钥。
docker run -p 9000:9000 --name minio1 \
-e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
-v /mnt/data:/data \
-v /mnt/config:/root/.minio \
minio/minio server /data
方式三 使用Docker secrets 设置秘钥
要覆盖MinIO的自动生成的密钥,可以把secret和access秘钥创建成Docker secrets. MinIO允许常规字符串作为Access和Secret密钥。
echo "AKIAIOSFODNN7EXAMPLE" | docker secret create access_key -
echo "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | docker secret create secret_key -
使用docker service 创建MinIO服务,并读取Docker secrets。
docker service create --name="minio-service" --secret="access_key" --secret="secret_key" minio/minio server /data
2 单节点安装
2.1 docker下安装单节点MinIO
先安装docker
2.1.1 docker下载 MinIO镜像
docker中运行镜像,镜像删除,存储的数据也就丢失。所以需要将运行的数据挂载到宿主机一个目录中,以防止存储的数据丢失。
要创建具有永久存储的MinIO容器,您需要将本地持久目录从主机操作系统映射到虚拟配置~/.minio 并导出/data 目录。
docker pull minio/minio
2.1.2 启动
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --zone=public --add-port=9999/tcp --permanent
systemctl restart firewalld
firewall-cmd --list-all
docker run -p 9000:9000 -p 9999:9999 --name minio1 \
-e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
-v /mnt/data:/data \
-v /mnt/config:/root/.minio \
minio/minio server --address '0.0.0.0:9000' --console-address '0.0.0.0:9999' /data
[root@centos1 ~]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a85b1cc8783 minio/minio "/usr/bin/docker-ent…" 3 minutes ago Up 3 minutes 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp minio1
[root@centos1 ~]
2.1.3 浏览器访问
浏览器输入 http://192.168.0.201:9999/ 或者9000端口都会映射到9999端口
账号密码是刚才运行时候的 MINIO_ACCESS_KEY 和 MINIO_SECRET_KEY。
能访问说明minio启动成功
2.2 centos 部署单节点minio
2.2.1 下载
http://dl.minio.org.cn/server/minio/release/linux-amd64/minio
并上传到 /usr/local/src 目录下
2.2.3 运行
firewall-cmd --zone=public --add-port=9000/tcp --permanent
[root@centos9 src]
[root@centos9 src]
总用量 240548
-rw-r--r--. 1 root root 185540433 5月 19 16:01 jdk-linux-x64.tar.gz
-rwxr-xr-x. 1 root root 59715584 7月 18 18:50 minio
-rw-r--r--. 1 root root 1061461 7月 14 15:53 nginx-1.20.1.tar.gz
[root@centos9 src]
No credential environment variables defined. Going with the defaults.
It is strongly recommended to define your own credentials via environment variables MINIO_ROOT_USER and MINIO_ROOT_PASSWORD instead of using default values
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ You are running an older version of MinIO released 4 weeks ago ┃
┃ Update: Run `mc admin update` ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
Endpoint: http://192.168.0.209:9000 http://192.168.0.140:9000 http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin
Browser Access:
http://192.168.0.209:9000 http://192.168.0.140:9000 http://127.0.0.1:9000
Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
$ mc alias set myminio http://192.168.0.209:9000 minioadmin minioadmin
Object API (Amazon S3 compatible):
Go: https://docs.min.io/docs/golang-client-quickstart-guide
Java: https://docs.min.io/docs/java-client-quickstart-guide
Python: https://docs.min.io/docs/python-client-quickstart-guide
JavaScript: https://docs.min.io/docs/javascript-client-quickstart-guide
.NET: https://docs.min.io/docs/dotnet-client-quickstart-guide
Detected default credentials 'minioadmin:minioadmin', please change the credentials immediately by setting 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment values
IAM initialization complete
./minio server --address 0.0.0.0:80 /data
export MINIO_ACCESS_KEY=mozhu
export MINIO_SECRET_KEY=mozhuxianren
./minio server /data/bucket &
./minio server /home/data1 /home/data2 /home/data3 /home/data4
2.2.4 浏览器访问
账号 和密码 是 刚才启动打印出来的默认账号密码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hFZXOsRV-1635167813679)(MInIO.assets/image-20210718221546276.png)]
2.3 java访问单节点MInio
2.3.1 依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.2</version>
</dependency>
</dependencies>
2.3.2 工具类
package com.mozhu.minioutils;
import io.minio.*;
import io.minio.http.Method;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Component
public class MinioUtils {
private static final String MINIO_SERVER_URL = "http://192.168.0.209:9000" ;
private static final String ACCESS_KEY = "minioadmin" ;
private static final String SECRET_KEY = "minioadmin" ;
private static final String BUCKET_NAME = "mybucket" ;
private static MinioClient minioClient;
static {
minioClient =MinioClient.builder().endpoint(MINIO_SERVER_URL).credentials(ACCESS_KEY, SECRET_KEY).build();
try {
boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKET_NAME).build());
if (!found) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET_NAME).build() );
} else {
System.out.println("Bucket "+ BUCKET_NAME +" already exists.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getRandomFileName ( String originalName ,String prefix ) {
if (StringUtils.isBlank(originalName)) {
return null ;
}
String subfix = originalName.substring(originalName.lastIndexOf(".") );
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
if ( StringUtils.isNotBlank(prefix) ) {
return prefix + "/" + uuid + subfix ;
}
return uuid + subfix ;
}
public static String uploadFile ( String originalPath , String prefix ) {
if ( StringUtils.isBlank( originalPath ) ) {
return null ;
}
String fileName = getRandomFileName(originalPath, prefix);
if ( StringUtils.isBlank( fileName ) ) {
return null ;
}
String objectUrl = null ;
try {
UploadObjectArgs objectArgs = UploadObjectArgs.builder().bucket(BUCKET_NAME).object(fileName).filename(originalPath).build();
ObjectWriteResponse uploadObject = minioClient.uploadObject(objectArgs);
objectUrl = minioClient.getPresignedObjectUrl( GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(BUCKET_NAME)
.object(fileName)
.expiry(24, TimeUnit.DAYS)
.build() );
} catch (Exception e) {
e.printStackTrace();
}
return objectUrl ;
}
public static String getFilePath ( String fileName ) {
if ( StringUtils.isBlank(fileName) ) {
return null ;
}
String objectUrl = null;
try {
objectUrl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(BUCKET_NAME)
.object(fileName)
.expiry(7, TimeUnit.DAYS)
.build());
} catch (Exception e) {
e.printStackTrace();
}
return objectUrl ;
}
public static Boolean removeObject ( String objectName ) {
if ( StringUtils.isBlank( objectName ) ) {
return false;
}
try {
minioClient.removeObject( RemoveObjectArgs.builder().bucket(BUCKET_NAME).object( objectName ).build());
return true ;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static void downloadFile (String objectName , String filename ,HttpServletResponse response) {
if ( StringUtils.isBlank(objectName) || response == null) {
return ;
}
if ( StringUtils.isBlank( filename ) ) {
filename = objectName.substring(objectName.lastIndexOf("/") + 1);
}
ServletOutputStream out = null;
try (InputStream inputStream = minioClient.getObject(
GetObjectArgs.builder().bucket(BUCKET_NAME).object(objectName).build())) {
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(),"ISO-8859-1"));
response.addHeader("Content-Length", "" );
response.setContentType("application/force-download");
response.setCharacterEncoding("UTF-8");
out = response.getOutputStream();
byte[] content = new byte[1024];
int length = 0;
while ((length = inputStream.read(content)) != -1) {
out.write(content, 0, length);
}
out.flush();
} catch ( Exception e ) {
e.printStackTrace();
}finally {
if(out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.3.3 controller
package com.mozhu.controller;
import com.mozhu.minioutils.MinioUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/file/")
public class FileController {
@PostMapping("upload")
public String uploadFile ( String path , String prefix) {
String filePath = MinioUtils.uploadFile(path ,prefix );
return filePath;
}
@GetMapping("fileName")
public String getFIleHttpPath ( String fileName ) {
String filePath = MinioUtils.getFilePath(fileName);
return filePath;
}
@PostMapping("removeobject")
public Boolean removeObject ( String fileName ) {
Boolean object = MinioUtils.removeObject(fileName);
return object;
}
@GetMapping("downloadFile")
public void downloadFile (String objectName , String filename , HttpServletResponse response ) {
MinioUtils.downloadFile( objectName ,filename ,response );
}
}
2.3.4 api说明
上传文件
基本信息
- 接口URL:
localhost:9999/file/upload - 请求方式:
POST - Content-Type:
application/x-www-form-urlencoded
请求参数
body参数及说明
参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
---|
path | D:\Backup\Documents\My Pictures\2050532.jpg | string | 是 | 文件全路径 | prefix | images | string | 否 | 文件前缀路径,多级用正斜杠隔开 a/b 路径名称规则遵循linux创建文件夹规则 |
获取文件访问链接
基本信息
- 接口URL:
localhost:9999/file/fileName?fileName=/images/aaa/bbb/ccc/fd9647cde0e643538cd90a3800605578.jpg - 请求方式:
GET - Content-Type:
application/x-www-form-urlencoded
请求参数
Query参数及说明
参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
---|
fileName | /images/aaa/bbb/ccc/fd9647cde0e643538cd90a3800605578.jpg | string | 是 | - |
删除
基本信息
- 接口URL:
localhost:9999/file/removeobject - 请求方式:
POST - Content-Type:
application/x-www-form-urlencoded
请求参数
body参数及说明
参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
---|
fileName | images/aaa/bbb/ccc/fd9647cde0e643538cd90a3800605578.jpg | string | 是 | - |
下载文件
基本信息
- 接口URL:
localhost:9999/file/downloadFile?objectName=/images/aaa/bbb/ccc/d17bba31b3ad49638842b612f87a5fe8.jpg&filename=123.jpg - 请求方式:
GET - Content-Type:
application/x-www-form-urlencoded
请求参数
Query参数及说明
参数名 | 示例值 | 参数类型 | 是否必填 | 参数描述 |
---|
objectName | /images/aaa/bbb/ccc/d17bba31b3ad49638842b612f87a5fe8.jpg | string | 是 | 远程地址文件 桶后面的的路径 | filename | 123.jpg | string | 是 | 下载本地文件名 |
3 分布式运行
3.1 准备
分布式Minio可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式Minio避免了单点故障。
在大数据领域,通常的设计理念都是无中心和分布式。Minio分布式模式可以帮助你搭建一个高可用的对象存储服务,你可以使用这些存储设备,而不用考虑其真实物理位置。
数据保护
分布式Minio采用 纠删码来防范多个节点宕机和位衰减bit rot 。
分布式Minio至少需要4个硬盘,使用分布式Minio自动引入了纠删码功能。
单机Minio服务存在单点故障,相反,如果是一个有N块硬盘的分布式Minio,只要有N/2硬盘在线,你的数据就是安全的。不过你需要至少有N/2+1个硬盘来进行写操作。
例如,一个16节点的Minio集群,每个节点16块硬盘,就算8台服務器宕机,这个集群仍然是可读的,不过你需要9台服務器才能写数据。
注意,只要遵守分布式Minio的限制,你可以组合不同的节点和每个节点几块硬盘。比如,你可以使用2个节点,每个节点4块硬盘,也可以使用4个节点,每个节点两块硬盘,诸如此类。
一致性
Minio在分布式和单机模式下,所有读写操作都严格遵守read-after-write一致性模型。
注意:
- 分布式Minio里所有的节点需要有同样的access秘钥和secret秘钥,这样这些节点才能建立联接。为了实现这个,你需要在执行minio server命令之前,先将access秘钥和secret秘钥export成环境变量。
- 分布式Minio使用的磁盘里必须是干净的,里面没有数据。
- 下面示例里的IP仅供示例参考,你需要改成你真实用到的IP和文件夹路径。
- 分布式Minio里的节点时间差不能超过3秒,你可以使用NTP 来保证时间一致。
- 在Windows下运行分布式Minio处于实验阶段,请悠着点使用。
四台服务器 部署 minio
一台服务器安装 nginx
架构如下:
3.2 安装minio
3.2.1 给四台服务器都执行下列命令
firewall-cmd --zone=public --add-port=9000/tcp --permanent
systemctl restart firewalld
[root@centos8 ~]
chmod +x minio
mkdir -p /opt/minio/data
cd /opt/minio/
chmod 777 /opt/minio/data/
export MINIO_ACCESS_KEY=mozhu
export MINIO_SECRET_KEY=mozhuxianren
/usr/local/minio server http://192.168.0.205/opt/minio/data http://192.168.0.206/opt/minio/data \
http://192.168.0.207/opt/minio/data http://192.168.0.208/opt/minio/data
3.2.2 安装nginx
链接 192.168.0.209
yum install -y centos-release-scl scl-utils-build
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
scl enable devtoolset-9 bash
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel
tar -zxvf nginx-1.20.1.tar.gz
cd nginx-1.20.1
./configure
make
make install
cd /usr/local/nginx/conf/
upstream backend {
192.168.0.205:9000 ;
192.168.0.206:9000 ;
192.168.0.207:9000 ;
192.168.0.208:9000 ;
}
server {
listen 9000;
server_name localhost;
location /{
proxy_pass http://backend ;
proxy_set_header Host $http_host;
}
}
[root@centos9 conf]
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@centos9 conf]
[root@centos9 conf]
3.3.3 Java测试
用上面的单节点java代码测试
初始化修改一下常量
private static final String MINIO_SERVER_URL = "http://192.168.0.209:9000" ;
private static final String ACCESS_KEY = "mozhu" ;
private static final String SECRET_KEY = "mozhuxianren" ;
上传图片成功,浏览器访问返回图片链接成功。
|