多台闲置或用途不同的 x86 主机,如果 CPU 核心数、内存容量甚至 GPU 型号都不一致,并不意味着它们只能分别运行独立任务。

通过 Linux、Slurm 和 Open MPI,可以将这些机器组织成一个统一管理的异构计算集群。

这种架构不会把几颗物理 CPU 和几组内存透明地变成一块“超级主板”,但可以建立一个统一的资源调度层,让计算任务自动使用整个集群中的空闲 CPU、内存和 GPU。

一、什么是真正的计算集群

假设存在四台规格不同的 x86 主机:

Node A
16 CPU Core
64GB RAM
GPU

Node B
12 CPU Core
32GB RAM
GPU

Node C
8 CPU Core
32GB RAM

Node D
4 CPU Core
16GB RAM

从集群管理角度,可以看到:

CPU:40 Core
RAM:144GB
GPU:2

但这里的“总计”需要正确理解。

一个普通应用程序仍然只能直接使用自己所在节点的 CPU 和本地 RAM。

例如 Node A 只有 64GB 内存,那么一个完全不支持分布式计算、需要 100GB 连续内存的普通程序,不能因为整个集群拥有 144GB RAM 就自动运行。

真正的分布式计算依赖应用程序本身将任务拆分到多个节点。

Open MPI 是 MPI 标准的开源实现,其核心用途正是让不同节点上的进程通过消息传递协同完成一个计算任务。

二、推荐架构

一个实用的小型集群可以设计成:

               显示器 / 键盘 / 鼠标
                         │
                         ▼
                 Desktop / Head Node
                  Linux KDE/GNOME
                         │
                 Slurm Controller
                         │
                   高速交换机
          ┌──────────────┼──────────────┐
          │              │              │
      Compute B      Compute C      Compute D
      Linux Server   Linux Server   Linux Server

其中 Head Node 可以同时承担日常桌面工作。

另外几台 Compute Node 不需要显示器、键盘和鼠标,可以作为纯 Headless Linux 节点运行。

如果 Head Node 本身性能较强,它也可以同时安装 slurmd,把自己的 CPU 和 GPU 加入计算资源池。

三、Slurm 负责什么

Slurm 是资源调度器。

它并不负责将程序自动改造成分布式程序,而是负责知道:

哪台机器有多少CPU
哪台机器还有多少内存
哪台机器有GPU
当前哪些资源空闲
任务请求了什么资源

随后将任务放到合适的节点。

例如:

任务 A:需要 8 CPU + 16GB RAM
任务 B:需要 1 GPU + 32GB RAM
任务 C:需要 4 CPU

Slurm 可以根据当前资源状态自动进行分配。

SchedMD 当前 Slurm 文档明确支持异构作业,不同组成部分可以分别请求不同数量的 CPU、内存、分区及其他资源。

因此集群节点不必具有完全相同的 CPU、RAM 或 GPU。

四、Open MPI 负责什么

Slurm 解决的是:

任务应该在哪些机器运行

Open MPI 解决的是:

这些机器上的多个程序进程怎样协同计算

例如一个支持 MPI 的程序可以启动:

Node A:8个进程
Node B:8个进程
Node C:4个进程

这些进程通过网络交换数据,共同完成同一个大型任务。

典型调用方式可以表现为:

srun -N3 -n20 ./mpi-program

其中计算过程是真正跨节点的。

但 Firefox、普通文本编辑器、普通单线程程序等不会因为安装了 MPI 就自动获得其他节点的 CPU。

因此,“计算集群”本质上是资源调度和分布式应用环境,而不是透明的硬件合并。

五、异构节点并不是问题

Slurm 可以记录不同节点拥有的不同资源。

例如:

Node A
CPU=16
RealMemory=64000
GPU=1

Node B
CPU=12
RealMemory=32000
GPU=1

Node C
CPU=8
RealMemory=32000

Node D
CPU=4
RealMemory=16000

管理员可以继续按照 CPU 型号、GPU 类型或者节点用途建立不同 Feature 或 Partition。

例如:

gpu
highmem
cpu
desktop

任务就可以明确要求:

只去GPU节点

或者:

至少需要32GB内存

Slurm 的异构任务机制甚至允许同一个作业的不同组成部分请求完全不同的 CPU 和内存配置。

六、GPU 怎样加入集群

GPU 可以通过 Slurm 的 GRES,即 Generic Resources 进行管理。

例如:

Node A → NVIDIA GPU
Node B → NVIDIA GPU
Node C → 无GPU
Node D → 无GPU

任务请求:

sbatch --gres=gpu:1 job.sh

Slurm 就只会在满足 GPU 条件的节点中调度。

Slurm 当前 GRES 文档专门提供 GPU 资源管理机制,并能够通过 CUDA_VISIBLE_DEVICES 控制具体作业可见的 GPU。

如果两台带 GPU 的机器性能不同,还可以进一步标记 GPU 类型。

例如:

gpu:rtx_a
gpu:rtx_b

这样某些任务可以指定使用特定显卡。

七、桌面主机与计算节点可以共存

如果其中一台带独显的机器同时承担日常桌面工作,最合理的设计通常不是让另一台弱机器成为所谓的“中心电脑”。

显示器、键盘和鼠标直接连接主要工作站:

Desktop Node
├── KDE / GNOME
├── 浏览器
├── IDE
├── Terminal
├── Slurm Controller
└── slurmd

