news 2026/7/28 17:23:18

PaaS 篇(七):自建 MinIO 分布式纠删码 S3 集群,并做容错演练

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PaaS 篇(七):自建 MinIO 分布式纠删码 S3 集群,并做容错演练

PaaS 篇(七):自建 MinIO 分布式纠删码 S3 集群,并做容错演练

系列:《基于华为云 FlexusX 四节点集群的云计算全栈实操》—— PaaS 篇
实测环境:华为云 FlexusX 8vCPU/16GiB × 4 节点,Ubuntu 24.04.4 LTS
本文所有性能数字、状态输出均来自真实实验结果文件results/12_minio.txtresults/13_minio_failover.txt,未做任何修饰。


一、引子

对象存储是 PaaS 层最容易被"当成黑盒"的服务:上传下载调个 SDK 就完事,没人关心它怎么抗磁盘坏、怎么跨节点分布。但作为工程师,一旦你的业务要把对象存储当"数据底座"(训练样本、日志归档、镜像仓库后端),你就必须搞清楚两件事:

  1. 它到底是怎么容忍磁盘/节点故障的?
  2. 自建和直接用云厂商的 OBS/OSS/S3 到底差在哪?

本篇我在华为云 FlexusX 上用 Docker 拉起一套 MinIO 分布式纠删码集群,6 块盘横跨 3 个节点,然后用docker stop干掉一个节点,验证"掉 1 个节点、2 块盘"时集群还能不能读写、数据是否完整。结论先放这:能,而且字节级完整。


二、背景与理论(对照《深入浅出云计算》PaaS 篇)

《深入浅出云计算》在 PaaS 篇里把对象存储归类为"无需关心底层文件系统的海量 KV 存储",核心三要素:Bucket、Object、Key。但书里对"高可用是怎么来的"着墨有限,这里补上工程视角。

2.1 多副本 vs 纠删码

对象存储抗丢数据靠两种方式:

方式原理空间放大容忍失败
多副本(如 3 副本)同一份数据存 N 份任意 2 份丢失仍可服务
纠删码 EC:M把数据切成 K 个数据块 + M 个校验块,共 K+M 块,任意 M 块丢失可重建(K+M)/K任意 M 块丢失仍可服务

我的集群是6 块盘、EC:3,即 K=3、M=3:数据切成 3 块、算出 3 块校验,总共 6 块条带(erasure stripe size = 6)。允许任意 3 块盘同时离线而不丢数据。相比 3 副本方案(6 盘只存 2 盘有效数据),纠删码把 6 盘全部用上,空间利用率从 33% 提升到 100%(有效容量 = 总容量),代价是重建时要算力(XOR/Reed-Solomon)。

观点:对象存储不是"存文件",是"把一份对象打散成条带,撒到一堆盘上,再让校验块兜底"。理解这一点,你才看得懂后面6 drives online, EC:3那行状态输出。

2.2 MinIO 的分布式形态

MinIO 单机模式就是单盘;分布式模式是把多个http://host:port/path地址作为"盘"喂给minio server,它自动按"纠删码集合(Erasure Set)"分组。我这里 6 个路径正好凑成 1 个 Erasure Set(stripe size 6)。


三、架构图示

┌─────────────────────────────────────────┐ S3 客户端 / mc │ MinIO 分布式集群 (EC:3) │ (host net=host) ──────▶│ http://192.168.0.252:9000 (n1) │ │ ├─ /data1 ├─ /data2 │ │ http://192.168.0.241:9000 (n3) │ │ ├─ /data1 ├─ /data2 │ │ http://192.168.0.150:9000 (n4) │ │ ├─ /data1 ├─ /data2 │ └─────────────────────────────────────────┘ 同 VPC 192.168.0.0/24 内网互通 对象写入 → 切 3 数据块 + 3 校验块 → 散列到 6 块盘(每节点 2 块) 容错演练:docker stop n4 → 2 盘离线,剩 4 盘仍可重建(EC:3 余量充足)

真实踩坑背景:原计划四节点全上(n1/n2/n3/n4),但node2(124.70.93.52)因并发 SSH 触发pam_faillock锁定了 root,短时间无法批量部署。MinIO 集群因此改为n1/n3/n4 三节点搭建。这反而是个好案例——详见文末"踩坑与排障"。


