linux下的分布式Minio部署实践

Linux下的分布式Minio部署实践

分布式Minio部署可以将多块硬盘(位于相同机器或者不同机器)组成一个对象存储服务,避免单机环境下硬盘容量不足、单点故障等问题。

1. 简介

在当前的云计算和大数据时代,IT系统通常的设计理念都是无中心和分布式。Minio分布式模式可以帮助搭建一个高可靠、高可用、弹性扩展的对象存储服务。

分布式部署,minio拓扑为Multi-Node Multi-Drive (MNMD), 即多个节点,每个节点有多个磁盘。可用于如下场景:

  • 企业级的高性能对象存储。

  • 多节点/多硬盘级别的可靠性,可配置容忍最多 1/2 节点或硬盘的损失。

  • 用于AI/ML、分布式查询、分析以及其他数据湖组件的主要存储。

  • 可扩展到 PB 级别的工作负载,具备存储容量和性能的双重扩展能力。

2. minio的数据保护机制

2.1 Erasure Code(纠删码)

Minio 使用 Erasure Code 提供数据的冗余:

  • 分布式 Minio 采用Erasure Code来防范多个节点宕机和位衰减。
  • 分布式 Minio 至少需要 4 个节点(4台服务器),使用分布式 Minio 就会自动启用纠删码功能。
  • Erasure Code 是一种恢复丢失和损坏数据的数学算法, Minio 采用 Reed-Solomon Code 将对象拆分成 N/2 数据 和 N/2 奇偶校验块。MinIO 在 N / 2 个数据盘 和 N / 2 个奇偶校验盘上分片对象。这就意味着如果是12块盘, 一个对象会被分成6个数据块、6个奇偶校验块, 可以丢失任意6块盘的情况下(不管其是存放的数据块还是奇偶校验块), 仍可以从剩下的盘中的数据进行读取和恢复。
  • Minio 纠删码是作用在对象级别,可以一次恢复一个对象,而RAID 是作用在卷级别,数据恢复时间很长。Minio 对每个对象单独编码,存储服务一经部署,通常情况下是不需要更换硬盘或者修复。
  • DataDrives : 纠删码中的数据盘,用来存储 Object 原始数据。
  • ParityDrives: 纠删码中的校验盘,用来存储 Object 计算出来的校验数据。
  • Minio 纠删码的默认配置为 1 : 1, 即数据盘 ( DataDrives )和 校验盘 ( ParityDrives ) 个数相同, 使用minio分布式部署最终真正可用的存储空间,只有所有磁盘总空间的一半大小。
  • 一个 ErasureCode 组/ Sets 中有多个 Drive(DataDrives + ParityDrives), Minio 会先将一块 Block 按照 Drives 数量, 划分为多个小块, 这些小块在 Minio 中叫做 Shards。比如一个 Block 是 10MB, 而 Set 里有 16 个 Drive(8 DataDrives + 8 ParityDrives), 此时 Minio 会将 Block 按照 10 MB / 8 DataDrives 的方式,将数据划分到 8 个 Data Shards,并额外再创建 8 个 空 Shards,用来存储编码后的冗余数据。
  • 接着 Minio 就会对 Data Shards 进行纠删码编码, 并将编码后的冗余数据存储到前面创建的 8 个空 Shards 中, 也就是 parity shards 中。

2.2 数据保护

分布式 MinIO 使用 Erasure Code 提供针对 多个节点/驱动器 故障 和 Bit Rot 保护。

  • 由于分布式 MinIO 所需的 最小磁盘为 4(与擦除编码所需的最小磁盘相同), 因此在您启动分布式 MinIO 时,擦除代码会自动启动。
  • 因此 只要 m / 2 个服务器 或 m * n / 2 个或更多磁盘在线, 具有 m个服务器 和 n个磁盘 的分布式 MinIO 设置将使您的数据安全。 ( M 表示 服务器总数, N 表示 数据库盘 总数 )
  • Erasure Code 是用来保证 Object 的每个 Block 的数据正确和可恢复的, 而 Bitrot 技术是用来检验磁盘数据的正确性的。
  • Erasure Code 技术比较复杂, 但是 Bitrot 技术就比较简单了。本质就是在写数据之前, 先计算好数据的 hash, 然后将 hash 先写入磁盘, 再写入需要存储的数据。这样读取数据时,就可以通过重新计算 hash,和原始写入的 hash进行一致性比较,来判断数据是否有损坏。
  • 上传文件时,Minio 不是直接上传到 object 在磁盘的最终存储目录的,而是先写到一个临时目录,等所有数据都写到临时目录后,Minio 才会进行 rename 操作,将 object 数据存储到最终存储目录。

