Azure云上构建弹性HPC集群:从InfiniBand网络到Slurm调度的超级计算实践
1. 项目概述:当超级计算成为“自来水”
“超级计算”这个词,听起来总是带着一股高冷、遥远的气息,仿佛只存在于国家实验室、顶尖科研机构,是少数精英科学家才能触及的“神器”。它意味着动辄上万个CPU核心、海量内存、高速互联网络,以及随之而来的天文数字般的采购成本、复杂的运维团队和专属的机房空间。在过去,这确实是事实。但今天,我想和你聊聊一个正在彻底改变游戏规则的事情:如何像打开水龙头一样,按需获取超级计算能力。这个“水龙头”,就是微软的Azure云平台。
这个项目的核心,就是**“Supercomputing on Demand with Microsoft Azure”**。它不是一个具体的软件或硬件产品,而是一种能力、一种模式、一种思维方式的转变。简单来说,它意味着你不再需要去“建造”一个超级计算机,而是可以根据你的研究、仿真或数据分析任务,在云端“租用”一个临时的、规模可大可小的超级计算集群。任务完成后,集群自动释放,你只为实际使用的计算时间付费。这就像是你不需要为了喝一杯水而去买下一个水厂,只需要拧开水龙头,按量付费即可。
那么,谁需要这个“水龙头”呢?范围远比你想的广。首先是传统的科研领域:气候模拟、天体物理、基因测序、新材料发现,这些需要处理PB级数据、运行数万核并行计算的任务是天然的应用场景。其次是工业界:汽车行业的碰撞仿真、流体动力学分析;航空航天领域的空气动力学设计;能源行业的油气勘探地震资料处理;制药公司的分子动力学模拟和药物筛选。最后,甚至是一些新兴的AI领域,比如训练超大规模的视觉或语言模型,其背后的分布式计算需求,本质上也是一种超级计算。
Azure之所以能成为这个“水龙头”的提供者,关键在于它背后整合了三大核心能力:全球化的超大规模数据中心基础设施、专为高性能计算(HPC)优化的虚拟机(VM)系列和裸机实例,以及一整套成熟的、企业级的云服务生态(如网络、存储、调度、安全)。接下来,我们就一层层拆解,看看这个“按需超级计算”的蓝图是如何绘就的,以及在实际操作中,我们该如何拧开这个“水龙头”,并让它流出最符合我们需求的计算资源。
2. 核心架构与资源选型解析
要在云上构建一个“按需”的超级计算环境,绝不是简单地把一堆高性能虚拟机扔在一起就能工作的。它需要一个经过精心设计的、全栈优化的架构。Azure的HPC解决方案,正是围绕计算、网络、存储和管理这四大支柱构建的。
2.1 计算层:从通用核心到专属硬件的光谱选择
计算资源是超级计算的引擎。Azure提供了从通用型到高度专用化的完整光谱,你需要根据计算任务的特性来精准匹配。
2.1.1 通用与计算优化型实例对于许多起步阶段的HPC工作负载,或者那些对单核性能、内存带宽要求不是极端苛刻的应用,HBv3和HC系列虚拟机是绝佳的起点。HBv3系列基于AMD EPYC™ Milan处理器,每个vCPU对应一个物理核心,避免了超线程带来的性能干扰,特别适合对核心间通信延迟敏感的科学计算应用。而HC系列则基于Intel Xeon可扩展处理器,同样提供无超线程的物理核心。选择时的一个关键经验是:如果你的应用代码来自开源社区或商业软件(如ANSYS Fluent、OpenFOAM),务必查阅其官方文档或社区论坛,了解其在AMD和Intel平台上的具体性能表现和编译优化建议。盲目选择“纸面频率更高”的型号,可能因为编译器优化不足而事倍功半。
2.1.2 图形与AI加速实例当你的工作负载涉及大量的矩阵运算、深度学习训练或推理时,NCasT4_v3或ND系列(搭载NVIDIA GPU)就成为必选项。这里有一个重要的细节:不仅要关注GPU的型号(如A100, V100, T4),更要关注GPU之间的互联带宽。例如,对于需要多卡并行训练的大模型,使用支持NVLink高速互联的A100实例,比使用通过PCIe连接的多个V100实例,通信效率可能高出数倍,从而大幅缩短训练时间。在Azure上,ND A100 v4系列就提供了这种优化。
2.1.3 终极性能:HPC专属裸机实例对于追求极致性能和隔离性的任务,Azure提供了HBv3和HC的裸机选项。这是真正的“超级计算”体验:你独享整台物理服务器,没有虚拟化层的任何开销,可以直接访问所有硬件特性,包括InfiniBand网络控制器。裸机实例特别适合那些对延迟抖动极度敏感、或需要自定义内核及驱动程序的极端应用。但请注意,其计费方式通常以整机为单位,成本较高,适合短时间、高强度的“冲刺计算”。
2.2 网络层:InfiniBand与低延迟以太网的抉择
在超级计算中,计算节点之间的通信速度往往直接决定了整个应用的扩展效率。一个在1000个核心上运行完美的应用,可能在10000个核心上因为网络拥堵而寸步难行。
Azure HPC的核心网络优势在于其集成的、基于Mellanox HDR InfiniBand的网络。在HBv3和HC等系列中,InfiniBand不是可选项,而是标准配置。它能提供高达200 Gb/s的单端口带宽,以及亚微秒级的延迟。更重要的是,Azure部署了非阻塞的胖树(Fat Tree)网络拓扑。这意味着,在同一个集群规模内,任意两个节点之间的通信带宽都是有保障的,不会因为“绕路”或链路争抢而显著下降。在创建虚拟机规模集或使用Azure CycleCloud部署集群时,务必确保所有计算节点位于同一个“邻近放置组(Proximity Placement Group, PPG)”和“可用性区域(Availability Zone)”内,这是获得低延迟、高带宽InfiniBand互联的前提条件。
对于不需要InfiniBand极致性能,或者应用本身通信不那么密集的工作负载,Azure也提供了加速网络(Accelerated Networking)支持的以太网,延迟也能达到极低的水平。选型原则很简单:如果你的MPI(消息传递接口)作业在规模扩展时性能下降曲线非常陡峭,InfiniBand是唯一解;如果通信开销占比不大,高速以太网是更具成本效益的选择。
2.3 存储层:从临时SSD到并行文件系统的数据管道
HPC任务通常是数据密集型的。存储系统的性能,尤其是高并发下的IOPS和吞吐量,常常成为整个工作流的瓶颈。
2.3.1 临时与托管磁盘每个计算虚拟机都附带有本地临时SSD或高性能托管磁盘。本地SSD速度极快,但数据是临时的,虚拟机重启或迁移后会丢失。因此,它只适合存放临时中间文件、缓存或Swap空间。对于需要持久化的工作目录和输入数据,必须使用Azure托管磁盘(如Premium SSD v2或Ultra Disk)。一个实用技巧是:对于需要频繁读写小文件的场景(如编译过程),可以为计算节点挂载一个高性能的Premium SSD作为/scratch目录,能显著提升效率。
2.3.2 并行文件系统:Avere vFXT与BeeGFS当你的集群规模成百上千,所有节点需要并发访问同一个数据集(如公共的输入文件、模型参数)时,传统的网络附加存储(NAS)就会成为瓶颈。这时需要引入并行文件系统。Azure提供了两种主要方式:
- Azure Avere vFXT:这是一个位于计算集群和后台存储(如Azure Blob存储或NetApp ONTAP)之间的高性能缓存层。它特别适合“热数据”的并发读取场景,例如机器学习训练中多个Worker节点读取同一组训练图片。它的优势在于可以将成本低廉的Blob存储“加速”成高性能文件系统,无需迁移数据。
- 自行部署BeeGFS或Lustre:你可以在Azure的虚拟机上自行部署这些开源的并行文件系统。这提供了最大的灵活性和控制权,但同时也带来了部署、运维和调优的复杂性。对于长期运行、存储I/O模式稳定且可预测的大型HPC项目,自行部署并行文件系统可能获得最佳性价比,但需要专业的存储管理员介入。
2.4 管理与调度层:自动化部署与作业编排
手动创建、配置、管理成百上千台虚拟机是不现实的。Azure提供了多种自动化工具。
2.4.1 Azure CycleCloud这是Azure上部署和管理HPC集群的“瑞士军刀”。它支持多种调度器(Slurm、PBS Pro、LSF等),可以通过简单的模板文件,定义集群的规模、虚拟机类型、网络、存储、要安装的软件栈等。CycleCloud最大的价值在于其“弹性”:你可以配置规则,让集群在作业队列为空时自动缩容到零以节省成本,当有新作业提交时再自动扩容。这对于应对突发性、间歇性的大规模计算需求至关重要。
2.4.2 虚拟机规模集与自定义镜像对于更定制化的场景,可以直接使用Azure虚拟机规模集。你可以先创建一台“黄金镜像”虚拟机,在其上安装好所有必要的编译器(如Intel oneAPI, GCC)、MPI库(如OpenMPI, Intel MPI)、应用软件和依赖库,然后将其通用化并捕获为自定义镜像。之后,规模集就可以基于此镜像快速批量部署出一模一样的计算节点。务必在捕获镜像前运行sudo waagent -deprovision+user命令进行通用化处理,否则新虚拟机可能无法正确启动。
3. 从零构建一个弹性HPC集群的实操流程
理论讲完,我们动手搭建一个最经典的、基于Slurm调度器的弹性HPC集群。这个集群将使用HBv3系列虚拟机,通过InfiniBand互联,并配置一个高性能的共享存储。
3.1 前期准备与资源规划
首先,你需要一个Azure订阅,并确保其配额足够。特别是HBv3这类特殊SKU,默认配额可能为0,需要通过Azure支持请求提升配额。
规划你的资源:
- 集群名称:
my-hpc-cluster - 调度器:Slurm
- 登录/管控节点:1台
Standard_D4s_v3(作为集群头节点,运行Slurm控制器和登录服务) - 计算节点:弹性规模集,初始为0,最大可扩展到200台
Standard_HB120rs_v3 - 网络:新建一个虚拟网络(VNet)和子网,启用加速网络。
- 存储:
- 头节点挂载1个1TB的Premium SSD,用于安装软件和用户家目录(
/shared/home)。 - 创建一个Azure NetApp Files (ANF) 卷,或部署一个Avere vFXT集群,作为并行共享存储(
/shared/apps,/shared/data)。
- 头节点挂载1个1TB的Premium SSD,用于安装软件和用户家目录(
3.2 使用Azure CycleCloud部署Slurm集群
这是最高效的方式。我们假设你已经安装了CycleCloud客户端并完成了配置。
导入Slurm项目模板:
cyclecloud import_template -f slurm.txt -n slurm这个
slurm.txt是CycleCloud提供的官方模板,定义了集群的基本结构。创建并配置集群:
cyclecloud create_cluster slurm -c my-hpc-cluster -p my-azure-resource-group \ --template slurm \ --parameters-file cluster_params.json关键的配置文件
cluster_params.json需要你精心编写:{ "ClusterName": "my-hpc-cluster", "Region": "eastus2", "VNetId": "/subscriptions/.../resourceGroups/.../providers/Microsoft.Network/virtualNetworks/my-vnet", "SubnetId": ".../subnets/compute-subnet", "Scheduler": "slurm", "Proxy": {"UseProxy": false}, "LoginNodes": { "Count": 1, "MachineType": "Standard_D4s_v3", "Image": "OpenLogic:CentOS-HPC:7_9-gen2:latest" }, "ComputeNodes": { "MachineType": "Standard_HB120rs_v3", "MaxCount": 200, "Image": "OpenLogic:CentOS-HPC:7_9-gen2:latest", "HPC": { "UseLowLatencyNetwork": true // 关键!启用InfiniBand } }, "AutoShutdown": { "Enabled": true, "IdleTime": "60" // 计算节点空闲60分钟后自动关闭 } }注意:这里我们使用了Azure Marketplace中的
CentOS-HPC镜像。这个镜像已经预装了InfiniBand驱动、MPI库和GPU驱动,是HPC环境的绝佳起点,能省去大量基础配置时间。启动集群:执行
cyclecloud start_cluster -c my-hpc-cluster。CycleCloud会自动创建头节点、配置网络、安装和配置Slurm。整个过程大约需要15-30分钟。
3.3 配置共享存储与软件环境
集群启动后,头节点已经就绪,但计算节点处于关机状态(因为我们设置了初始规模为0)。现在需要配置共享环境。
挂载共享存储:根据你选择的存储方案(如ANF),你需要将存储卷挂载到所有节点(头节点和未来的计算节点)的相同路径下,例如
/shared/apps和/shared/data。这通常需要在CycleCloud的“初始化脚本”或通过自定义脚本实现。例如,对于ANF,脚本中需要包含安装nfs-utils和添加/etc/fstab挂载条目的命令。部署软件环境:有两种主流方式:
- 模块化环境(推荐):在
/shared/apps下安装Environment Modules或Lmod。然后为每个编译器(GCC, Intel)、MPI库(OpenMPI, Intel MPI)和应用软件(如GROMACS, OpenFOAM)创建独立的模块文件。用户登录后,通过module load intel-mpi gromacs/2022.3来加载所需环境。这种方式干净、隔离,且支持多版本共存。 - 容器化:将整个应用及其依赖打包成Singularity或Apptainer容器镜像,存放在共享存储上。在Slurm作业脚本中直接调用容器运行。这种方式环境一致性最好,但需要学习容器技术。
- 模块化环境(推荐):在
配置Slurm账户与QoS:在头节点上,使用
sacctmgr命令创建用户账户、关联项目和QoS(服务质量)。例如,为“分子动力学”项目创建一个高优先级QoS,允许其使用更多核心和更长的运行时间。
3.4 提交第一个弹性作业
现在,集群已经准备就绪。计算节点数为0,不产生任何费用。
编写Slurm作业脚本
job.slurm:#!/bin/bash #SBATCH --job-name=my_hpc_job #SBATCH --nodes=4 #SBATCH --ntasks-per-node=120 #SBATCH --cpus-per-task=1 #SBATCH --time=01:00:00 #SBATCH --partition=compute #SBATCH --qos=normal #SBATCH --output=%x_%j.out #SBATCH --error=%x_%j.err # 加载所需环境模块 module purge module load gcc/11.2.0 openmpi/4.1.2 my-science-app/2.0 # 设置MPI相关环境变量,优化InfiniBand性能 export UCX_NET_DEVICES=mlx5_0:1 export OMPI_MCA_btl=^openib # 对于OpenMPI,使用UCX而非openib BTL以获得更好的IB支持 # 进入工作目录 cd /shared/data/$USER/$SLURM_JOB_ID # 执行MPI并行程序 srun --mpi=pmix ./my_mpi_app -i input.dat -o output.dat这个脚本申请了4个节点,每个节点使用全部120个物理核心(
HB120rs_v3有120核),总共480个MPI任务。提交作业:在头节点上,运行
sbatch job.slurm。- Slurm接收到作业后,发现当前没有可用的计算节点。
- Slurm会通过CycleCloud的集成接口,触发Azure虚拟机规模集扩容。
- Azure开始创建4台
HB120rs_v3虚拟机,并自动将其加入Slurm集群(通过slurmd守护进程)。 - 虚拟机启动、加入集群后,Slurm开始在该节点上运行你的作业。
- 作业运行1小时后结束。
- 节点变为空闲状态。由于我们设置了
AutoShutdown.IdleTime: 60,60分钟后,CycleCloud会自动关闭并释放这些计算节点,规模集缩容为0。
至此,你完成了一次完整的“按需超级计算”。你只为这4台高性能虚拟机实际运行的1小时(加上可能的一点启动时间)付费,而无需承担任何闲置成本。
4. 性能调优与成本控制实战技巧
在云上玩转HPC,除了能跑起来,更要跑得“快”且“省”。这离不开精细化的调优和成本策略。
4.1 计算性能调优:榨干每一分硬件潜力
CPU与内存绑定:在NUMA架构的服务器上,错误的内存访问会导致性能大幅下降。在作业脚本中,使用
srun的--cpu-bind和--mem-bind选项,将进程绑定到特定的CPU核心和对应的内存控制器上。对于HBv3这类多路CPU系统,这至关重要。一个简单的测试方法是:在运行实际应用前,先用一个小的MPI测试程序(如IMB)对比绑定与不绑定的性能差异。MPI库选择与参数调优:不同的MPI库对底层硬件的利用效率不同。在Azure的InfiniBand环境中,Intel MPI和HPC-X(基于OpenMPI,由Mellanox优化)通常能提供最佳性能。你需要针对你的应用进行测试。例如,设置
I_MPI_ADJUST_ALLREDUCE=5(针对Intel MPI)或OMPI_MCA_coll_hcoll_enable=1(针对HPC-X)来优化集体通信操作。编译器优化标志:不要只使用
-O2。针对你的CPU架构使用特定的优化标志。对于AMD EPYC,GCC可以使用-march=znver3;Intel编译器可以使用-xHost。但要注意,过度激进的优化(如-O3)有时可能导致数值不稳定或程序错误,需进行正确性验证。
4.2 存储I/O性能调优:打破数据瓶颈
并行文件系统条带化:如果使用ANF或自建并行文件系统,合理设置条带化(Stripe)参数能极大提升并发读写性能。对于大量小文件,较小的条带大小(如128KB)更合适;对于大文件顺序读写,较大的条带大小(如1MB)更好。这没有统一答案,必须用你的实际工作负载进行基准测试。
利用节点本地SSD:将每个计算节点本地的临时SSD用作“暂存空间”(Scratch Space)。在作业脚本开始时,将共享存储上的输入数据拷贝到本地
$TMPDIR;计算过程中所有中间I/O都发生在本地SSD;作业结束时,再将最终结果拷贝回共享存储。这能彻底消除计算期间的网络存储I/O竞争,尤其适合I/O密集型作业。记得在作业脚本末尾添加清理本地临时文件的命令。
4.3 成本控制:让每一分钱都花在刀刃上
利用Spot虚拟机(抢占式实例):这是云上HPC节省成本的“大杀器”。Spot虚拟机的价格可能比按需价格低70%-90%。其代价是Azure可能在需要容量时提前30秒通知并回收这些虚拟机。对于具有检查点(Checkpoint)功能的长时运行作业,Spot实例性价比极高。你可以在Slurm中配置单独的
partition和qos给Spot节点,并在作业脚本中通过#SBATCH --partition=spot来指定。即使作业被中断,也能从上一个检查点恢复。混合使用不同代际的实例:Azure会不断推出新的虚拟机系列。新一代实例通常性能更高或性价比更优。例如,从
HBv2升级到HBv3。你可以通过CycleCloud模板,配置集群同时包含新旧两种实例类型,并为它们设置不同的Slurmgres(通用资源)或feature,让作业按需选择。例如,将HBv3标记为feature=zen3,HBv2标记为feature=zen2,在作业脚本中用#SBATCH --constraint=zen3来指定。精细化监控与预算预警:务必使用Azure Cost Management + Billing服务。为你的HPC项目创建独立的资源组,并设置预算和警报。更精细的做法是,利用Azure Tags为不同的研究项目、PI(首席研究员)或计算类型(如CPU作业、GPU作业)打上标签,然后通过成本分析报告,清晰地看到每一笔费用花在了哪里,便于内部核算和优化资源分配策略。
5. 典型问题排查与运维经验
即使架构再完美,在实际运行中也会遇到各种问题。以下是一些常见“坑位”及解决方法。
5.1 计算节点无法加入Slurm集群
这是部署后最常见的问题。
- 症状:作业一直处于
PENDING状态,sinfo命令显示节点状态为down*或idle~。 - 排查步骤:
- 检查网络与安全组:确保计算节点子网的安全组允许与头节点在
6817-6819端口(Slurm守护进程端口)和22端口(SSH)上的通信。 - 检查CycleCloud代理:登录到出问题的计算节点,查看
/opt/cycle/jetpack/logs/jetpack.log。最常见的错误是slurmd服务启动失败。通常是因为主机名解析问题或与头节点的通信故障。 - 检查
slurmd日志:在计算节点上运行sudo systemctl status slurmd和sudo journalctl -u slurmd -f。常见的错误信息如“can‘t resolve hostname [headnode]”指向DNS问题;“Authentication denied”指向munge密钥不一致(所有节点的/etc/munge/munge.key必须完全相同)。
- 检查网络与安全组:确保计算节点子网的安全组允许与头节点在
- 解决:确保头节点的主机名和IP能被计算节点正确解析(可通过
/etc/hosts文件静态绑定);在头节点上重新分发munge密钥到新节点。
5.2 InfiniBand网络性能不达预期
- 症状:MPI作业的扩展性很差,增加节点数后性能提升不明显,甚至下降。
- 排查步骤:
- 验证IB设备:在计算节点上运行
ibstat和ibv_devinfo,确认mlx5设备状态为ACTIVE,链路速率是预期的(如HDR)。 - 测试带宽与延迟:使用
ib_write_bw和ib_write_lat工具在两台节点间进行点对点测试。如果带宽远低于预期(如远低于200 Gb/s),检查是否处于同一PPG和可用性区域。 - 检查MPI库的IB传输层:对于OpenMPI,确保使用了UCX传输层(
--mca pml ucx)。对于Intel MPI,确保I_MPI_FABRICS=shm:ofi且OFI provider设置为mlx。
- 验证IB设备:在计算节点上运行
- 解决:在创建集群时,务必确认所有计算节点都部署在同一个邻近放置组中。这是获得非阻塞、低延迟InfiniBand网络的关键。
5.3 作业运行中途失败或Spot实例被回收
- 症状:作业运行一段时间后突然失败,退出代码非零。
- 排查步骤:
- 检查作业输出/错误文件:首先查看
slurm-<jobid>.out和.err文件末尾的错误信息。 - 检查系统日志:如果错误信息不明,登录到失败的计算节点(如果它还存活着),查看
/var/log/messages或dmesg,看是否有OOM(内存不足) killer、硬件错误或Spot实例回收通知。 - Spot实例回收:对于Spot实例,Azure会通过元数据服务发送回收通知。应用程序可以定期查询
http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01来捕获Preempt事件,并优雅地执行检查点保存和退出。
- 检查作业输出/错误文件:首先查看
- 解决:对于可能被抢占的长作业,必须实现应用层的检查点/重启功能。在作业脚本中,可以结合Azure元数据查询,或在收到SIGTERM信号时触发保存状态。对于内存不足问题,需要优化应用程序内存使用,或请求更多的
--mem资源。
5.4 共享存储性能抖动
- 症状:作业的I/O阶段时间时快时慢,尤其是在集群规模较大时。
- 排查步骤:
- 监控存储性能:对于Azure NetApp Files,使用Azure门户的监控图表查看卷的IOPS、吞吐量和延迟。观察是否在特定时间段(如所有作业同时开始读写时)出现性能瓶颈。
- 检查客户端负载:在多个计算节点上同时运行
iostat -x 2,观察是否所有节点都对存储发起高强度的I/O请求。
- 解决:这通常是“惊群效应”。优化方案包括:
- 错峰I/O:在作业脚本中引入随机延迟,让不同节点的I/O请求不要完全同步。
- 使用本地暂存空间:如前所述,将共享存储的读写减少到仅输入和输出阶段。
- 升级存储层级:ANF和Avere vFXT都提供不同的性能层级。如果预算允许,升级到更高性能的SKU。
- 调整文件系统参数:例如,对于NFS挂载,尝试调整
rsize、wsize、noatime等挂载选项进行测试。
在云上运营一个按需的超级计算环境,其核心思想从“拥有基础设施”转变为“消费计算服务”。这意味着运维的重点也从硬件维护、机房管理,转移到了对云资源模板、自动化脚本、性能配置和成本策略的精细化管理上。最大的挑战和乐趣,也正在于如何在这弹性的、由API驱动的世界里,设计出最贴合科研与工程需求、同时又高效经济的工作流。每一次对作业脚本的优化、对实例类型的精选、对Spot实例的巧妙利用,都直接转化为更快的科研成果和更低的计算成本,这种即时的反馈和掌控感,正是云上超级计算的魅力所在。
