一、Minio介绍
MinIO
基于Apache License 2.0开源协议的对象存储服务。它兼容Amazon S3云存储接口。适合存储非结构化数据,如图片,音频,视频,日志等。对象文件最大可以达到5TB
官网:
https://min.io/
中文
http://minio.org.cn/
1、Minio基础概念
- Object:存储到Minio的基本对象,如文件字节流,Anything
- Bucket:用来存储Object的逻辑空间。每个Bucket之间的数据是相互隔离的。对于客户端而言,就相当于一个存放文件的顶层文件夹。
- Drive:即存储数据的磁盘,在MinlO启动时,以参数的方式传入。Minio中所有的对象数据都会存储在Drive里
-
Set:即-组Drive的集合,分布式部署根据集群规模自动划分一个或多个Set,每个Set中的Drive分布在不同位置。一个对象存
储在一个Set上。(For example:{1…64} is divided into 4sets each of size16)
- 一个对象存储在一个Set上
- 一个集群划分为多个Set
- 一个Set包含的Drive数量是固定的,默认由系统根据集群规模自动计算得出
- 一个SET中的Drive尽可能分布在不同的节点上
1.1 纠删码
MiniO 使用纠删码机制来保证高可靠性,使用highwayhash来处理数据损坏(Bit Rot Protection)。关于纠删码,简单来说就是可以通过数学计算,把丢失的数据进行还原,它可以将n份原始数据,增加m份数据,并能通过n+m份中的任意n份数据,还原为原始数据。即如果有任意小于等于m份的数据失效,仍然能通过剩下的数据还原出来。
1.2 存储形式
文件对象上传到Minio,会在对应的数据存储磁盘中,以Bucket名称为目录,文件名称为下一级目录,文件下是part.1(超过10M时候才会有此文件)和xl.meta,前者是编码数据块以及检验块,后者是元数据文件
1.3 存储方案
二、Minio环境搭建
1、单机部署
基于Centos7
安装路径 /usr/local/soft
wget https://dl.min.io/server/minio/release/darwin-amd64/minio
chmod +x minio
./minio server /mnt/data
访问
http://192.168.150.129:41922
用户名密码:minioadmin
发现图中有警告:
WARNING: Console endpoint is listening on a dynamic port (41922), please use –console-address “:PORT” to choose a static port.
目前启动的时候端口是动态的,只要在启动命令后加上 –console-address “:PORT” ,就变成静态端口
再次启动
./minio server /mnt/data –console-address “:9001”
图中还有警告:
WARNING: Detected default credentials ‘minioadmin:minioadmin’, we recommend that you change these values with ‘MINIO_ROOT_USER’ and ‘MINIO_ROOT_PASSWORD’ environment variables
意思是我们在启动的时候可以通过
MINIO_ROOT_USER
和
MINIO_ROOT_PASSWORD
设置用户密码访问
完整启动命令:
MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=12345678 ./minio server /mnt/data --console-address ":9001"
访问
http://192.168.150.129:9001
账号:admin 密码:12345678
基于docker部署
安装docker命令(如果已经安装就跳过此步骤)
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce
启动docker
systemctl start docker
部署命令以及自定义用户名密码
docker run -d -p 9000:9000 -p 9001:9001 --name minio \
-e "MINIO_ROOT_USER=admin" \
-e "MINIO_ROOT_PASSWORD=12345678" \
-v /mnt/data:/data \
-v /mnt/config:/root/.minio \
minio/minio server /data --console-address ":9001"
获取容器ID
在容器中使用Docker命令, 你需要知道这个容器的
容器ID
。 为了获取
Container ID
, 运行
docker ps -a
-a
flag 确保你获取所有的容器(创建的,正在运行的,退出的),然后从输出中识别
Container ID
。
启动和停止容器
启动容器,你可以使用
docker start
命令。
docker start <container_id>
停止一下正在运行的容器, 使用
docker stop
命令。
docker stop <container_id>
MinIO容器日志
获取MinIO日志,使用
docker logs
命令。
docker logs <container_id>
监控MinioDocker容器
监控MinIO容器使用的资源,使用
docker stats
命令.
docker stats <container_id>
minio纠删码模式
Minio使用纠删码
erasure code
和校验和
checksum
来保护数据免受硬件故障和无声数据损坏。 即便您丢失一半数量(N/2)的硬盘,您仍然可以恢复数据。
纠删码是一种恢复丢失和损坏数据的数学算法, Minio采用Reed-Solomon code将对象拆分成N/2数据和N/2 奇偶校验块。 这就意味着如果是12块盘,一个对象会被分成6个数据块、6个奇
偶校验块,你可以丢失任意6块盘(不管其是存放的数据块还是奇偶校验块)
docker run -d -p 9000:9000 -p 9001:9001 --name minio-ec \
-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 /data{1...8} --console-address ":9001"
2、分布式集群部署
分布式Minio可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式Minio避免了单点故障。
分布式存储可靠性常用方法
分布式存储,很关键的点在于数据的可靠性,即保证数据的完整,不丢失,不损坏。只有在可靠性实现的前提下,才有了追求一致性、高可用、高性能的基础。而对于在存储领域,一般对于保证数据可靠性的方法主要有两类,一类是冗余法,一类是校验法。
冗余
冗余法最简单直接,即对存储的数据进行副本备份,当数据出现丢失,损坏,即可使用备份内容进行恢复,而副本备份的多少,决定了数据可靠性的高低。这其中会有成本的考量,副本数据越多,数据越可靠,但需要的设备就越多,成本就越高。可靠性是允许丢失其中-份数据。当前已有很多分布式系统是采用此种方式实现,如Hadoop的文件系统(3个副本),Redis的集群,MvSOL的主备模式等。
校险
校验法即通过校验码的数学计算的方式,对出现丢失、损坏的数据进行校验,还原。注意,这里有两个作用,一个校验,通过对数据进行校验和(checksum)进行计算,可以检查数据是否完整,有无损坏或更改,在数据传输和保存时经常用到,如TCP协议:二是恢复还原通过对数据结合校验码,通过数学计算,还原丢失或损坏的数据,可以在保证数据可章的前提下,降低冗余,如单机硬盘存储中的RAID技术,纠删码(ErasureCode)技术等。Minlo采用的就是纠删码技术。
分布式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
启动一个分布式Minio实例,你只需要把硬盘位置做为参数传给minio server命令即可,然后,你需要在所有其它节点运行同样的命令。
-
所有运行分布式 MinIO 的节点都应该共享一个共同的根凭证,以便节点相互连接和信任。为此,
建议
在执行 MinIO 服务器命令之前,将 root 用户和 root 密码导出为环境变量,
MINIO_ROOT_USER
并在所有节点上导出。
MINIO_ROOT_PASSWORD
如果未导出,
minioadmin/minioadmin
则应使用默认凭据。 -
MinIO 创建每组2
到
16 个
驱动器的纠删码集。您提供的驱动器总数必须是这些数字之一的倍数。
-
MinIO 选择最大的 EC 集大小,将其划分为给定的驱动器总数或节点总数 – 确保保持均匀分布,即每个节点参与每组相同数量的驱动器
。 -
每个对象都写入单个 EC 集,因此分布在不超过 16 个驱动器上。
-
建议运行分布式 MinIO 设置的所有节点是同质的,即相同的操作系统、相同数量的磁盘和相同的网络互连。
-
MinIO 分布式模式需要
新目录
。如果需要,驱动器可以与其他应用程序共享。您可以通过使用 MinIO 独有的子目录来执行此操作。例如,如果您已将卷安装在 下
/export
,则将其作为参数传递
/export/data
给 MinIO 服务器。 - 下面的 IP 地址和驱动器路径仅用于演示目的,您需要将它们替换为实际的 IP 地址和驱动器路径/文件夹。
-
运行分布式 MinIO 实例的服务器之间的间隔应小于 15 分钟。您可以启用
NTP
服务作为最佳实践,以确保跨服务器的时间相同。 -
MINIO_DOMAIN
应为桶 DNS 样式支持定义和导出环境变量。 -
在Windows
操作系统上运行分布式 MinIO被认为是
实验性
的。请谨慎行事。
前期准备
四台服务器开启时间同步,命令:
yum -y install ntp
systemctl enable ntpd
systemctl start ntpd
timedatectl set-ntp yes
ntpdate -u cn.pool.ntp.org
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
watch -n 1 'date'
关闭防火墙
1.首先查看防火墙状态:
service iptables status
2.永久性生效,重启后不会复原
开启:
chkconfig iptables on
关闭:
chkconfig iptables off
3.即时生效,重启后复原
开启:
service iptables start
关闭:
service iptables stop
4.设置后重启:
reboot
4个节点,每节点4块盘
每台服务器中都要配置如下hostname
服务器 IP | hostname | 说明 |
192.168.150.128 | minio1.com | Minio节点 |
192.168.150.129 | minio2.com | Minio节点 |
192.168.150.130 | minio3.com | Minio节点 |
192.168.150.131 | minio4.com | Minio节点 |
192.168.150.132 | minio5.com |
Nginx负载均衡 |
启动分布式Minio实例,4个节点,每节点4块盘,需要在4个节点上都运行下面的命令。
1、给每台服务器新增一块硬盘,这里使用的10G(这里使用的是虚拟机,自行百度怎么添加,不使用新硬盘部署集群会报错)
2、格式化硬盘 (不格式化会提示只读模式)
mkfs.ext4 /dev/sdb
3、创建minio数据目录,挂载数据磁盘到数据目录
mkdir -p /data/minio{1..4} // 模拟四块硬盘
mount /dev/sdb /data
实现永久挂载需要配置 vim /etc/fstab
4、minio-cluster.sh脚本
4.1 第一中写法
#!/bin/bash
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
nohup /usr/local/soft/minio server --address ":9000" --console-address ":9001" \
http://192.168.150.128:9000/data/minio1 \
http://192.168.150.128:9000/data/minio2 \
http://192.168.150.128:9000/data/minio3 \
http://192.168.150.128:9000/data/minio4 \
http://192.168.150.129:9000/data/minio1 \
http://192.168.150.129:9000/data/minio2 \
http://192.168.150.129:9000/data/minio3 \
http://192.168.150.129:9000/data/minio4 \
http://192.168.150.130:9000/data/minio1 \
http://192.168.150.130:9000/data/minio2 \
http://192.168.150.130:9000/data/minio3 \
http://192.168.150.130:9000/data/minio4 \
http://192.168.150.131:9000/data/minio1 \
http://192.168.150.131:9000/data/minio2 \
http://192.168.150.131:9000/data/minio3 \
http://192.168.150.131:9000/data/minio4 >/data/minio.log 2>&1 &
4.2 第二中写法
#!/bin/bash
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
nohup /usr/local/soft/minio server --address ":9000" --console-address ":9001" http://minio{1...4}.com:9000/data/minio{1...4} >/data/minio-data.log 2>&1 &
5、Nginx负载均衡配置
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# Minio配置---开始
upstream minio_console {
server 192.168.150.128:9001 max_fails=3 fail_timeout=5s;
server 192.168.150.129:9001 max_fails=3 fail_timeout=5s;
server 192.168.150.130:9001 max_fails=3 fail_timeout=5s;
server 192.168.150.131:9001 max_fails=3 fail_timeout=5s;
}
upstream minio_api {
server 192.168.150.128:9000 max_fails=3 fail_timeout=5s;
server 192.168.150.129:9000 max_fails=3 fail_timeout=5s;
server 192.168.150.130:9000 max_fails=3 fail_timeout=5s;
server 192.168.150.131:9000 max_fails=3 fail_timeout=5s;
}
server {
listen 9001; #或者用80端口也可以
server_name 192.168.150.132; #可以用域名
location / {
#Nginx默认是上传一个不能超过1M大小的文件
#client_body_buffer_size 配置请求体缓存区大小, 不配的话,
#client_body_temp_path 设置临时文件存放路径。只有当上传的请求体超出缓存区大小时,才会写到临时文件中
#client_max_body_size 设置上传文件的最大值
client_max_body_size 600M;
client_body_buffer_size 600M;
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://minio_console;
expires 0;
}
}
server {
listen 9000;
server_name 192.168.150.132; #可以用域名
location / {
#Nginx默认是上传一个不能超过1M大小的文件
#client_body_buffer_size 配置请求体缓存区大小, 不配的话,
#client_body_temp_path 设置临时文件存放路径。只有当上传的请求体超出缓存区大小时,才会写到临时文件中
#client_max_body_size 设置上传文件的最大值
client_max_body_size 600M;
client_body_buffer_size 600M;
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://minio_api;
expires 0;
}
}
# Minio配置---结束
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}