3. 部署分布式Minio

3.1 环境准备

机器准备
hostname os 配置 ip disk
minioserver1 centos7.9 8C32G 192.168.1.10 vdb,vdc,vdd,vde
minioserver2 centos7.9 8C32G 192.168.1.11 vdb,vdc,vdd,vde
minioserver3 centos7.9 8C32G 192.168.1.12 vdb,vdc,vdd,vde
minioserver4 centos7.9 8C32G 192.168.1.13 vdb,vdc,vdd,vde
  1. 各节点按照上表信息完成基础配置。
  2. 各节点配置ntp服务,确保时间同步。
  3. 各节点关闭防火墙或者放行9000和9001端口:
bash 复制代码
firewall-cmd --permanent --zone=public --add-port=9000-9001/tcp
firewall-cmd --reload
磁盘和挂载点准备

本文以4节点的分布式Minio为例,每个节点4块盘为例。将4块盘分别挂载到4个节点上,并在每个节点上创建目录。

  1. 格式化磁盘并配置挂载点
bash 复制代码
]# cat disk-mount.sh
#!/bin/bash
mkfs.xfs /dev/vdb -L DISK1
mkfs.xfs /dev/vdc -L DISK2
mkfs.xfs /dev/vdd -L DISK3
mkfs.xfs /dev/vde -L DISK4


mkdir -p /data/minio/data0{1..4}

cat >> /etc/fstab <<-EOF
LABEL=DISK1      /data/minio/data01         xfs     defaults,noatime  0       2
LABEL=DISK2      /data/minio/data02         xfs     defaults,noatime  0       2
LABEL=DISK3      /data/minio/data03         xfs     defaults,noatime  0       2
LABEL=DISK4      /data/minio/data04         xfs     defaults,noatime  0       2
EOF

mount -a

在4个节点依次执行上述脚本sh disk-mount.sh,确保硬盘挂载到相应目录:

bash 复制代码
]# lsblk -f
NAME   FSTYPE  LABEL    UUID                                 MOUNTPOINT
sr0    iso9660 config-2 2024-09-18-14-22-17-00               
vda                                                          
└─vda1 xfs              a8486478-6076-4541-bfc7-8d945834d5a0 /
vdb    xfs     DISK1    c4f4442a-f805-4404-ab5b-2e27b46a2b75 /data/minio/data01
vdc    xfs     DISK2    dba519e6-7a01-4eaf-a3cc-3d2b2a23a39a /data/minio/data02
vdd    xfs     DISK3    369b7795-510f-4f50-b314-7fc3b533a36b /data/minio/data03
vde    xfs     DISK4    360ccb99-029a-496d-9f2c-22d58cb51206 /data/minio/data04

注意:

确保用于minio的数据盘是干净无数据的。

  1. 禁用XFS Retry On Error

MinIO 强烈建议通过 max_retries 配置禁用以下错误类别的重试行为:

  • EIO 错误:读写时发生的输入/输出错误
  • ENOSPC 错误:设备上空间不足
  • 默认:所有其他错误

默认的 max_retries 设置通常会让文件系统在错误发生时无限期地重试,而不是传播错误。MinIO 可以正确处理 XFS 错误,因此重试行为只会引入不必要的延迟或性能下降。

以下脚本会遍历指定挂载路径下的所有硬盘,并将 XFS 的 max_retries 设置为 0,或设置为"在发生错误时立即失败",以符合推荐的错误类别。该脚本会忽略未挂载的硬盘(无论是手动挂载还是通过 /etc/fstab)。请根据您的 MinIO 硬盘修改 /data/minio/data 行以匹配使用的模式。