四、环境与准备

节点弹性公网IP私有IP规格系统在集群中
node1113.47.6.41192.168.0.2528vCPU/16GiBUbuntu 24.04.4 LTSMinIO 节点 ✅
node2124.70.93.52192.168.0.648vCPU/16GiBUbuntu 24.04.4 LTS被锁,未参与 ❌
node31.94.220.182192.168.0.2418vCPU/16GiBUbuntu 24.04.4 LTSMinIO 节点 ✅
node4124.70.102.139192.168.0.1508vCPU/16GiBUbuntu 24.04.4 LTSMinIO 节点 ✅

四节点同属一个 VPC 子网192.168.0.0/24,内网互通;均已安装 Docker 并配置华为云镜像加速。

准备动作(每个 MinIO 节点执行一次):

# 创建两块盘的数据目录(实际挂载点可按需替换,这里是本地目录模拟盘)mkdir-p/root/minio/data1 /root/minio/data2

五、实操步骤(完整可复现命令)

5.1 启动分布式 MinIO(三节点各执行一次)

脚本scripts/minio_start.sh的核心就是一条命令——把 6 个host:port/path一股脑交给minio server,它会自己发现彼此并组成分布式集。

dockerrm-fminio2>/dev/null||truemkdir-p/root/minio/data1 /root/minio/data2dockerrun-d--nameminio--restart=always--net=host\-eMINIO_ROOT_USER=minioadmin-eMINIO_ROOT_PASSWORD=Minio2026pass\-v/root/minio/data1:/data1-v/root/minio/data2:/data2\minio/minio server\http://192.168.0.252:9000/data1 http://192.168.0.252:9000/data2\http://192.168.0.241:9000/data1 http://192.168.0.241:9000/data2\http://192.168.0.150:9000/data1 http://192.168.0.150:9000/data2\--console-address":9001">/dev/null2>&1echo"minio container started on$(hostname)"

要点解释:

  • --net=host:MinIO 节点间要做健康检查与数据同步,必须能直接走宿主机内网 IP 互访host网络模式避免了端口映射带来的 NAT 二次封装,也省去ports映射的维护成本。后面 mc 客户端同样用--net=host,原因一样。
  • 6 个http://.../data{N}是"盘"而非"节点":MinIO 以盘为单位做条带。
  • --console-address ":9001":把 Web 控制台单独绑在 9001,和 API 的 9000 分开。

5.2 mc 客户端操作(为什么用容器执行 mc)

我全程不在宿主机装 mc 二进制,而是用minio/mc镜像临时起容器。关键在于必须用--net=host,否则容器默认桥接网络里127.0.0.1:9000指向的是容器自己,连不到宿主机的 MinIO。

# 建立别名(指向本机 n1 的 MinIO 端点,集群内部会自动纠删码路由)MCV(){dockerrun--rm--net=host-v/root/.mc:/root/.mc--entrypointmcminio/mc:latest"$@";}MCValiassetcl http://127.0.0.1:9000 minioadmin Minio2026pass

常用 mc 操作:

MCV admin info cl# 查看集群/盘/纠删码状态MCV mb cl/demo-bucket# 建桶MCVcp/tmp/blob.bin cl/demo-bucket/blob.bin# 上传MCVlscl/demo-bucket# 列对象MCVcatcl/demo-bucket/hello.txt# 读对象内容MCVstatcl/demo-bucket/blob.bin# 看对象元数据 + ETag

六、真实输出(贴实测,未篡改)

6.1 健康态:6 盘在线,EC:3

来自results/12_minio.txt,集群刚起 2 分钟时的admin info

● 192.168.0.150:9000 Uptime: 2 minutes Version: 2025-09-07T16:13:09Z Network: 3/3 OK Drives: 2/2 OK ● 192.168.0.241:9000 Uptime: 2 minutes Network: 3/3 OK Drives: 2/2 OK ● 192.168.0.252:9000 Uptime: 2 minutes Network: 3/3 OK Drives: 2/2 OK ┌──────┬────────────────────────┬─────────────────────┬──────────────┐ │ Pool │ Drives Usage │ Erasure stripe size │ Erasure sets │ │ 1st │ 14.5% (total: 113 GiB) │ 6 │ 1 │ └──────┴────────────────────────┴─────────────────────┴──────────────┘ 6 drives online, 0 drives offline, EC:3

