简介:这是一份面向HPC初学者、系统架构师与运维工程师的高性能计算架构设计参考文档,围绕HPC基础概念、系统组成与主流技术路线展开,帮助读者建立从计算、存储、网络到集群软件的完整认知框架。内容涵盖HPC分类方式(高吞吐计算与分布计算)、X86处理器与Linux操作系统的主流选型、刀片系统构建方式、IB与10GE互联网络,以及MPI节点、胖节点、GPU加速节点三类计算节点的定位差异,并延伸至CPU性能计算公式、Linpack基准测试、DIMM内存类型等关键知识点。资源包为1个docx文档,约979KB,结构紧凑,适合作为技术入门与方案梳理的案头资料。目前已有225人学习,读者可借此快速掌握HPC性能衡量方法、GPU加速原理及气象预报、材料科学、生命科学、金融分析等典型应用场景,为架构选型与方案设计提供参考。
1. 从一份 docx 说起:HPC 高性能计算架构设计到底在解决什么问题
很多人第一次接触 HPC 高性能计算架构设计,是从一份名为HPC高性能计算架构设计.docx的文档开始的。它可能来自某个内部立项、某次技术评审,或者某个甲方甩过来的需求附件。文档本身不神秘,真正让人头疼的是:看完之后不知道从哪下手——集群怎么搭、网络怎么选、存储怎么配、调度器用哪个、运维怎么兜底,这些问题文档里往往只给了名词,没给路径。
HPC 高性能计算架构设计要解决的核心问题,是把一堆 CPU、GPU、高速网络和并行存储组织成一台“逻辑上的超级计算机”,让气象预报、CAE 仿真、分子动力学、AI 大模型训练这类算力密集型任务,能在可接受的时间内跑完,并且跑得稳、跑得可复现。它适合两类人:一类是正在从零搭建或改造计算集群的工程师,另一类是接手了别人集群、需要做架构评审和性能调优的运维人员。
这份文档标题里没有写具体行业,但架构设计的通用逻辑是相通的。下面我按“先立住理论、再动手复现、最后讲坑”的顺序,把 HPC 架构设计拆成能落地的步骤。你不需要先看完那份 docx,跟着走也能把最小可用集群跑起来。
2. HPC 架构的四层骨架:计算、网络、存储、调度怎么选
2.1 计算节点选型:CPU 主频、核数与 GPU 加速比的取舍
HPC 集群的计算节点不是越贵越好,而是要看任务特征。CFD 类任务通常吃内存带宽和核间通信,主频高、核数适中(32~64 核)的 CPU 节点往往比 128 核低频节点更快;AI 训练类任务则更依赖 GPU 的显存和 NVLink 带宽。常见做法是分池:CPU 池跑传统 MPI 任务,GPU 池跑 PyTorch/TensorFlow 任务,通过调度器统一纳管。
选型时先算一笔账:假设你有 100 万核时/月的需求,单节点 64 核、利用率 70%,那么需要约 1000000 / (64 × 24 × 30 × 0.7) ≈ 31 个节点。这个粗算能帮你判断预算量级,避免一开始就拍脑袋买机器。
提示:不要忽略内存配比。CFD 任务常见配比是每核 4~8GB 内存,AI 训练节点则按 GPU 显存 2~4 倍配系统内存,否则会出现“CPU 等内存”的假性瓶颈。
2.2 网络互联:InfiniBand 与 RoCE 的实测差异和选型边界
HPC 的网络不是“能通就行”,而是决定并行效率的关键。MPI 集合通信(Allreduce、Alltoall)对延迟和带宽极其敏感。InfiniBand 的延迟通常在 1~2 微秒,RoCEv2 在 3~5 微秒,看起来差距不大,但在 512 节点以上的大规模并行任务里,累积延迟会直接吃掉 20% 以上的加速比。
选型边界很清晰:节点数少于 32、任务以单机多卡为主,RoCE 足够且成本低;节点数超过 64、频繁跨节点 MPI 通信,优先 InfiniBand。如果预算卡在中间,可以计算节点用 IB、管理网络用万兆以太网,这是最常见的混合做法。
2.3 并行存储:Lustre、GPFS 与 NFS 的适用场景
存储是 HPC 架构里最容易翻车的一层。NFS 在小规模(10 节点以内)还能凑合,一旦并发写超过 20 个节点,元数据服务就会成为黑匣子式的瓶颈。Lustre 和 GPFS 是主流并行文件系统,前者生态开放、社区资料多,后者在 IBM 生态里集成度高。
一个可抄的配置思路:元数据节点(MDS)用 NVMe SSD 做元数据盘,对象存储节点(OSS)用 8~12 块大容量 HDD 做 RAID6,单 OSS 带宽目标 2~4GB/s。客户端挂载时务必调大max_read_ahead和max_write参数,否则默认值会让顺序读写性能打对折。
2.4 调度器:Slurm 与 PBS 的配置差异与迁移成本
Slurm 是目前新建集群的首选,配置灵活、社区活跃;PBS Pro 在传统超算和企业环境里仍有存量。两者核心概念对应关系是:Slurm 的 partition 对应 PBS 的 queue,Slurm 的sbatch对应 PBS 的qsub。
迁移时最大的坑是资源限制语法不同。Slurm 用--mem-per-cpu,PBS 用-l mem=;Slurm 的 GPU 申请是--gres=gpu:2,PBS 是-l ngpus=2。如果脚本里硬编码了调度器指令,迁移时需要逐行改写,建议一开始就用环境变量或包装脚本隔离。
3. 从零跑通一个最小 HPC 集群:Slurm + MPI 实操
3.1 三节点集群的硬件与系统准备
先准备 3 台机器:1 台管理/登录节点,2 台计算节点。系统统一用 Rocky Linux 9 或 Ubuntu 22.04,关闭 SELinux 和防火墙(内网环境),配置主机名和 hosts 解析。三台机器之间用万兆交换机互联,管理节点额外挂一块 SSD 做共享存储。
基础环境命令如下:
# 三台机器统一执行:设置主机名和 hosts hostnamectl set-hostname hpc-master # 计算节点改为 hpc-node01 / hpc-node02 cat >> /etc/hosts <<'EOF' 192.168.1.10 hpc-master 192.168.1.11 hpc-node01 192.168.1.12 hpc-node02 EOF # 关闭 SELinux 和防火墙(内网测试环境) setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config systemctl stop firewalld && systemctl disable firewalld # 配置免密登录:管理节点生成密钥并分发 ssh-keygen -t ed25519 -N '' -f /root/.ssh/id_ed25519 for node in hpc-node01 hpc-node02; do ssh-copy-id -i /root/.ssh/id_ed25519.pub root@$node done这段脚本做了三件事:统一主机名和解析、关闭安全组件避免 MPI 通信被拦截、配置 root 免密登录。参数上,ed25519比 RSA 更短更快,-N ''表示空密码,适合内网自动化。注意生产环境不要直接关防火墙,而是按端口放行 Slurm 的 6817/6818 和 MPI 的动态端口段。
3.2 Slurm 的安装与 slurm.conf 关键参数
管理节点和计算节点都安装 Slurm,但角色不同。管理节点跑slurmctld,计算节点跑slurmd。
# 所有节点安装 Slurm dnf install -y slurm slurm-devel munge munge-devel # 生成 munge key 并分发(所有节点一致) dd if=/dev/urandom bs=1 count=1024 > /etc/munge/munge.key chown munge:munge /etc/munge/munge.key chmod 400 /etc/munge/munge.key scp /etc/munge/munge.key root@hpc-node01:/etc/munge/ scp /etc/munge/munge.key root@hpc-node02:/etc/munge/ # 所有节点启动 munge systemctl enable --now mungeslurm.conf是核心配置文件,管理节点和计算节点必须完全一致。最小可用配置如下:
# /etc/slurm/slurm.conf ClusterName=hpc-lab SlurmctldHost=hpc-master SlurmUser=slurm SlurmdUser=root AuthType=auth/munge StateSaveLocation=/var/spool/slurmctld SlurmdSpoolDir=/var/spool/slurmd SchedulerType=sched/backfill SelectType=select/cons_tres SelectTypeParameters=CR_Core_Memory NodeName=hpc-node01 CPUs=32 RealMemory=64000 State=UNKNOWN NodeName=hpc-node02 CPUs=32 RealMemory=64000 State=UNKNOWN PartitionName=cpu Nodes=hpc-node01,hpc-node02 Default=YES MaxTime=INFINITE State=UP关键参数说明:SelectType=select/cons_tres表示按核和内存做资源分配,比默认的按节点分配更精细;SchedulerType=sched/backfill开启回填调度,能利用大任务等待间隙跑小任务,提升利用率;RealMemory单位是 MB,要略小于物理内存,给系统留余量。配置完成后,管理节点启动slurmctld,计算节点启动slurmd,用sinfo验证节点状态是否为idle。
3.3 MPI 程序编译与 sbatch 提交模板
装好 OpenMPI 或 MPICH,编译一个最简单的 MPI 程序验证跨节点通信:
# 所有节点安装 OpenMPI dnf install -y openmpi openmpi-devel echo 'export PATH=/usr/lib64/openmpi/bin:$PATH' >> /etc/profile.d/openmpi.sh echo 'export LD_LIBRARY_PATH=/usr/lib64/openmpi/lib:$LD_LIBRARY_PATH' >> /etc/profile.d/openmpi.sh source /etc/profile.d/openmpi.sh/* hello_mpi.c:打印每个进程所在节点和 rank */ #include <mpi.h> #include <stdio.h> #include <unistd.h> int main(int argc, char** argv) { MPI_Init(&argc, &argv); int rank, size; char hostname[256]; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); gethostname(hostname, sizeof(hostname)); printf("Rank %d of %d on %s\n", rank, size, hostname); MPI_Finalize(); return 0; }编译命令:mpicc -O2 -o hello_mpi hello_mpi.c。然后用 sbatch 提交:
#!/bin/bash #SBATCH --job-name=mpi-test #SBATCH --nodes=2 #SBATCH --ntasks-per-node=4 #SBATCH --partition=cpu #SBATCH --time=00:05:00 #SBATCH --output=mpi-test-%j.log module load mpi/openmpi-x86_64 mpirun -np 8 --hostfile $SLURM_JOB_NODELIST hello_mpi--nodes=2和--ntasks-per-node=4表示跨 2 个节点各起 4 个进程,共 8 个 rank。$SLURM_JOB_NODELIST是 Slurm 自动生成的主机列表,避免手写 hostfile。提交后看日志,如果 8 个 rank 分布在两台机器上,说明 MPI 跨节点通信已经通了。这一步跑通,最小 HPC 集群就算立住了。
4. 性能调优与运维:让集群从“能跑”到“跑得快、跑得稳”
4.1 用 perf 和 IPM 定位 MPI 通信瓶颈
集群能跑之后,下一步是看它跑得怎么样。MPI 程序最常见的性能问题是集合通信不均衡。用 IPM(Integrated Performance Monitoring)可以低开销地采集每个 rank 的通信时间占比:
# 安装 IPM 后,在 sbatch 脚本里替换 mpirun mpirun -np 8 -genv IPM_LOG=full ipm_hello_mpi # 运行结束后生成 root.ipm.xml,用 ipm_parse 转成文本报告 ipm_parse -html root.ipm.xml报告里重点看MPI_Allreduce和MPI_Barrier的时间占比。如果 Allreduce 超过总时间 30%,说明网络或算法需要优化,常见手段是换用MPI_Allreduce的分层算法,或者检查是否误用了全局同步。
4.2 存储 IO 的 fio 基准测试与 Lustre 参数调整
存储性能不能靠感觉,要用 fio 压出来。在计算节点上对共享存储做顺序写测试:
# 顺序写:1M 块大小,8 个并发任务,跑 60 秒 fio --name=seqwrite --directory=/shared/test \ --rw=write --bs=1M --size=10G --numjobs=8 \ --time_based --runtime=60 --group_reporting # 随机读:4K 块大小,32 队列深度 fio --name=randread --directory=/shared/test \ --rw=randread --bs=4k --size=10G --numjobs=32 \ --iodepth=32 --time_based --runtime=60 --group_reporting如果顺序写带宽低于 1GB/s,先查 OSS 的 RAID 条带和网络是否跑满;如果随机读 IOPS 低于 5000,检查 MDS 的元数据盘是否成为瓶颈。Lustre 客户端侧可以调/etc/lustre/下的max_read_ahead_mb和max_write_mb,通常设成 64~128 能明显改善大文件吞吐。
4.3 节点健康检查与作业重排队机制
HPC 集群最怕的是“僵尸节点”——Slurm 显示 idle,但实际 SSH 不通或 GPU 掉卡。常见做法是写一个定时巡检脚本,结合sinfo和pdsh批量检查:
#!/bin/bash # health_check.sh:检查所有计算节点连通性和 GPU 状态 for node in $(sinfo -N -h -o "%N"); do if ! ssh -o ConnectTimeout=5 $node "nvidia-smi -L" &>/dev/null; then echo "[$(date)] $node GPU check FAILED, draining" scontrol update NodeName=$node State=DRAIN Reason="health_check_failed" fi done配合 Slurm 的ReturnToService=2参数,节点被 drain 后如果 slurmd 重新注册成功,会自动恢复服务。作业侧建议在 sbatch 里加--requeue,节点故障时作业自动重排队,避免人工重提。
5. 避坑与排查:HPC 架构设计里最容易翻车的 5 个点
5.1 现象:MPI 程序跨节点运行报“Permission denied (publickey)”
原因:Slurm 和 MPI 的认证体系是两套。Slurm 用 munge 认证,MPI 的mpirun默认走 SSH,如果计算节点之间没有配置免密,跨节点启动就会失败。
解决:要么在所有计算节点之间配置 root 或专用用户的 SSH 免密,要么在mpirun时指定--mca plm_rsh_agent "ssh -q"并确保密钥已分发。更彻底的做法是用 Slurm 的srun替代mpirun,直接复用 Slurm 的认证通道。
5.2 现象:作业提交后一直 PENDING,Reason 显示“Resources”
原因:分区资源被占满,或者MaxTime设置过短导致大作业永远排不上。也可能是SelectType配置为按节点分配,而节点内存碎片化严重。
解决:用scontrol show job <jobid>看具体原因;用sinfo -o "%P %a %l %D %t %N"看分区状态。如果是内存碎片,把SelectType改成cons_tres并开启CR_Core_Memory;如果是 MaxTime 限制,调整分区或作业的--time。
5.3 现象:Lustre 挂载后写入速度只有几十 MB/s
原因:客户端挂载参数默认值保守,或者 OSS 的 RAID 条带宽度与块大小不匹配。也可能是网络走了管理网而不是高速网。
解决:检查lctl get_param osc.*.max_write和max_read_ahead,调大到 64MB 以上;确认 Lustre 的lnet网络接口绑定的是 IB 或万兆网卡,而不是 1G 管理口;RAID 条带建议 256KB~1MB,与 Lustre 的stripe_size对齐。
5.4 现象:GPU 节点跑训练任务时随机掉卡,dmesg 报 Xid 错误
原因:常见于 GPU 散热不良、PCIe 链路降速或驱动版本与 CUDA 不匹配。Xid 48 通常是 ECC 错误,Xid 79 是 GPU 掉总线。
解决:先查nvidia-smi -q的 ECC 错误计数和 PCIe 链路宽度;如果是散热问题,清理风道或调高风扇曲线;驱动和 CUDA 版本严格按 NVIDIA 兼容性矩阵来,不要混用。掉卡频繁的节点直接 drain 送修,不要带病运行。
5.5 现象:Slurm 控制节点重启后,所有作业状态丢失
原因:StateSaveLocation指向的目录没有持久化,或者slurmctld启动时没有正确加载状态文件。
解决:确保/var/spool/slurmctld在本地 SSD 或共享存储上,并且slurmctld有写权限;重启前用scontrol reconfigure而不是直接 kill;生产环境建议配slurmdbd+ MySQL 做作业记账,即使控制节点挂了也能从数据库恢复历史。
6. 进阶技巧:用 cgroup 做作业级资源隔离与能耗监控
最小集群跑通之后,真正拉开架构水平的是资源隔离和能耗控制。Slurm 默认只做逻辑分配,不阻止作业超用内存或 CPU。开启 cgroup 后,每个作业的 CPU、内存、甚至 GPU 都能被硬限制,避免“一个作业拖垮整个节点”。
配置分两步。第一步,在slurm.conf里加:
ProctrackType=proctrack/cgroup TaskPlugin=task/cgroup ConstrainCores=yes ConstrainRAMSpace=yes ConstrainSwapSpace=yes第二步,在计算节点创建/etc/slurm/cgroup.conf:
CgroupAutomount=yes ConstrainCores=yes ConstrainRAMSpace=yes AllowedRAMSpace=100 AllowedSwapSpace=0AllowedRAMSpace=100表示允许使用申请内存的 100%,超过就 OOM kill;AllowedSwapSpace=0禁止用 swap,防止作业被换出后性能断崖。改完systemctl restart slurmd,再用systemd-cgtop就能看到每个作业的实时资源占用。
能耗监控方面,如果节点支持 IPMI,可以用ipmitool采集整机功耗,结合 Slurm 的sacct数据算出每个作业的能效比(性能/瓦特):
# 采集节点功耗(需要 IPMI 权限) ipmitool -I lanplus -H 192.168.1.11 -U admin -P password dcmi power reading # 结合 sacct 看作业耗时和 CPU 时间 sacct -j <jobid> --format=JobID,Elapsed,TotalCPU,MaxRSS,State把功耗和作业数据按天聚合,就能识别出哪些用户或哪些代码在“空转烧电”。我一般会设一个阈值:如果某作业的 CPU 利用率低于 30% 且持续超过 1 小时,就发提醒给提交者。这个习惯帮我省过不少电费,也逼着大家把串行代码改成并行。
最后说一句血泪经验:HPC 架构设计里,最贵的不是硬件,是返工。网络选型、存储配比、调度器参数这三件事,一旦上线后再改,迁移成本往往是初始投入的数倍。所以宁可前期多花两周做基准测试和 PoC,也不要拍脑袋上生产。希望帮到你。
本文还有配套的精品资源,点击获取