上个章节简单介绍了下单机和纠删码的部署,也对一些最基础的API进行了实现,本章
进入分布式部署讲解。
本章节我们就讲述以下几个内容:
1、MinIO如何进行纠删码部署
2、MinIO分布式部署场景实战
3、分布式场景扩容方案如何落地
1、MinIO如何进行纠删码部署
上个章节我介绍了下纠删码模式的特点,本节重点介绍下纠删码的部署和使用。
1.1、什么是纠删码
erasure code
?对于纠删码模式,其实就是一种数据恢复的保护模式,而MinIO对纠删码模式的算法进
行了实现,采用Reed-Solomon code(简称RScode)将对象拆分成N/2数据和N/2 奇偶校
验块。Reed Solomon利用范特蒙矩阵或者柯西矩阵的特性来实现纠错码的功能,感兴趣可
以自己谷歌下,这就意味着如果是12块盘,一个对象会被分成6个数据块、6个奇偶校验块,
你可以丢失任意6块盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的盘中
的数据进行恢复,是不是很NB?
1.2、为什么纠删码有用
纠删码的工作原理和RAID(磁盘阵列)或者复制不同,像RAID6可以在损失两块盘的
情况下不丢数据,而Minio纠删码可以在丢失一半的盘的情况下,仍可以保证数据安全。 而
且Minio纠删码是作用在对象级别,可以一次恢复一个对象,而RAID是作用在卷级别,数据
恢复时间很长。 Minio对每个对象单独编码,存储服务一经部署,通常情况下是不需要更换
硬盘或者修复。Minio纠删码的设计目标是为了性能和尽可能的使用硬件加速。
先在/usr/chenxin/data目录下我新建data1~data8,模拟一个服务器上接入8块外接磁盘
文件对象上传到 MinIO后,会在对应的数据存储磁盘中,以 Bucket 名称为目录,文件名称为下一级目录,目录下有 xl.meta是元数据文件。
举个例子,我在Console中建立了一个BucketName为chenxin-bug的桶,在这桶下建立了一个文件夹nicaicai,在nicaicai下上传了一个文件,当这个文件小于1M的时候,会生成一个目录,该目录是文件名称形成的,而真实的文件在这个目录下的xl.mata是真实的元数据。
如果这个文件是大于1M,以文件名称为下一级目录,文件名下是 part.1 和 xl.meta,前者是编码数据块及检验块,后者是元数据文件。
那么这8块中任意丢失4块或者损坏,会保证数据可以恢复还原,后续实战的时候会验证出来。
附上一张图:
当然纠删码模式不是只有单机下可以,分布式部署下自带纠删码模式,更加保证高可用,这个后面会提及。
同样我vim一个脚本叫start-erasurecode.sh
nohup /usr/chenxin/my-minio/minio server --console-address ":50000" /usr/chenxin/data/data{1...8} > /usr/chenxin/data/minio.log 2>&1 &
只要运行脚本后,就可以打开指定的ip+端口访问Console server了。
1.3、具备位衰减恢复
位衰减又被称为数据腐化
Data Rot
、无声数据损坏Silent Data Corruption,
是目前硬盘数据的一种严重数据丢失问题。硬盘上的数据可能会神不知鬼不觉就损坏了,也没有
什么错误日志。正所谓明枪易躲,暗箭难防,这种背地里犯的错比硬盘直接咔咔宕了还危
险。 不过不用怕,Minio纠删码采用了高速 HighwayHash 基于哈希的校验和来防范位衰
减。
2、分布式部署MinIO
分布式模式下的 MinIO 允许将多个驱动器(甚至在不同的机器上)集中到一个对象存储服务器中。由于驱动器分布在多个节点上,分布式 MinIO 可以承受多个节点故障,同时确保完整的数据保护。
分布式MinIO使用纠删码提供针对多个节点/驱动器故障和位衰减的保护,由于分布式MinIO所需要的最小磁盘为4,因此在启动的时候,纠删码模式会随之启动。
官方对于纠删码模式部署的条件有如下要求:
- MinIO 创建每组4到16 个驱动器的纠删码组。驱动器总数必须是这些数字之一的倍数
- MinIO 选择最大的 EC集大小,它分为给定的驱动器总数或节点总数,确保均匀分布,即每个节点参与每组相同数量的驱动器。
- 每个对象都写入单个 EC 集,因此分布在不超过 16 个驱动器上。
- 建议所有运行分布式 MinIO 设置的节点是同构的,即相同的操作系统、相同的磁盘数量和相同的网络互连。
- 运行分布式 MinIO 实例的服务器之间的间隔应小于 15 分钟。可以启用NTP服务作为最佳实践,以确保跨服务器的时间相同。
- 在Windows操作系统上运行分布式 MinIO被认为是实验性的。请谨慎行事!!
因此我这里采用了4台服务器,每台上有四个目录data1~4,模拟4块磁盘,默认一共4*4=16块磁盘。
在每个服务器下的/usr/chenxin-minio/data目录下我都创建4个目录
脚本都加上start-distribute.sh
export MINIO_ROOT_USER=你的账号 export MINIO_ROOT_PASSWORD=你的密码 nohup /usr/chenxin/my-minio/minio server --console-address ":50000" http://10.12.105.13/usr/chenxin01/data/data1 http://10.12.105.13/usr/chenxin01/data/data2 \ http://10.12.105.13/usr/chenxin01/data/data3 http://10.12.105.13/usr/chenxin01/data/data4 \ http://10.12.105.14/usr/chenxin01/data/data1 http://10.12.105.14/usr/chenxin01/data/data2 \ http://10.12.105.14/usr/chenxin01/data/data3 http://10.12.105.14/usr/chenxin01/data/data4 \ http://10.12.105.15/usr/chenxin01/data/data1 http://10.12.105.15/usr/chenxin01/data/data2 \ http://10.12.105.15/usr/chenxin01/data/data3 http://10.12.105.15/usr/chenxin01/data/data4 \ http://10.12.105.20/usr/chenxin01/data/data1 http://10.12.105.20/usr/chenxin01/data/data2 \ http://10.12.105.20/usr/chenxin01/data/data3 http://10.12.105.20/usr/chenxin01/data/data4 > /usr/chenxin/data/minio.log 2>&1 &
最终我们在四台上都运行该脚本,这里要注意点,如果一台一台启动,日志会打出一些连不上的信息,不断的刷,那是因为你其他的服务都没有启动,如果启动的话日志就会停下来。登陆每台上看,其实很明显发现四台都已经配置成功,每台机子4个盘,一共16个存储盘。
新建一个bucket并上传个文件来看下磁盘上的分布,前者是编码数据块及检验块,后者是元数据文件。
那么现在的分布式环境已经搭建好了,上传下载也没有什么问题。
3、分布式下的扩容方案
如果你想进行扩容,这个地方就非常的坑,验证了很久才成功,官方的标准是这么说的:
我们可以把原来的集群看做一个区,新增集群看做另一个区,新对象按每个区域中的可用空间比例放置在区域中。在每个区域内,基于确定性哈希算法确定位置。 说明: 您添加的每个区域必须具有与原始区域相同的磁盘数量(纠删码集)大小,以便维持相同的 数据冗余SLA。 例如,第一个区有8个磁盘,您可以将集群扩展为16个、32个或1024个磁盘的区 域,您只需确保部署的SLA是原始区域的倍数即可。注意:扩容原节点和新节点使用的目录不能是根磁盘路径,必须使用独立磁盘,否则扩容失败。
而目前我们做的第一个区是16个磁盘,我要扩展必须要以16的整数倍扩展,可以扩展成32,48等等...但是验证下来,失败了。报错(后面发现是其他的问题导致)
这个地方是个槽点,官方写的文档对于扩容不得不说太垃圾,而且社区这块回复也相当的慢,让我有点怀疑这个用的人这么多issue的问题没有人处理??
我尝试现在把服务器做成2个,13和14服务器,每个服务器2个磁盘,这样方便扩容效果,于是我在上述的基础上,我把目录删除重新建立/usr/chenxin01/data目录,脚本简化修改为这个:
export MINIO_ROOT_USER=minioadmin export MINIO_ROOT_PASSWORD=ahpu@2019# nohup /usr/chenxin/my-minio/minio server --console-address ":50000" \ http://10.12.105.{13...14}/usr/chenxin01/data/data{1...2} > /usr/chenxin/data/minio.log 2>&1 &
上传个文件后,很明显在data1和data2上有这样的文件
这个时候需要扩容,目前的区是4个磁盘,我需要扩容4个磁盘。我拉了两个服务器,ip要连续,这个是比较坑的地方,另外找了两个服务器14 15。
启动好13 和14 后结果
这个时候把13和14服务停掉,脚本重新更新成这样,然后覆盖到13 14 15 16节点上。
export MINIO_ROOT_USER=minioadmin export MINIO_ROOT_PASSWORD=ahpu@2019# nohup /usr/chenxin/my-minio/minio server --console-address ":50000" \ http://10.12.105.{13...14}/usr/chenxin01/data/data{1...2} \ http://10.12.105.{15...16}/usr/chenxin01/data/data{1...2} > /usr/chenxin/data/minio.log 2>&1 &
一个一个启动后成功。
那么问题来了,MinIO就这么low吗,必须要服务器ip相同才可以进行扩容吗?当然不是
所以还有一个方式可以进行扩容,同样我先采用13,14节点先做上述一样的例子;前提我要先在这两台服务上进行hosts的修改,在13和14上分别执行:
cat > /etc/hosts << EOF 10.12.105.13 minio-1 10.12.105.14 minio-2 EOF
执行下面脚本后,vim看下hosts文件,说明成功配置
然后start-distribute.sh脚本里这么写:
export MINIO_ROOT_USER=minioadmin export MINIO_ROOT_PASSWORD=ahpu@2019# nohup /usr/chenxin/my-minio/minio server --console-address ":50000" \ http://minio-{1...2}/usr/chenxin01/data/data{1...2} > /usr/chenxin/data/minio.log 2>&1 &
启动13,14节点,启动成功后如下
这个时候停掉两个节点的minio服务,另外加两台机器ip是20,23;于是把这四台的hosts都修改掉,记住每台都要执行,并且要检查下别有重复的,并且四台都一样的hosts配置;
cat > /etc/hosts << EOF 10.12.105.13 minio-1 10.12.105.14 minio-2 10.12.105.20 minio-3 10.12.105.23 minio-4 EOF
start-distribute.sh脚本同样修改成这样:
export MINIO_ROOT_USER=minioadmin export MINIO_ROOT_PASSWORD=ahpu@2019# nohup /usr/chenxin/my-minio/minio server --console-address ":50000" \ http://minio-{1...2}/usr/chenxin01/data/data{1...2} \ http://minio-{3...4}/usr/chenxin01/data/data{1...2} > /usr/chenxin/data/minio.log 2>&1 &
ok,一台一台启动,扩容就完成了,这样ip地址不连续一样可以,只需要host指向是连续就可以。
这里注意防火墙!!!这几台防火墙一定要关闭,彼此可以telnet成功,不然非常容易失败!
后续如果你想扩容,就要以当前的节点+磁盘为当前区,即4个节点,8个磁盘;
扩容的话,最少4个节点,每个节点2个盘,也就是8个盘,节点数跟磁盘总共翻倍;
要么就是扩容8个节点,每个节点2个盘,一共16个盘,依次倍数往后...
不得不说,扩容满坑的!!
4、Nginx做负载均衡配置
既然这四台都已经成功的变成了扩容后的方案,那么我们还是希望可以通过统一的入口,后续整合Springboot也比较方便,来看下Nginx怎么配置:
首先你要先通过这几部把Nginx下载下来
- 先安装gcc-c++编译器
yum install gcc-c++ -y yum install -y openssl openssl-devel
- 再安装pcre包
yum install -y pcre pcre-devel
- 再安装zlib包
yum install -y zlib zlib-devel
- 在/usr/local/下创建文件nginx文件
mkdir /usr/local/nginx
- 在网上下nginx包
wget https://nginx.org/download/nginx-1.19.9.tar.gz
- 解压并进入nginx目录
tar -zxvf nginx-1.19.9.tar.gz cd nginx-1.19.9
- 使用nginx默认配置
./configure
- 编译安装
make && make install
- 进入/usr/local/nginx/sbin目录,可以看到有一个可执行文件nginx,直接./nginx执行就OK了。
- 接下来我们要修改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; upstream minio { # 这里配置你集群的ip地址 server 10.12.105.13:9000; server 10.12.105.14:9000; server 10.12.105.20:9000; server 10.12.105.23:9000; } upstream console { ip_hash; # 这里配置集群的ip地址 server 10.12.105.13:50000; server 10.12.105.14:50000; server 10.12.105.20:50000; server 10.12.105.23:50000; } # minio sdk接口 server { listen 9000; listen [::]:9000; server_name localhost; # To allow special characters in headers ignore_invalid_headers off; # Allow any size file to be uploaded. # Set to a value such as 1000m; to restrict file size to a specific value client_max_body_size 0; # To disable buffering proxy_buffering off; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 300; # Default is HTTP/1, keepalive is only enabled in HTTP/1.1 proxy_http_version 1.1; proxy_set_header Connection ""; chunked_transfer_encoding off; proxy_pass http://minio; } } # minio 控制台 server { listen 50000; listen [::]:50000; server_name localhost; # To allow special characters in headers ignore_invalid_headers off; # Allow any size file to be uploaded. # Set to a value such as 1000m; to restrict file size to a specific value client_max_body_size 0; # To disable buffering proxy_buffering off; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-NginX-Proxy true; proxy_connect_timeout 300; # Default is HTTP/1, keepalive is only enabled in HTTP/1.1 proxy_http_version 1.1; proxy_set_header Connection ""; chunked_transfer_encoding off; proxy_pass http://console; } } 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; # } #} }
- 然后覆盖服务器上的nginx.conf,启动访问就可以成功!!
当前分布式部署就先到这,下一章讲解minio的客户端的使用,欢迎指出!