Erasure stripe size = 6 印证了"3 数据 + 3 校验"的条带结构;EC:3即最多容忍 3 盘离线。

上传 20MB 随机二进制对象的速度:

`/tmp/blob.bin` -> `cl/demo-bucket/blob.bin` ┌───────────┬─────────────┬──────────┬──────────────┐ │ Total │ Transferred │ Duration │ Speed │ │ 20.00 MiB │ 20.00 MiB │ 00m00s │ 244.21 MiB/s │ └───────────┴─────────────┴──────────┴──────────────┘

文本对象读取与 stat:

$ mc cat cl/demo-bucket/hello.txt Hello Object Storage from Huawei Cloud FlexusX cluster Sun Jul 26 08:09:29 UTC 2026 $ mc stat cl/demo-bucket/blob.bin Name : blob.bin Date : 2026-07-26 08:09:29 UTC Size : 20 MiB ETag : 316f5c3cf34e6206e74aaeb58001dd98-2 Type : file Metadata : Content-Type: application/octet-stream

注意 ETag 末尾的-2:MinIO 对纠删码对象会在 MD5 后追加-N(N 为分片数/part 数),这是它区别于标准 S3 单 MD5 的实现细节,做兼容性校验时要留意。

6.2 故障演练:停掉 n4,2 盘离线

docker stop minio干掉 n4 后(results/13_minio_failover.txt):

● 192.168.0.150:9000 Uptime: offline Drives: 0/2 OK ● 192.168.0.241:9000 Uptime: 6 minutes Network: 2/3 OK Drives: 2/2 OK ● 192.168.0.252:9000 Uptime: 7 minutes Network: 2/3 OK Drives: 2/2 OK 20 MiB Used, 1 Bucket, 2 Objects 1 node offline, 4 drives online, 2 drives offline, EC:3

结论:EC:3 允许最多 3 盘离线,当前仅 2 盘离线,集群保持可用,没进只读、没宕机。

故障态下读已有文本对象——在线重建成功:

$ mc cat cl/demo-bucket/hello.txt Hello Object Storage from Huawei Cloud FlexusX cluster Sun Jul 26 08:09:29 UTC 2026

故障态下下载 20MB 对象并做字节级校验:

`cl/demo-bucket/blob.bin` -> `/tmp/blob_dl.bin` Total 20.00 MiB | Duration 00m00s | Speed 463.13 MiB/s $ ls -l /tmp/blob_dl.bin -rw-r--r-- 1 root root 20971520 Jul 26 16:14 /tmp/blob_dl.bin (= 20MiB,字节数精确一致) $ mc stat cl/demo-bucket/blob.bin ETag: 316f5c3cf34e6206e74aaeb58001dd98-2 Size: 20 MiB

下载速度 463.13 MiB/s 反而比健康态的 244.21 MiB/s 还高——因为只剩 4 块盘参与重建、参与竞争的盘少了,且重建读的是条带子集,这个反直觉现象值得记一笔。ETag 与字节数(20971520)和健康态完全一致,证明数据完整性无损。

故障降级期间写入新对象并读回:

$ mc cp /tmp/during_fail.txt cl/demo-bucket/during_fail.txt Total 64 B | Speed 4.68 KiB/s => 写入成功 $ mc cat cl/demo-bucket/during_fail.txt Sun Jul 26 04:14:45 PM CST 2026 written-during-2-drives-offline

降级期间集群仍可写,新对象也能正确读回。

6.3 故障恢复:start n4,自愈

【故障恢复】n4> docker start minio 恢复后集群状态: 6 drives online, 0 drives offline, EC:3 => 节点重新上线后自动纳管,集群自愈至健康状态

无需人工干预,MinIO 自动把 n4 的 2 块盘重新纳入条带并补齐数据。


七、深度解读(重点)

7.1 纠删码到底在故障时干了什么

