特点:
1. 多机同时运行
2. 当客户端提交一个大文件的时候,服务端要判断这个文件的大小,然后把这个文件分割,并执行一些调度逻辑,假设分成4份,调度逻辑要调度出这份文件的4个子集,分别应该放到哪个具体的data-server上,并向客户端返回这4个data-server的IP地址
3. 服务端记录下这个文件和这4个dataserver的对应关系,这些就叫元数据,比如类似这样的结构化形式:
id、filename、storage_path、total_size、splits、data_servers(可以有多个)、每个data_server上存储的具体位置、每个data_server存储的文件分片的offset位置
换句话说,元数据服务器进程要根据客户端提交上来的一个文件写入的请求,进行计算,计算什么呢?
- 这个文件有多大
- 分成几份,每份按字节来计算偏移量,startoffset ~ endoffset,比如分成4份,分别是1-1000、1001-2000、2001-3000、3001-3555字节,这4份子文件分别存放在4台data-server上
- 找出4台data-server,比如根据data-server是否在线,data-server的磁盘剩余容量等
- 向客户端返回4台data-server的ip地址
- 客户端同时连接4台data-server,分别向4台data-server发送数据,把文件的4个子集写到data-server磁盘上,还要记住4个data-server上的具体存储位置,比如/data/companyname/projectname/abc/myfile001
4. 客户端向meta-server发起查询文件的时候,metaserver就要根据之前的元数据信息,找出这个文件对应存放在哪些data-server上了,然后让client和这4个data-server建立tcp连接,同时下载数据,客户端最后把文件自行拼接起来
5. 整个集群系统要支持文件的副本备份,上面一个客户端提交的大文件,分成4份后,要自动再集群内进行备份,而且要跨data-server进行互为备份,这些备份信息要存储在meta-server的数据库中,而且meta-server的数据库也必须高可用
6. meta-server也是必须HA部署
7. 要能够随时对meta-server进行扩容
8. 要能够随时对data-server进行扩容,meta-server必须知道每个data-server的详细信息(健康状态、磁盘剩余空间、cpu使用率、内存使用率、网卡流量等信息),data-server和meta-server之间有心跳包
MinIO的集群方式部署
肯定不能单机试验那样启动一个进程就完事了,必须集群部署,如果是docker-compose的话,可以在单机启动多个minIO docker容器,但是不能跨物理主机,用docker swarm或者K8s的话,可以跨物理主机部署minIO,下面这个compose.yaml文件说明了一切。
version: '3.7'
# Settings and configurations that are common for all containers
x-minio-common: &minio-common
image: quay.io/minio/minio:RELEASE.2021-09-09T21-37-07Z
command: server --console-address ":9001" http://minio{1...4}/data{1...2}
expose:
- "9000"
- "9001"
environment:
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: minio123
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
# starts 4 docker containers running minio server instances.
# using nginx reverse proxy, load balancing, you can access
# it through port 9000.
services:
minio1:
<<: *minio-common
hostname: minio1
volumes:
- data1-1:/data1
- data1-2:/data2
minio2:
<<: *minio-common
hostname: minio2
volumes:
- data2-1:/data1
- data2-2:/data2
minio3:
<<: *minio-common
hostname: minio3
volumes:
- data3-1:/data1
- data3-2:/data2
minio4:
<<: *minio-common
hostname: minio4
volumes:
- data4-1:/data1
- data4-2:/data2
nginx:
image: nginx:1.19.2-alpine
hostname: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "9000:9000"
- "9001:9001"
depends_on:
- minio1
- minio2
- minio3
- minio4
## By default this config uses default local driver,
## For custom volumes replace with volume driver configuration.
volumes:
data1-1:
data1-2:
data2-1:
data2-2:
data3-1:
data3-2:
data4-1:
data4-2:
启动分布式Minio实例,8个节点,每节点1块盘,需要在8个节点上都运行下面的命令
export MINIO_ACCESS_KEY=<ACCESS_KEY>
export MINIO_SECRET_KEY=<SECRET_KEY>
minio server http://192.168.1.11/export1 http://192.168.1.12/export2 \
http://192.168.1.13/export3 http://192.168.1.14/export4 \
http://192.168.1.15/export5 http://192.168.1.16/export6 \
http://192.168.1.17/export7 http://192.168.1.18/export8
但是奇怪的是,并没有看到minio有meta-server这样的角色,难道所有的节点都是对等的?貌似核心是它用了一个所谓的纠删码机制
纠删码是一种恢复丢失和损坏数据的数学算法, Minio采用Reed-Solomon code将对象拆分成N/2数据和N/2 奇偶校验块。 这就意味着如果是12块盘,一个对象会被分成6个数据块、6个奇偶校验块,你可以丢失任意6块盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的盘中的数据进行恢复
纠删码的工作原理和RAID或者复制不同,像RAID6可以在损失两块盘的情况下不丢数据,而Minio纠删码可以在丢失一半的盘的情况下,仍可以保证数据安全。 而且Minio纠删码是作用在对象级别,可以一次恢复一个对象,而RAID是作用在卷级别,数据恢复时间很长。 Minio对每个对象单独编码,存储服务一经部署,通常情况下是不需要更换硬盘或者修复。Minio纠删码的设计目标是为了性能和尽可能的使用硬件加速。
位衰减又被称为数据腐化Data Rot
、无声数据损坏Silent Data Corruption
,是目前硬盘数据的一种严重数据丢失问题。硬盘上的数据可能会神不知鬼不觉就损坏了,也没有什么错误日志。正所谓明枪易躲,暗箭难防,这种背地里犯的错比硬盘直接咔咔宕了还危险。 不过不用怕,Minio纠删码采用了高速 HighwayHash 基于哈希的校验和来防范位衰减。