bash 复制代码
#!/bin/bash

for i in $(df -h | grep /data/minio/data | awk '{ print $1 }'); do
      mountPath="$(df -h | grep $i | awk '{ print $6 }')"
      deviceName="$(basename $i)"
      echo "Modifying xfs max_retries and retry_timeout_seconds for drive $i mounted at $mountPath"
      echo 0 > /sys/fs/xfs/$deviceName/error/metadata/EIO/max_retries
      echo 0 > /sys/fs/xfs/$deviceName/error/metadata/ENOSPC/max_retries
      echo 0 > /sys/fs/xfs/$deviceName/error/metadata/default/max_retries
done
exit 0

将上述脚本保存为 /opt/minio/xfs-retry-settings.sh,添加执行权限:chmod +x /opt/minio/xfs-retry-settings.sh。并在所有 MinIO 节点上运行此脚本,以禁用 XFS 的错误重试功能。

因为 Linux 操作系统通常在重启不会保留这些更改,可以使用带有 @reboot 时间参数的 cron 作业,在节点重启时运行上述脚本,以确保所有硬盘禁用错误重试功能。使用 crontab -e 创建以下任务,并根据每个节点的实际情况修改脚本路径:

bash 复制代码
@reboot /opt/minio/xfs-retry-settings.sh

说明

官方建议使用本地存储类型(DAS),同时文件系统使用xfs,磁盘使用的存储介质和容量建议一致。

关于minio部署的硬件要求可以参考:https://min.io/docs/minio/linux/operations/checklists.html

minio软件准备

在每个节点上安装minio:

bash 复制代码
# 在节点的/opt目录下载安装minio软件
mkdir -p /opt/minio
mv minio /opt/minio/
cd /opt/minio/
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio

3.2 启动分布式Minio

以下两种方式任选一种,用于配置启动分布式Minio服务:

通过后台运行命令启动

在4个节点下依次创建并配置开机自动运行如下脚本:

bash 复制代码
# minio文件和运行脚本
]# pwd
/opt/minio
]# ls
minio minio-cluster-start.sh 

# 配置脚本开机运行
]# chmod +x minio-cluster-start.sh
]# echo "/opt/minio/minio-cluster-start.sh" >> /etc/rc.d/rc.local
]# chmod +x /etc/rc.d/rc.local

其中minio-cluster-start.sh脚本内容如下:

bash 复制代码
#!/bin/bash
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=minioadmin

nohup /opt/minio/minio server --address :9000 --console-address :9001 \
http://192.168.1.10/data/minio/data01 http://192.168.1.10/data/minio/data02 http://192.168.1.10/data/minio/data03 http://192.168.1.10/data/minio/data04 \
http://192.168.1.11/data/minio/data01 http://192.168.1.11/data/minio/data02 http://192.168.1.11/data/minio/data03 http://192.168.1.11/data/minio/data04 \
http://192.168.1.12/data/minio/data01 http://192.168.1.12/data/minio/data02 http://192.168.1.12/data/minio/data03 http://192.168.1.12/data/minio/data04 \
http://192.168.1.13/data/minio/data01 http://192.168.1.13/data/minio/data02 http://192.168.1.13/data/minio/data03 http://192.168.1.13/data/minio/data04 \
> /var/log/minio.log 2>&1 &
配置系统服务管理

也可以将minio配置为系统服务,实现systemctl统一管理。

bash 复制代码
# minio文件和运行脚本
]# pwd
/opt/minio
]# ls
minio run.sh
]# chmod +x run.sh

其中run.sh脚本内容如下:

bash 复制代码
#!/bin/bash
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=minioadmin