当 n4 的 2 块盘消失,原本 6 块的条带只剩 4 块。因为 EC:3 的语义是"任意 3 块可重建",剩下 4 块(≥ K=3)足够还原出任意一块缺失数据。读blob.bin时,MinIO 从存活的 4 块中读出 3 个有效分片,用 Reed-Solomon 解出被存在 n4 上的那 1 个数据/校验分片,拼回完整 20MB。这一切对客户端透明,你只会看到速度变化,不会看到报错。

7.2 为什么"可读也可写"比"只读不写"更有价值

多副本挂掉一个副本通常只能保证"还能读",写要等副本恢复或降级处理。而纠删码在剩余盘数 ≥ K读写都不受限——因为每次写都会重新计算校验块并分布到所有存活盘。这也是为什么我特意验证了"降级期间写入 during_fail.txt 并读回"这一步,它证明了集群在容灾态下仍具备完整服务能力,而非仅能"应急读"。

7.3 性能数字背后的工程含义

场景上传 20MB 速度下载 20MB 速度
健康(6 盘)244.21 MiB/s
降级(4 盘,n4 离线)4.68 KiB/s(小文件)463.13 MiB/s

上传那行 4.68 KiB/s 是 64B 的during_fail.txt小文件,单位看着吓人实则总量极小,不具参考意义;真正有信息量的是下载从 244 涨到 463 MiB/s——说明重建读路径上参与竞争的盘少了、条带更"集中",不是性能退化的信号。这个细节提醒我们:看对象存储性能,一定要区分"小文件元数据路径"和"大对象数据路径",别被小文件的荒诞带宽误导。


八、踩坑与排障(真实的坑)

8.1 mc 精简镜像没有 grep

我最初把整段测试塞进一个minio/mc容器的sh -c '...'里,想用mc admin info cl | grep -iE "Erasure..."过滤。结果:

[stderr] sh: line 28: grep: command not found

minio/mc是基于精简基础镜像的,里面没有 grep、awk 这类 GNU 工具。解决:把grep/过滤交给宿主机 bash,每条 mc 命令用独立容器执行(见scripts/minio_failover_test.shMCV()函数)。

8.2 内联 shell 含中英文括号导致 syntax error

更早的版本里,我在sh -c的多行脚本里写了中文括号注释(如(预期 4 online / 2 offline)),shell 把中文全角括号当成了语法结构,直接syntax error。教训:写进容器执行的脚本保持纯 ASCII,注释拿到宿主机 bash 层输出。最终方案是每个MCV调用只跑一条 mc 命令,echo 说明文字由 n1 宿主机的 bash 负责。

8.3 node2 被 pam_faillock 锁定的运维教训

本集群的"四节点变三节点"不是设计,是事故:编写批量部署脚本时,对 node2 的并发 SSH 连接次数过多,触发了 Ubuntu 默认的pam_faillock,root 被锁。这暴露两个问题:

  1. 自动化脚本要有重试/并发上限,别用for循环对同主机猛打 SSH。
  2. 生产环境关键节点要预留带外通道(如云控制台的 VNC/串口),否则 root 被 pam 锁死时,你连"进去解鎖"的门都没有。

最终 MinIO 用 n1/n3/n4 三节点照样把容错演练跑通,反而说明良好设计的分布式系统对单点缺失有韧性——但这韧性不该被用来为运维疏忽买单。


九、自建 MinIO vs 云 OSS/OBS/S3:成本与场景

维度自建 MinIO(本实验)云 OBS/OSS/S3
存储成本仅付 FlexusX 实例 + 云盘费,无流量/请求费按量存储费 + 公网流出费 + API 请求费
可用性 SLA靠自己运维,EC:3 容忍 3 盘坏,但无官方 SLA通常 99.9%~99.99% SLA,厂商兜底
运维负担你要管升级、监控、扩盘、故障切换基本零运维
公网访问需自己配反代/HTTPS/鉴权原生 HTTPS + 细粒度 ACL + CDN
适用性内网大数据底座、合规数据不出域、成本敏感且量大公网分发、托管静态站、与云上其他 PaaS 联动