后台计算节点则:

Compute Node
├── Linux Server
├── slurmd
├── Open MPI
└── SSH

日常操作始终只面对桌面主机。

需要计算时提交任务:

sbatch job.sh

任务可能自动跑到另一台机器。

执行结束后的结果再写回共享文件系统。

这比远程桌面或者试图建立“透明分布式桌面系统”稳定得多。

八、第二块 GPU 更适合作为后台 Worker

如果两台机器都有独立显卡,可以考虑把主要桌面 GPU 与后台 GPU 分工。

例如:

Node A GPU
→ 桌面显示
→ 浏览器硬件加速
→ 视频
→ 轻量计算

Node B GPU
→ 长时间CUDA任务
→ AI计算
→ Blender渲染
→ 视频编码

这样后台 GPU 被持续占满时,不会明显影响日常桌面响应。

如果需要,也可以让 Slurm 同时调度两台 GPU 节点。

九、操作系统怎么选

小型集群最好让计算节点使用相同发行版。

一种常见布局是:

Desktop / Head Node
Ubuntu / Debian / Arch + KDE

Compute Node
Ubuntu Server / Debian

如果希望最大限度降低 MPI 库、编译器和动态链接库差异,甚至可以让所有计算节点使用完全相同的系统版本。

真正重要的是确保:

用户UID/GID一致
Open MPI版本兼容
编译器和运行库兼容
SSH正常
主机名解析正常
时间同步正常

对于需要高度一致运行环境的工作负载,还可以在 Slurm 上结合 Apptainer 等 HPC 容器技术。

十、共享存储很重要

分布式任务往往需要所有节点访问同样的数据,例如:

程序
数据集
模型
输入文件
计算结果

小型环境最简单的方案通常是 NFS:

Storage Node
      │
      NFS
      │
      ▼
 /cluster
      │
 ┌────┼────┬────┐
 A    B    C    D

所有节点都看到:

/cluster/jobs
/cluster/data
/cluster/results

如果未来需要真正的跨节点分布式存储,则可以换成 MooseFS、CephFS 等系统。

计算调度与共享存储是两个独立的问题:

Slurm
→ 管CPU、RAM、GPU和任务

NFS / MooseFS / CephFS
→ 管文件和数据

不要将两者混为一体。

十一、高速交换机决定跨节点效率

CPU 密集型且节点之间数据交换较少的任务,即使 1GbE 也可能获得不错的扩展效果。

但 MPI、AI 数据处理、大型数据集和共享存储都可能大量使用网络。

网络结构最好是:

                    Router
                      │
               High-speed Switch
          ┌───────────┼───────────┐
          │           │           │
        Node A      Node B      Node C      Node D

同一局域网中的节点通信直接经过交换机,不需要经过路由器。

对于小型计算集群,2.5GbE 已经明显优于普通千兆网络,而 10GbE 会给共享存储和大量跨节点传输留下更大余量。

十二、每台机器需要安装什么

可以采用如下基础布局:

组件Head NodeCompute Node
Linux
SSH
Chrony
Slurm Controller
slurmd可选/推荐
Open MPI
GPU Driver有GPU时有GPU时
NFS Client
Ansible

Head Node 还可以运行 Ansible,用于统一管理其他节点。

这样软件安装、配置修改和系统维护都可以从一个节点完成。

十三、最终使用方式

集群建成后,管理员首先可以通过:

sinfo

查看整个集群。

例如:

NODE    CPU   RAM    GPU   STATE
node-a   16   64G    1     mix
node-b   12   32G    1     idle
node-c    8   32G    0     idle
node-d    4   16G    0     idle

提交普通任务:

sbatch job.sh

申请指定资源:

sbatch --cpus-per-task=8 --mem=16G job.sh

申请 GPU:

sbatch --gres=gpu:1 gpu-job.sh

运行支持 MPI 的跨节点程序:

srun -N4 -n32 ./mpi-program

Slurm 的 sbatchsrun 等工具目前都原生支持异构资源请求和 GPU 参数。

十四、不能期待什么

计算集群最容易出现的误解是认为:

4台电脑
↓
变成一台拥有全部CPU和全部RAM的大电脑

实际并不是这样。

正确模型是:

4台独立计算机
      │
      ▼
统一资源调度系统
      │
      ▼
多个分布式任务协同运行

单机程序仍然受单节点硬件上限约束。

只有支持 MPI、分布式数据处理、分布式渲染、任务队列或者其他并行框架的软件,才能真正利用多台主机共同完成一个任务。

十五、总结

Slurm + Open MPI 的价值在于把一批规格不同、原本独立管理的 x86 主机变成一个统一计算平台。

整个架构可以概括为:

                 Linux Head Node
                       │
                   Slurm
                       │
               High-speed Network
          ┌────────────┼────────────┐
          │            │            │
       Worker A     Worker B     Worker C
          │            │            │
          └──────── Open MPI ───────┘
                       │
                  Shared Storage

Slurm 负责资源发现和调度,Open MPI 负责真正的跨节点并行通信,共享文件系统负责让所有节点访问相同的数据。

这种设计既不要求所有机器规格一致,也不要求将现有设备全部替换成服务器级硬件。

对于拥有多台闲置或用途不同的 x86 设备,又希望统一利用计算资源的环境,这是一条成熟、可扩展且相对标准化的 Linux 集群路线。

Leave a Reply

Your email address will not be published. Required fields are marked *