/opt/minio/minio server --address :9000 --console-address :9001 \
http://192.168.1.10/data/minio/data01 http://192.168.1.10/data/minio/data02 http://192.168.1.10/data/minio/data03 http://192.168.1.10/data/minio/data04 \
http://192.168.1.11/data/minio/data01 http://192.168.1.11/data/minio/data02 http://192.168.1.11/data/minio/data03 http://192.168.1.11/data/minio/data04 \
http://192.168.1.12/data/minio/data01 http://192.168.1.12/data/minio/data02 http://192.168.1.12/data/minio/data03 http://192.168.1.12/data/minio/data04 \
http://192.168.1.13/data/minio/data01 http://192.168.1.13/data/minio/data02 http://192.168.1.13/data/minio/data03 http://192.168.1.13/data/minio/data04

在3个节点上创建minio.service文件:

bash 复制代码
# minio.service文件内容
]# cat > /usr/lib/systemd/system/minio.service <<-EOF
[Unit]
Description=Minio service
Documentation=https://docs.minio.io/
 
[Service]
WorkingDirectory=/opt/minio/
ExecStart=/opt/minio/run.sh
 
Restart=on-failure
RestartSec=5
 
[Install]
WantedBy=multi-user.targe
EOF

# 配置minio服务启动
]# systemctl daemon-reload
]# systemctl enable minio && systemctl start minio

3.3 访问minio console

此时通过任意节点的ip和端口(9001)访问minio console,默认用户名和密码为admin/minioadmin

4. 配置nginx代理minio集群

通过nginx反向代理4台minio节点,统一访问入口并做负载均衡。这里使用两台机器搭建高可用的nginx集群。

hostname ip 操作系统 软件版本
nginx1 192.168.1.2 centos7.9 keepalived-1.3.5-19.el7.x86_64; nginx-1.20.1-10.el7.x86_64
nginx2 192.168.1.9 centos7.9 keepalived-1.3.5-19.el7.x86_64; nginx-1.20.1-10.el7.x86_64

说明

Minio官方建议的LB方案为nginx和Haproxy,本文使用nginx做为LB。

4.1 安装keepalived和nginx

bash 复制代码
]# yum -y install keepalived nginx
配置keepalived

主节点keepalived配置。编辑 /etc/keepalived/keepalived.conf,配置如下:

bash 复制代码
global_defs {
   router_id nginx1
}

vrrp_script chk_nginx {
    script "/etc/keepalived/check_nginx.sh"  # 指定检查脚本路径
    interval 2                               # 每2秒检查一次
    weight -10                               # 如果Nginx挂掉,优先级减10。确保降低优先级后低于slave节点优先级
    fall 10
    rise 2
}

vrrp_instance VI_1 {
    state MASTER                 # 主节点为 MASTER,备节点为 BACKUP
    interface eth0               # 绑定的网卡接口
    virtual_router_id 51         # VRID 相同,表示同一个虚拟路由器
    priority 100                 # 优先级,主节点要比备节点高
    advert_int 1                 # 检测时间间隔
    authentication {
        auth_type PASS           # 认证方式
        auth_pass 1111           # 认证密码
    }
	unicast_src_ip 192.168.1.2          #配置单播的源地址,即本机地址
    unicast_peer {            # 默认为组播模式,此处配置单播
        192.168.1.9             # 备节点的IP地址,如果由多个备节点,可以配置多个,每行一个
    }
    virtual_ipaddress {
        192.168.1.14            # 虚拟IP地址 (VIP)
    }
    track_script {
        chk_nginx    # 跟踪Nginx检查脚本
    }
}

备节点keepalived配置。编辑 /etc/keepalived/keepalived.conf,配置如下:

bash 复制代码
global_defs {
   router_id nginx2
}

vrrp_instance VI_1 {
    state BACKUP    # 备节点为 BACKUP
    interface eth0
    virtual_router_id 51    # VRID 相同
    priority 99    # 优先级,备节点要比主节点低
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111       # 认证密码相同
    }
	unicast_src_ip 192.168.1.9          #配置单播的源地址,即本机地址
    unicast_peer {            # 默认为组播模式,此处配置单播
        192.168.1.2             # 备节点的IP地址,如果由多个备节点,可以配置多个,每行一个
    }
    virtual_ipaddress {
        192.168.1.14    # 虚拟IP地址 (VIP)
    }
    track_script {
        chk_nginx    # 跟踪Nginx检查脚本
    }
}

