1. 高性能计算集群到底在解决什么问题
先说个很多人容易混淆的点:高性能计算集群和普通服务器集群,本质上是两种思路。普通集群(比如 Kafka 集群、Redis 集群、Kubernetes 集群)追求的是高可用和水平扩展,核心诉求是"挂了能扛、流量大了能加节点";而高性能计算集群,也就是 HPC 集群,追求的是算力的极限释放——把成百上千个 CPU 核心、GPU 加速卡组合起来,去求解单个节点根本算不动的科学计算问题。
打个不恰当的比方:前者像开连锁店,一家店忙不过来就多开几家;后者像把几十个顶级厨师集中到一个厨房,合力做一桌满汉全席还要求半小时内出锅。后者对"协作效率"的苛刻程度,是前者完全没法比的。
所以,如果你手里有这些需求,大概率会走上 HPC 集群这条路:
- 科学计算与仿真:流体力学、分子动力学、天气模式计算、有限元分析,这些领域动不动就需要几千核并行跑几天。
- AI 大模型训练与推理:单卡 A100/H100 已经撑不住动辄几十上百亿参数的模型,需要多卡多机通过高速互联协同训练,相关的话题比如"rk3588 部署 yolov8"、"deepseek 本地部署"和"大模型部署"其实都属于这类需求的一个侧面。
- 大规模数据处理:Hadoop、Spark 这类大数据框架虽然和传统 HPC 有区别,但部署基础设施时的思路——存储怎么共享、节点怎么管理、任务怎么调度——高度相似。
- 渲染农场 / 基因测序 / 金融风险模拟:每个场景都有自己独特的业务特征,但底层对"集群能力"的依赖是相同的。
这篇文章我会直接用一套真实场景来描述——从硬件选型、网络设计、操作系统配置到作业调度系统搭建,再到性能验证和常见坑位排查。写这篇的时候我已经把架构思路收敛到了当前最主流的方案:Rocky Linux 9 作为操作系统,Slurm 作为作业调度器,共享存储采用 NFS/GPFS 方案,网络走 InfiniBand 或高速以太网。这套组合在工业界和研究机构里的覆盖率非常高,选它作为"标准答案"来讲,大家以后出去面对任何集群都不心虚。
2. 硬件选型与网络设计:预算花在刀刃上
2.1 算力节点的关键取舍:CPU 主频 vs 核心数
很多第一次搭集群的人会纠结一个问题:同样预算,买 32 核的机器还是买 64 核的机器?
我的答案是:看你的负载特征,不要在没想清楚之前就盲目堆核。
如果跑的是分子动力学、有限元这类通信密集型的 MPI 程序,核心之间需要频繁同步数据,那么高频、单核性能强的 CPU 比单纯堆核数更管用;反过来,如果跑的是参数扫描、批处理任务,每个任务天然独立不通信,那核数越多越好,因为并行度非常充足。
具体到型号选择,Intel Xeon 和 AMD EPYC 是两大主流阵营,以 EPYC 9004 系列为例,单颗最高可以到 96 核 128 核。但注意,核心数翻倍不代表性能翻倍,因为内存带宽会成为瓶颈。所以内存通道数、内存频率和容量配比,往往比 CPU 本身更能决定系统的真实表现。我见过太多人把预算全砸在 CPU 上,结果内存带宽不够导致计算效率只有理论峰值的一半,这种教训太贵了。
给一个普适性的参考配比:
| 组件 | 建议配置 | 说明 |
|---|---|---|
| CPU | 2 × 32 核 2.5GHz+(Intel Xeon 或 AMD EPYC) | 平衡主频与核心数 |
| 内存 | 每物理核 4~8 GB | 计算节点适可而止,内存计算节点加大 |
| 系统盘 | 2× 480GB SSD RAID1 | 避免单盘故障导致重装系统 |
| 本地数据盘 | 2× 1.92TB NVMe SSD 或更高 | 用于临时文件,不要存重要数据 |
| GPU(可选) | NVIDIA A100/H100/L20S 或国产加速卡 | 按业务需要决定是否上 GPU |
2.2 网络互联:InfiniBand 和高速以太网,到底怎么选
这是集群部署里面最容易踩坑的一环。很多团队为了省钱,直接用千兆以太网把几十台机器连起来就开工了,结果 MPI 跑起来之后效率惨不忍睹——程序 80% 的时间在等待网络同步,计算单元全部在空转。
为什么会这样?因为 HPC 集群里节点间通信极其频繁。你跑一个需要 1000 个核心协同的作业,每个时间步都要做一轮全局数据交换,千兆网(理论 1Gb/s,实际 900Mb/s 左右)传输 1MB 数据就要 8ms 以上,2000 个核心每个时间步都等这 8ms,算下来一天要多浪费多少时间?答案是数以小时计。
所以,高性能计算集群的网络选型,我给出三条路线:
- InfiniBand(IB):HPC 领域的绝对王者,时延 0.5~1.3μs,带宽从 HDR100(100Gbps)到 NDR400(400Gbps),配合 RDMA 技术可以绕过内核直接进行内存到内存的数据传输。缺点是真贵,一个 HDR 交换机加网卡算下来,小集群也要几十万。
- RoCEv2(RDMA over Converged Ethernet):基于普通以太网的 RDMA 方案,40Gbps/100Gbps 的网卡加支持 PFC(优先流控)的交换机,成本和 IB 比能省一半左右,时延略高但在很多场景下性能接近 IB。
- 传统 TCP/IP 高速以太网:25GbE、100GbE 也能用,适合通信不那么密集的场景。配置最简单,但跑大规模 MPI 作业时要做好性能下降的心理准备。
我个人建议:如果预算允许、未来 3~5 年算力需求会持续增长,优先上 IB。如果预算卡得死,RoCEv2 是性价比最优的妥协方案。最忌讳的是先买了一堆千兆交换机,最后发现整套集群被网络卡死,然后被迫返工。
2.3 存储架构:共享存储决定了集群的"使用体验"
集群存储和单机存储的思路完全不同。一个集群里面经常有几十上百个节点,用户提交作业后,作业落在哪个节点上是调度器随机决定的。如果每个节点存各自的数据、没有共享存储,那么用户在登录节点上传的数据计算节点根本看不到,这个集群就没法用。
所以 HPC 集群必须有并行文件系统或网络文件系统。主流方案:
- NFS:最简单,部署快,但单点性能有限,适合 20 个节点以内的中小集群。
- IBM GPFS(现为 Storage Scale):工业级方案,性能和扩展性都很强,但授权费用不菲。
- Lustre:开源并行文件系统,被大量超算中心使用,适合大规模场景,但部署运维难度高。
- BeeGFS:另一个开源选择,比 Lustre 简单不少,性能也可圈可点。
- CephFS:如果团队本身已经熟悉 Ceph,也可以考虑,性能上需要调优。
这里先说一个最关键的架构判断:计算节点上的本地盘绝对不要当数据盘用。本地盘的正确用法是存放临时文件,比如作业运行时产生的中间结果,作业跑完自动清理。真正的数据必须放在共享存储上,否则一旦某个计算节点宕机,上面没来得及同步的数据就全部丢失了。这个教训我是亲眼见过的,某课题组辛辛苦苦算了三天的临时数据存在本地盘上,系统崩溃后全没了,负责运维的人差点背大锅。
3. 操作系统与基础软件栈:把地基打牢
3.1 为什么选 Rocky Linux 9 而不是其它系统
CentOS 停更之后,社区里一度很混乱,有人转 Ubuntu,有人投奔 Debian,有人试了 AlmaLinux,还有人坚守 CentOS 7 不肯挪窝。但在 HPC 领域,Red Hat 兼容发行版依然是最稳妥的选择,Rocky Linux 9 是当前我最推荐的地基。
原因很朴素:
- 硬件厂商支持最好:InfiniBand 网卡的驱动、GPU 驱动、BIOS 固件工具,几乎都是优先验证 RHEL 兼容系统,用 Rocky 9 意味着踩坑最少。
- 和 EL9 的软件生态完全兼容:EPEL、RHEL 的科学计算软件源(如 OpenHPC 仓库)都直接支持,装 MPICH、OpenMPI、SLURM 就是一条命令的事。
- 生命周期长:每个大版本支持 10 年,对于一台要用 5 年以上的计算节点来说,不需要频繁做大版本升级。
有人可能会问,Ubuntu 不是更新更好用吗?如果你只是搭一个实验环境,Ubuntu 没问题。但在生产集群里,驱动兼容性、安全更新机制、系统管理工具链,Rocky/RHEL 系的成熟度确实高一个等级。对于一个 24x7 跑生产的集群来说,"稳妥"比"新颖"重要得多。
3.2 集群软件栈的分层结构
从裸机到能跑作业,中间要装的东西可以分为几层,每层解决不同的问题:
- 基础系统层:操作系统、内核参数优化、BIOS 固件、电源管理策略(高性能模式)。
- 硬件驱动层:IB 网卡驱动(mlnx-ofed)、GPU 驱动(NVIDIA CUDA)、存储卡驱动(如果是 HBA 卡要装对应的驱动)。
- 通信库层:MPI 实现,最主流的有 Intel MPI、OpenMPI、MPICH。这一步是 HPC 的灵魂,因为上层科学计算程序几乎全部依赖 MPI 做跨节点通信。
- 调度管理层:Slurm,负责接受用户作业、分配计算资源、管理队列优先级。类似 Kubernetes 之于容器,但设计哲学更朴素、更稳定。
- 应用软件层:GROMACS、VASP、ANSYS 这类具体的科学计算软件,或者 Python/深度学习框架。这些软件和 MPI、CUDA 库的版本兼容关系极其严格,经常需要按应用需求单独建环境。
我的建议是把这些层分开装、分开维护,尤其不要为了省事把应用层的东西直接装进系统环境。因为不同应用对同一库的版本要求经常互相冲突,最后环境炸了根本不知道去怪谁。业界标准做法是把各层分开管理,应用层用 Module 机制(Environment Modules)动态切换环境,后文会提。
3.3 最容易忽略的硬件配置细节
这里想说几个装系统时 100% 会被忽视、但后期影响巨大的细节:
- BIOS 里开 Performance Mode / 关掉 C-States:否则 CPU 频率动态调节可能导致 MPI 任务各节点性能不均衡,拖慢整个并行作业。你不想让一个节点因为内核省电策略跑得比别的节点慢 20% 吧。
- 打开 VT-d / IOMMU:只有打开才能在集群里安稳地做 GPU 直通、RDMA 等高级功能。
- NUMA 架构理解:AMD EPYC 和 Intel Ice Lake 之后基本都是多 NUMA 节点架构。跑内存密集型任务时,如果线程和内存分配的 NUMA 节点不匹配,内存访问延迟可能翻倍。最好在跑 MPI 作业时用
numactl --interleave=all或按作业拓扑绑核。 - 系统日志和时间同步:提前在装机阶段把 chrony 配好,所有节点统一时间源。集群的调度器、文件系统、MPI 运行库对时间同步都有依赖,时间跳变会导致作业莫名其妙的失败。
4. 集群部署实施:从裸机到可用集群
4.1 节点规划与操作系统批量安装
假设你有 8 台机器,我的部署策略是:
- 1 台管理/登录节点,负责用户登录、作业提交、文件共享,不需要太强的算力,但要内存大、硬盘可靠。
- 6 台计算节点,全部算力集中在这里,尽可能统一配置,方便维护和调度。
- 1 台存储节点,如果用 NFS 做共享存储,存储节点可以用一台单独机器加 RAID 阵列,或者直接用一台性能好的机器挂载多块 NVMe。
装系统这件事,一台台手工装也可以,但既然叫"集群",就要用集群的方式去装。两种主流选择:
PXE + Kickstart 批量安装:安装一台基础系统,导出 Kickstart 配置,通过 DHCP/TFTP 让所有节点通过网络自动安装系统。8 台机器半小时内全部装完。
Clonezilla 镜像克隆:先在模板机上装好系统和驱动,然后用 Clonezilla 做磁盘镜像,批量恢复到其他节点。
最关键的注意点是:计算节点的主机名和 IP 分配一定要先规划清楚再动手。比如节点名称就用node01、node02这种统一前缀,IP 也按规律分配(比如 192.168.10.21~26),避免后期因为主机名混乱导致 Slurm 无法正确识别节点。
我给出一个典型的小集群规划表供参考:
| 节点角色 | 主机名 | IP 地址 | 内存 | 存储 |
|---|---|---|---|---|
| 管理/登录 | master | 192.168.10.10 | 128GB | 2×480GB SSD |
| 存储 | storage | 192.168.10.20 | 64GB | 12×16TB HDD (RAID6) |
| 计算节点 1-6 | node01~node06 | 192.168.10.21~26 | 256GB | 2×1.92TB NVMe |
4.2 共享存储部署:NFS 的方案与悬念
对中小规模集群来说,NFS 是上手最快的方案。网上 NFS 配置教程一大堆,我捡重点说。在存储节点上,先做磁盘阵列:为了兼顾容量和性能,建议用 RAID6(至少可以坏两块盘)。文件系统层面建议用xfs,对大文件和高并发有更好的表现。然后导出目录:
# 存储节点 /etc/exports 配置 /data 192.168.10.0/24(rw,sync,no_root_squash,no_subtree_check) /home 192.168.10.0/24(rw,sync,no_root_squash,no_subtree_check)后记,如果你对性能有更高要求,考虑 GPFS/Lustre/BeeGFS。这里必须泼冷水,GPFS 部署非常复杂,建议至少预留一周来搞定。而 NFS 做"能用的集群"完全没有问题,等业务规模起来了再迁移到更高性能的文件系统也不迟。
共享文件系统要规划好层次。/home放每个用户的个人文件,/data放项目数据,/opt可以考虑放集群公共软件。这样划分后的好处是:用户家目录里不会堆满大型数据集,管理起来清爽很多。
4.3 时钟同步与网络基础设施
不要小看时钟同步,集群里节点时间不一致会引发一个极其隐蔽的坑:MPI 作业某个节点延迟几秒完成,其他节点一直在空转等待它,整个作业被带得极慢。Slurm 在节点状态判定上,如果节点的通信超时时间受时钟影响,会出现节点瞬间变 DOWN 的诡异问题。
部署方式:
# 在管理节点上 dnf install chrony -y systemctl enable chronyd systemctl start chronyd # 配置 /etc/chrony.conf,允许内网其他节点同步 allow 192.168.10.0/24计算节点上只要指向管理节点即可:
# /etc/chrony.conf 中设置 server 192.168.10.10 iburst4.4 Slurm 作业调度系统配置
Slurm 是整个集群的"任务分发中枢",相当于 Linux 系统里的 systemd 之于进程,只是它管理的是整个集群的计算资源。我给它一个非常直观的类比:Slurm 就像一个会议室的预约系统,每个计算节点就是会议室,用户提交的作业就像预约单,Slurm 负责分配会议室和时间段,还要处理插队和优先级的事。
安装非常简单(Rocky 9 的 EPEL 源里直接有):
dnf install epel-release -y dnf install slurm slurm-slurmd slurm-slurmctld -y最大的工作量在slurm.conf这个配置文件上。最核心的几项要配好:
# slurm.conf 关键参数 ClusterName=lab-cluster SlurmctldHost=master NodeName=node[01-06] CPUs=64 RealMemory=250000 State=UNKNOWN PartitionName=compute Nodes=node[01-06] Default=YES MaxTime=INFINITE State=UP SelectType=select/cons_tres SelectTypeParameters=CR_Core AccountingStorageType=accounting_storage/none注意这里的CR_Core,意思是核心级别的资源分配。如果你有 6 台 64 核节点,这个配置允许一个用户的任务申请 128 核,也就是跨两台机器,也允许只申请 8 核,非常灵活。还有MaxTime=INFINITE,生产环境一般要根据业务情况给一个上限,免得某些作业一占占几个月。
配好之后启动服务:
systemctl enable slurmctld # 管理节点上 systemctl enable slurmd # 计算节点上启动顺序有讲究,先重启管理节点上的slurmctld,再逐台启动计算节点的slurmd,或者一次性在计算节点systemctl start slurmd即可。启动后可用sinfo查看节点状态,如果显示idle就说明已经成功加入了集群。
4.5 MPI 环境与用户作业提交
Slurm 装完只是骨架,要让用户真正能跑并行程序,MPI 环境是必须的。以 OpenMPI 为例:
dnf install openmpi -y # 注意 Rocky 9 的 openmpi 默认装在 /usr/lib64/openmpi 下 # 用户环境变量需要 export PATH=/usr/lib64/openmpi/bin:$PATH用户的提交脚本,我用一个例子来说明。假设我写了一个 MPI 程序mpi_hello,需要用 128 个核心跑,那提交脚本run.slurm这样写:
#!/bin/bash #SBATCH --job-name=hello #SBATCH --partition=compute #SBATCH --ntasks=128 #SBATCH --time=01:00:00 #SBATCH --output=hello_%j.out module load mpi/openmpi-x86_64 mpirun ./mpi_hello然后sbatch run.slurm提交,squeue查看队列,作业跑完后scancel取消作业,以及sacct查看历史记录。到这里,一个基本的 HPC 集群就已经可以"工作"了。
但要注意,module load mpi/openmpi-x86_64 需要配置环境模块。直接用dnf install openmpi装之后,默认环境变量是黑的,需要在/etc/profile.d/或者通过 Environment Modules 来让用户方便地加载。
5. 集群验收:性能验证与基准测试
5.1 为什么必须做基准测试
很多集群搭完之后,验收标准就是"能跑 MPI 程序"。这远远不够。硬件没问题不代表性能达标,我之前遇到过一种情况:某项目集群跑起来一切正常,但算总账发现性能只到预期的 70%,最后定位到是 IB 网卡的驱动没有启用 RDMA,MPI 走的是 IP over IB,性能损失巨大。
所以,集群搭好后必须做基准测试,用数据说话,我每次都会跑这三项:
1. 带宽和时延测试。用 IB 自带的工具(比如ib_write_bw、ib_write_lat)或者 Intel MPI Benchmarks(IMB),验证高层的 MPI 通信性能:
mpirun -np 2 IMB-MPI1 PingPong这个测试跑两个节点之间的点对点通信,会输出不同消息大小下的带宽和时延。如果配置没问题,IB 环境下 1MB 消息的带宽应该跑到 90% 以上的线速,时延应该在 1~2μs 量级。如果差距过大,那就要回头查驱动和路由了。
2. HPL(High Performance Linpack)测试。HPL 是超算排行榜 TOP500 的官方基准测试,用来衡量浮点计算峰值。它不仅能验证 CPU 算力,还能拉满内存带宽和网络通信,是集群综合性能最可靠的标尺。HPL 的调参比较微妙,需要设置矩阵规模 N、分块大小 NB、通信因子等,新手可以直接用网上现成的调优配置来跑第一次。
3. 存储性能测试。用IOzone或fio压一下共享存储的读写带宽。尤其是你规划 NFS 之后,必须知道单个文件的大带宽读写能到多少,几百个小文件并发的 IOPS 是多少。这些数据决定了你以后跑 IO 密集型任务时的期望值,也可以用来排查是否有人把存储资源消耗殆尽。
5.2 实际测试中可能出现的性能异常
这里有个经典案例,非常值得拿出来讲:MPI 点对点通信带宽正常,但跑 HPL 效率就是上不去,从 80% 掉到 40%。排查过程如下:
- 先用
sinfo确认作业确实落在多个节点上了(有的人配了 Slurm 但所有任务被塞到一个节点,发现不了)。 - 再测同一节点内的多核 MPI 带宽,发现 intra-node 通信没问题。
- 换 inter-node 测试,发现跨节点带宽骤降,基本锁定网络链路问题。
- 用
ibstatus查看 IB 网卡速率,发现只有 SDR(10Gbps),而不是预期的 HDR(200Gbps),说明速率协商出了问题,链路没有跑到最高速率。 - 最终定位到是交换机端口的配置问题,换了一个端口后恢复满速。
这类问题不实际测一遍真的很难发现,因为程序"能跑",但性能完全不符合预期。这也说明了自动化测试脚本在集群验收阶段的关键作用。不要嫌基准测试麻烦,每一项都有它不可替代的价值。
6. 实战中容易踩的坑与排查思路
6.1 共享存储的并发写问题:NFS 的软硬模式之争
NFS 作为共享存储,有几个细节会导致性能大跳水。最常见的是大量小文件并发写入时 NFS 的 inode 分配锁竞争。假设 200 个 MPI 进程同时朝同一个目录写日志,NFS 服务端会频繁处理文件创建和属性更新的元数据操作,性能立刻崩盘。我见过 100MB/s 的吞吐量直接掉到 5MB/s 的实例。
解决思路有几种:
- 不要让所有进程直接写服务器上的同一个目录。规划好项目数据布局,让各节点写各自节点的临时目录,作业结束后再做合并拷贝到共享存储。
- 调整 NFS 挂载参数:
mount -o rw,hard,intr,bg,timeo=600这种方式,hard + intr可以在服务端短时无响应时让进程等待而不是直接报错退出。 - 服务端调优:NFS 服务端
/etc/nfs.conf里调rpc-nfsd的线程数和nfsd的并发数;threads参数调高到 64 或 128,对小文件并发场景有明显提升。
另外特别提醒:不要在生产环境使用soft挂载 NFS。soft模式下,服务端如果因为负载过高延迟超过设置的timeo,客户端会直接返回 IO 错误,MPI 作业瞬间崩掉。而hard模式会持续重试,虽然会卡,但至少作业不会因为一次临时的网络抖动就通盘失败。
6.2 IB 网络最容易踩的坑:PFC 和子网管理器
如果你上了 InfiniBand,有一个概念一定要懂:子网管理器(Subnet Manager,SM)。IB 网络不像以太网那样自动就能通,它需要一个 SM 来扫描网络拓扑、分配 LID(Local IDentifier)。如果物理链路都正常但ibstat显示端口状态为DOWN,那很可能就是 SM 没起来。
解决方案是,在管理节点上装opensm并启动:
dnf install opensm -y systemctl enable opensm systemctl start opensmIB 网络还有一个常见问题是PFC(优先流控)配置不一致导致 RoCE 丢包,当然纯 IB 网络不涉及,但在 RoCE 环境下,交换机上必须开启 PFC,网卡侧也要配置对应的 QoS 策略,否则流量一高就开始丢包,MPI 作业表现为"时延突然暴增、带宽上不去"。这种问题肉眼根本看不出来,只能用ibstat和perftest反复测才能定位。
6.3 Slurm 节点莫名其妙变 DOWN
这是集群运维里最让大家头疼的问题之一。节点明明活着,但sinfo显示down*或drained,所有作业卡在排队状态。排查思路一般是:
- 先看
slurmd进程是否还活着:systemctl status slurmd。通常是服务挂了,或者是节点 load 太高导致 Slurm 健康检查判定异常。 - 查看日志
/var/log/slurm/slurmd.log和slurmctld.log,里面一般会有Node node01 communication timeout之类的字样。 - 确认是否是网络问题。如果管理节点和计算节点之间的网络有抖动,slurmctld 和 slurmd 之间的心跳超时,节点会被自动标记为 DOWN。
解决方式要看根因。如果只是心跳超时导致误判,在slurm.conf里调高SlurmdTimeout(默认可能只有 300 秒,可根据网路质量调到 600 秒)。如果是节点内存被跑满导致 slurmd 无法响应,那就要靠监控系统提前发现,人工干预解决。
6.4 深挖:为什么用户明明提交了 MPI 多机任务,却总是被调度到一个节点上
这是新手集群最常见的"伪问题",现象是用户写了--ntasks=128,提交后squeue看到的作业确实有 128 个任务,但mpirun实际只用了 1 个节点的 128 核。
根因在于 Slurm 的SelectTypeParameters。如果你的配置是CR_Core,MPI 程序在启动时用srun或mpirun的方式会被 Slurm 接管,任务会按 Slurm 分配的资源分布到多个节点。但你如果直接在登录节点上mpirun -np 128 ./app而不是通过sbatch提交,OpenMPI 默认只能看到单个节点上可用的核数,于是全部挤在一个节点上。
正确的做法有两个:
- 在
slurm.conf里设置好正确的SelectType和节点资源,让srun系统原生的并行启动器接管 MPI 进程分发。 - 用户提交脚本里不要写死
mpirun,而应该用srun ./app。如果你必须用 mpirun,就加上参数让 OpenMPI 从 Slurm 获取环境变量:mpirun --mca mpi_affinity_off ./app或者直接依赖 Slurm 的 PMIx 集成。
这个问题的最大原因其实是惯性——很多用户从单机转集群,不习惯用srun启动并行程序,总以为mpirun就是全部。运维人员需要把这套逻辑理清并在集群使用规范里写明白。
7. 集群运维与性能调优的进阶经验
7.1 用监控系统看全局,别等问题找上门
很多人到了集群出问题,第一反应是"哪台机器出事了",而不是"整个集群现在处于什么状态"。我习惯用集群监控工具来进行全局面板管理,比如 Prometheus + Grafana 配合 node_exporter 和 DCGM 做 GPU 监控,可以实时看到每个节点的 CPU/内存/IO/GPU 利用率。
具体的部署方式已经有大量现成文档,我这里更想说的是监控能帮你抓到哪些必须提前处理的隐患:
- 内存用量缓慢攀升:大概率是有进程内存泄漏,趁作业没结束前找到是哪个作业,省得最后节点 OOM 全部任务失败。
- 存储节点带宽长期逼近上限:你的业务 IO 压力和存储性能不匹配,预警你在拖垮整个集群之前扩容。
- IB 端口链路降速:交换机和网卡之间的光模块或线缆状态退化,监控能及时发现并提前更换,等你跑大作业时才发现就晚了。
集群运维的最高境界,就是在用户发现问题之前,先把问题解决掉。
7.2 作业队列优先级策略:怎么避免"一个作业堵死所有作业"
没有作业优先级策略的集群,一旦用户多了就会变成"先到先得,大作业塞满所有资源,小作业等到天荒地老"的灾难现场。Slurm 的优先级策略是必配的配置项,业界常用的是公平树(Fair Tree)和多因素优先级的结合:
PriorityType=priority/multifactor PriorityDecayHalfLife=14-0 PriorityUsageResetPeriod=never PriorityWeightFairshare=100000 PriorityWeightQOS=1000 PriorityWeightPartition=1000这套配置的含义是大致这样:当某个用户的历史用量超过了公平份额时,他的优先级会随时间衰减,从而让长期没用到资源的用户能够插队。说白了,这个机制和"排队太多人时要照顾后到的人"是一个道理。记得PriorityUsageResetPeriod=never,这个参数是让衰耗慢慢积累,而不是每次重置清零,这样才能真正保证公平性。
7.3 容器化和 HPC:一个不可忽视的新方向
最近两年,容器化正在侵入 HPC 领域。理解容器对 HPC 的价值,最直接的方式是想一个场景:用户 A 在集群上装了 TensorFlow 环境,跑通了一个模型;三个月后,用户 B 想在同一个集群上用同一套环境跑数据,但全局环境已经因为各种原因被升级过,他的模型在跑的时候报版本冲突。
这种情况下,容器镜像能够提供可复现的环境。Singularity/Apptainer是 HPC 圈子的主流选择,它和 Kubernetes 里的 Docker 不同,它不需要守护进程,并且能直接访问 IB 设备和 GPU 设备。部署方式很直接:
dnf install apptainer -y apptainer build myenv.sif docker://tensorflow/tensorflow:latest-gpu apptainer exec --nv myenv.sif python train.py在 Slurm 里跑容器的案例也简单,提交脚本里加一行module load apptainer,然后直接在脚本里调用容器命令。容器的优势是根据我的经验,一旦用户习惯了这种"即拉即用"的环境管理方式,他们都会爱上。
个人体会:够劲。容器化之后,集群的环境冲突投诉几乎归零,运维同学不需要再为"这个用户要 Python 3.7,那个用户要 Python 3.11"这种问题和无休止的版本冲突折腾了。但还是提醒一句:容器镜像的存储会占用共享存储空间,要为容器镜像建专属目录并定期清理不用的镜像。
8. 最后的实战建议:小集群起步时的避坑清单
文章的最后,我想把最朴素也最有价值的东西列出来。部署集群这件事,从 0 到 1 的过程很激动人心,但真正考验人的是从 1 到 100——持续稳定运行。我梳理了一份实操落地时会不断用到的清单,每一行都是用真金白银和时间换来的经验:
- 先画拓扑图再动手装机:管理网、业务网、存储网、IB 网,不同网段物理隔离或 VLAN 隔离。拓扑图画清楚了,后面出任何网络问题都是排查的导航图。
- 所有节点的固件版本保持一致:BIOS、网卡固件、磁盘固件,版本不一致会导致同一款机器性能差异很大,而且很难定位。
- 把
/etc/hosts维护好:集群内部不要依赖 DNS 解析,直接在/etc/hosts里写好所有节点的映射。DNS 挂了连带着集群不可用的经历,我不想再体验第二次。 - 定期备份 slurm 配置和数据库:Slurm 的作业记录、用户账户信息都在配置和数据里,硬件的钱都花了,备份的功夫不能省。
- 写一份操作规范文档:哪怕只是给自己看,也要把"如何登录、如何提交作业、数据应该放哪儿、跑完怎么清理"写得明明白白。这项投资越早做,收益越大。
如果只让我留一条建议,那一定是:先从一个小规模集群(比如 4~8 台)完整跑通一遍,再谈扩容。小集群能让你把所有环节——存储、网络、调度、监控——的坑都踩一遍,踩完之后你的排障能力和对系统的理解,远不是看一百篇文章能比的。集群搭起来只是开始,真正让它发挥价值的是后面日复一日的维护和调优。祝开工顺利。