MinIO分布式专题(第二章、MinIO分布式部署)

        上个章节简单介绍了下单机和纠删码的部署,也对一些最基础的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是真实的元数据。

MinIO分布式专题(第二章、MinIO分布式部署)_第1张图片

        如果这个文件是大于1M,以文件名称为下一级目录,文件名下是 part.1 和 xl.meta,前者是编码数据块及检验块,后者是元数据文件。

        

        那么这8块中任意丢失4块或者损坏,会保证数据可以恢复还原,后续实战的时候会验证出来。

        附上一张图:

MinIO分布式专题(第二章、MinIO分布式部署)_第2张图片

         当然纠删码模式不是只有单机下可以,分布式部署下自带纠删码模式,更加保证高可用,这个后面会提及。

        同样我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 创建每组416 个驱动器的纠删码组。驱动器总数必须是这些数字之一的倍数
  • MinIO 选择最大的 EC集大小,它分为给定的驱动器总数或节点总数,确保均匀分布,即每个节点参与每组相同数量的驱动器
  • 每个对象都写入单个 EC 集,因此分布在不超过 16 个驱动器上。
  • 建议所有运行分布式 MinIO 设置的节点是同构的,即相同的操作系统、相同的磁盘数量和相同的网络互连。
  • 运行分布式 MinIO 实例的服务器之间的间隔应小于 15 分钟。可以启用NTP服务作为最佳实践,以确保跨服务器的时间相同。
  • Windows操作系统上运行分布式 MinIO被认为是实验性的。请谨慎行事!!

        因此我这里采用了4台服务器,每台上有四个目录data1~4,模拟4块磁盘,默认一共4*4=16块磁盘。

        在每个服务器下的/usr/chenxin-minio/data目录下我都创建4个目录

MinIO分布式专题(第二章、MinIO分布式部署)_第3张图片

        脚本都加上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个存储盘。

MinIO分布式专题(第二章、MinIO分布式部署)_第4张图片

         新建一个bucket并上传个文件来看下磁盘上的分布,前者是编码数据块及检验块,后者是元数据文件。

MinIO分布式专题(第二章、MinIO分布式部署)_第5张图片

         那么现在的分布式环境已经搭建好了,上传下载也没有什么问题。

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上有这样的文件

MinIO分布式专题(第二章、MinIO分布式部署)_第6张图片

        这个时候需要扩容,目前的区是4个磁盘,我需要扩容4个磁盘。我拉了两个服务器,ip要连续,这个是比较坑的地方,另外找了两个服务器14 15。

        启动好13 和14 后结果

MinIO分布式专题(第二章、MinIO分布式部署)_第7张图片

         这个时候把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分布式专题(第二章、MinIO分布式部署)_第8张图片

        那么问题来了,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分布式专题(第二章、MinIO分布式部署)_第9张图片

         这个时候停掉两个节点的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的客户端的使用,欢迎指出!

你可能感兴趣的:(MinIO专栏,minio,java)