配置健康检查脚本:

在每台nginx节点上创建一个检查脚本,例如/etc/keepalived/check_nginx.sh,内容如下:

bash 复制代码
#!/bin/bash
if ! pidof nginx > /dev/null; then
    exit 1  # Nginx 没有运行,返回非 0 值表示失败
fi
exit 0  # Nginx 运行正常

该脚本通过pidof命令检查Nginx进程是否正常运行,如果nginx进程不存在则返回状态码非0,这样Keepalived可以根据返回状态做出决定。

添加脚本的执行权限:

bash 复制代码
]# sudo chmod +x /etc/keepalived/check_nginx.sh
配置nginx

通过使用 nginx 代理,在主节点和备节点上分别配置nginx,编辑 /etc/nginx/nginx.conf,配置如下:

bash 复制代码
upstream minio-server {
        least_conn;
        server 192.168.1.10:9001 weight=25 max_fails=2 fail_timeout=30s;
        server 192.168.1.11:9001 weight=25 max_fails=2 fail_timeout=30s;
        server 192.168.1.12:9001 weight=25 max_fails=2 fail_timeout=30s;
        server 192.168.1.13:9001 weight=25 max_fails=2 fail_timeout=30s;
    }   


server{
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    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;
        client_body_buffer_size 10M;
        client_max_body_size 10G;
        proxy_buffers 1024 4k; 
        proxy_connect_timeout 300;
        proxy_next_upstream error timeout http_404; 
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://minio-server; # This uses the upstream directive definition to load balance
    }
}

其中主要是 upstreamproxy_pass 的配置,配置到nginx.conf中的http块中。

启动配置服务
bash 复制代码
# keepalived服务
]# systemctl start keepalived
]# systemctl enable keepalived

# nginx服务
]# systemctl start nginx
]# systemctl enable nginx

4.2 验证

访问 [http://${VIP}:80](http://$%7BVIP%7D:80) 即可访问minio console。

4.3 FAQ

  1. **问题详情:**配置nginx代理后,通过nginx访问minio。在浏览桶中的列表的时候,始终在loading,无法加载桶内的文件列表。通过浏览器F12调试界面查看有很多的WebSocket connection的错误。

解决方式:

在nginx配置中,确保添加如下参数:

bash 复制代码
    location / {
    	...
		proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        ...
        }

5. 参考资料

  1. https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-multi-node-multi-drive.html
  2. https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html
  3. https://min.io/docs/minio/linux/operations/checklists/hardware.html#minio-hardware-checklist-memory
  4. Minio Cluster 详解 )
相关推荐
丶Darling.6 分钟前
MIT 6.S081 | 操作系统 | Lab1: Xv6 and Unix utilities
linux·服务器·c语言·操作系统·unix·lab·mit 6.s081
Burfitt.Lee13 分钟前
Linux:confluence8.5.9的部署(下载+安装+pojie)离线部署全流程 遇到的问题
linux·运维·服务器
vvw&25 分钟前
使用 Nginx 在 Ubuntu 22.04 上安装 LibreNMS 开源网络监控系统
linux·运维·服务器·nginx·ubuntu·github·librenms
运维&陈同学30 分钟前
【zookeeper02】消息队列与微服务之zookeeper单机部署
linux·服务器·分布式·微服务·zookeeper·云原生·消息队列·云计算
与君共勉121381 小时前
Jenkins-Git Parameter 插件实现指定版本的发布和回滚
linux·服务器·gitlab·jenkins
wusam1 小时前
CentOS8.5.2111(7)完整的Apache综合实验
linux·运维·apache
&黄昏的乐师1 小时前
Opencv+ROS实现摄像头读取处理画面信息
linux·人工智能·opencv·计算机视觉·ros
大筒木老辈子2 小时前
Linux笔记---进程:进程切换与O(1)调度算法
linux·服务器·笔记
小七de尾巴2 小时前
Linux下X11协议理解
linux·运维·计算机外设
大风吹PP凉3 小时前
45系统调用与内核API
java·linux·服务器