我的观点:数据量大、主要在 VPC 内流转、且对"数据不出私有环境"有合规要求时,自建 MinIO 长期成本明显更低,且控制权完全在自己手里;但若要公网分发、要省心、要 SLA,直接用云厂商对象存储。别为了"显得技术强"而自建一个你没精力运维的对象存储——它出问题时,背锅的是你。


十、小结

本篇在华为云 FlexusX 三节点上跑通了 MinIO 分布式纠删码集群(6 盘、EC:3),并用真实故障注入证明了:

  • 健康态 6 盘在线,20MB 对象上传 244.21 MiB/s,ETag316f5c3cf34e6206e74aaeb58001dd98-2
  • 停掉 1 节点(2 盘离线)后集群仍可读、可写、可下载,20MB 下载 463.13 MiB/s、字节数精确20971520
  • docker start后自动自愈回 6 盘在线。

纠删码不是魔法,它用算力换空间:在容忍同样多故障的前提下,比多副本省一大笔盘。但省下的盘钱,要拿运维精力来填。


参考脚本(本篇命令均来自仓库scripts/):

  • scripts/minio_start.sh—— 三节点分布式启动
  • scripts/minio_test.sh—— S3 功能与纠删码验证
  • scripts/minio_failover_test.sh—— 容错演练
  • 实测结果:results/12_minio.txtresults/13_minio_failover.txt

下一篇(八)我们切到另一个 PaaS 核心:PostgreSQL 16 流复制主从架构实战。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/28 17:22:21

企业AI知识库搭建实战指南:架构设计与核心模块实现

企业AI知识库搭建实战指南:架构设计与核心模块实现 [配图:企业AI知识库系统架构总览图,展示各核心模块及其交互关系] 引言 大模型时代,企业AI知识库成为数字化基础设施的重要一环。但"搭建"二字的分量,远不止…

作者头像 李华
网站建设 2026/7/28 17:21:59

React组件化开发:核心原则与高级实践

1. React组件化开发的核心价值 在当今前端开发领域,React的组件化思想已经彻底改变了我们构建用户界面的方式。作为一名长期使用React的开发者,我深刻体会到组件化开发带来的效率提升和代码可维护性优势。当我们需要创建一个按钮时,不再需要重…

作者头像 李华
网站建设 2026/7/28 17:21:16

半年170起!公安部重拳出击AI造谣-当虚假信息用上AI,真相还有多少时间?

半年170起!公安部重拳出击AI造谣——当虚假信息用上AI,真相还有多少时间? 治理升级国务院新闻发布会190余人被查处 7月28日,公安部在国务院新闻办公室发布会上公布了一组数据:今年上半年,共侦办利用AI工具生成网络谣言案件170余起,依法查处190余人。 同时,开展AI应用…

作者头像 李华
网站建设 2026/7/28 17:20:17

3步搞定碧蓝航线全皮肤解锁:Perseus原生库终极指南

3步搞定碧蓝航线全皮肤解锁:Perseus原生库终极指南 【免费下载链接】Perseus Azur Lane scripts patcher. 项目地址: https://gitcode.com/gh_mirrors/pers/Perseus 还在为碧蓝航线中那些精美的限定皮肤无法体验而烦恼吗?Perseus原生库补丁为您提…

作者头像 李华
网站建设 2026/7/28 17:19:25

AI Agent技术解析:从LLM到智能体架构的演进与实践

1. AI Agent技术全景解析:从LLM到智能体架构的演进路径 在2023年的大模型技术爆发后,AI Agent(人工智能代理)正在成为继ChatGPT之后最受开发者关注的技术方向。不同于传统单次问答的LLM交互,AI Agent通过多轮决策、工具…

作者头像 李华
网站建设 2026/7/28 17:18:31

美团LongCat-2.0 MoE模型解析:ASIC训练与OpenRouter实践指南

上周在 OpenRouter 上测试几个新模型时,我注意到一个叫 “Owl Alpha” 的模型在推理和代码任务上表现异常稳定,响应速度快,而且成本控制得相当不错。当时没太在意,直到后来看到社区讨论,才发现它背后竟然是美团开源的 LongCat-2.0——一个拥有 1.6 万亿参数的混合专家模型…

作者头像 李华