跳转至

HPC集群使用(SLURM/PBS)

一句话说明: HPC集群就是一台大家排队共用的超级计算机——你写好任务脚本提交排队,系统自动分配资源帮你跑,本篇教你SLURM/PBS的核心用法和生信场景实操。


目录

  1. 什么是HPC集群
  2. SLURM核心概念
  3. 编写sbatch脚本
  4. 资源申请策略
  5. 常见SLURM脚本模板
  6. PBS对比
  7. 模块管理(module)
  8. 集群上的conda环境管理
  9. 生信pipeline在集群上运行
  10. 面试怎么答
  11. 速查表
  12. 延伸资源

1. 什么是HPC集群

1.1 白话解释

HPC(High Performance Computing,高性能计算)集群,可以理解为:

  • 一堆电脑(节点)连在一起,共享一个文件系统
  • 有个"调度员"(作业调度器)负责排队、分配资源
  • 你不能直接霸占一台机器,而是提交一个任务申请,写清楚需要多少CPU、多少内存、跑多久,调度员给你安排

1.2 集群的基本结构

┌──────────────────────────────────────────┐
│              登录节点 (Login Node)         │  ← 你SSH登录到这里
│         ⚠️ 不要在这里跑大任务!           │
└──────────┬───────────────────────────────┘
           │ 提交任务 (sbatch/qsub)
┌──────────────────────────────────────────┐
│           调度器 (SLURM / PBS)            │  ← 排队分配资源
└──────────┬───────────────────────────────┘
           │ 分配到具体节点
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 计算节点1│ │ 计算节点2│ │ 计算节点3│  ← 实际跑任务的地方
│ 64核/256G│ │ 64核/256G│ │ 8xGPU   │
└─────────┘ └─────────┘ └─────────┘
┌──────────────────────────────────────────┐
│         共享存储 (/home, /data)           │  ← 所有节点都能访问
└──────────────────────────────────────────┘

1.3 为什么生信需要HPC

生信任务典型资源需求为什么需要集群
宏基因组组装(MEGAHIT)50-200GB内存普通电脑内存不够
序列比对(Bowtie2/BWA)多核并行加速一个样本跑1小时,100个样本需要并行
Kraken2物种注释70GB+内存(标准库)需要大内存节点
深度学习模型训练GPU需要GPU节点
批量质控(fastp × 100)数组任务100个样本并行跑

2. SLURM核心概念

SLURM(Simple Linux Utility for Resource Management)是目前最主流的集群调度系统(版本已到25.11)。

2.1 关键术语

术语英文白话解释类比
Partition分区一组计算节点的集合,类似"不同窗口"银行的普通窗口vs VIP窗口
Node节点集群中的一台服务器银行的一个柜员
Job作业你提交的一个计算任务你的一个业务办理请求
CPU/Core核心一个节点上的处理器核心数柜员有几只手能同时干活
QOS服务质量优先级和资源限制策略VIP客户优先办理

2.2 核心命令

# ===== 提交任务 =====
sbatch my_job.sh          # 提交批处理脚本(最常用!)
# 白话:把你的任务扔到排队队列里

srun hostname              # 直接在分配的节点上运行一个命令(交互式)
# 白话:当场申请资源跑一个命令

salloc -n 4 -t 2:00:00    # 申请资源但不立即运行任务(交互式会话)
# 白话:先占个座位,等会儿再点菜

# ===== 查看任务 =====
squeue                     # 查看所有排队/运行中的任务
# 白话:看看队排到哪了

squeue -u $USER            # 只看自己的任务
# 白话:看看我自己的号排到哪了

squeue -j 12345            # 查看指定任务的状态
# 白话:查一下这个号的状态

# ===== 取消任务 =====
scancel 12345              # 取消指定任务
# 白话:不排了,取消这个号

scancel -u $USER           # 取消自己所有任务
# 白话:我所有的号都不要了

# ===== 查看集群信息 =====
sinfo                      # 查看集群分区和节点状态
# 白话:看看哪些窗口开着、哪些窗口忙

scontrol show job 12345    # 查看任务详细信息
# 白话:看这个任务的详细收据

sacct -j 12345             # 查看已完成任务的资源使用情况
# 白话:回顾这个任务实际用了多少资源(事后分析)

3. 编写sbatch脚本

3.1 完整模板(生信任务示例:fastp质控)

#!/bin/bash
#============================================================
# SLURM 作业脚本模板 - fastp质控
# 作者:[用户]
# 日期:2026-05-03
#============================================================

#---------- SLURM 参数设置(每行一个#SBATCH) ----------

#SBATCH --job-name=fastp_qc          # 任务名称(方便在squeue中识别)
#SBATCH --output=logs/%x_%j.out      # 标准输出文件(%x=任务名, %j=任务ID)
#SBATCH --error=logs/%x_%j.err       # 错误输出文件
#SBATCH --partition=normal           # 提交到哪个分区(问管理员有哪些分区)
#SBATCH --nodes=1                    # 申请1个节点(大多数生信任务只需要1个)
#SBATCH --ntasks=1                   # 1个任务(不是MPI并行时设为1)
#SBATCH --cpus-per-task=8            # 每个任务用8个CPU核心
#SBATCH --mem=16G                    # 申请16GB内存
#SBATCH --time=04:00:00              # 最长运行时间4小时(超时会被杀掉!)
#SBATCH --mail-type=END,FAIL         # 任务结束或失败时发邮件通知
#SBATCH --mail-user=your@email.com   # 接收通知的邮箱

#---------- 环境设置 ----------

# 打印任务开始信息(方便调试)
echo "任务开始时间: $(date)"            # 记录开始时间
echo "运行节点: $(hostname)"            # 记录在哪个节点上跑
echo "工作目录: $(pwd)"                 # 记录当前目录

# 加载需要的软件模块
module purge                            # 先清除所有已加载模块(避免冲突)
module load fastp/1.3.3                 # 加载fastp模块

# 或者激活conda环境(二选一)
# source activate qc_env

#---------- 定义变量 ----------

INPUT_DIR="/data/raw_reads"             # 原始数据目录
OUTPUT_DIR="/data/clean_reads"          # 输出目录
SAMPLE="sample_001"                     # 样本名称
THREADS=8                               # 线程数(和--cpus-per-task一致!)

# 确保输出目录存在
mkdir -p ${OUTPUT_DIR}                  # -p:如果目录已存在不报错
mkdir -p logs                           # 创建日志目录

#---------- 主要分析步骤 ----------

echo "开始处理样本: ${SAMPLE}"

fastp \
    --in1 ${INPUT_DIR}/${SAMPLE}_R1.fastq.gz \      # 输入:正向reads
    --in2 ${INPUT_DIR}/${SAMPLE}_R2.fastq.gz \      # 输入:反向reads
    --out1 ${OUTPUT_DIR}/${SAMPLE}_clean_R1.fastq.gz \  # 输出:质控后正向
    --out2 ${OUTPUT_DIR}/${SAMPLE}_clean_R2.fastq.gz \  # 输出:质控后反向
    --html ${OUTPUT_DIR}/${SAMPLE}_fastp.html \      # 质控报告(HTML格式)
    --json ${OUTPUT_DIR}/${SAMPLE}_fastp.json \      # 质控报告(JSON格式)
    --thread ${THREADS} \                            # 使用的线程数
    --qualified_quality_phred 20 \                   # 质量值≥20的碱基才保留
    --length_required 50                             # 过短的reads(<50bp)丢弃

#---------- 结束信息 ----------

echo "任务结束时间: $(date)"
echo "退出状态码: $?"                    # 0表示成功,非0表示出错

3.2 提交和监控

# 提交任务
sbatch fastp_qc.sh
# 输出:Submitted batch job 12345

# 查看任务状态
squeue -u $USER
# JOBID  PARTITION  NAME       USER   ST  TIME  NODES  NODELIST
# 12345  normal     fastp_qc   user   R   0:05  1      node01
# ST列:PD=排队中, R=运行中, CG=正在完成

# 查看任务输出(实时跟踪)
tail -f logs/fastp_qc_12345.out

# 任务完成后查看资源使用
sacct -j 12345 --format=JobID,JobName,MaxRSS,Elapsed,State
# MaxRSS:实际使用的最大内存
# Elapsed:实际运行时间

4. 资源申请策略

4.1 估算指南

资源估算方法生信参考值
CPU看软件文档的-t/--threads参数质控4-8核,比对8-16核,组装16-32核
内存先小量测试,用sacct看实际使用fastp: 4-8G, Kraken2: 8-70G, MEGAHIT: 50-200G
时间先设长一点,后续根据经验缩短质控: 1-2h/样本, 比对: 2-4h/样本, 组装: 6-24h
GPU只有深度学习任务才需要AlphaFold: 1-2 GPU, 模型训练: 1-4 GPU

4.2 实用技巧

# 技巧1:先跑一个小测试,看实际资源使用
sbatch --wrap="fastp -i test_R1.fq.gz -o /dev/null" --mem=4G -t 00:30:00

# 技巧2:查看已完成任务的实际资源使用
sacct -j 12345 --format=JobID,MaxRSS,MaxVMSize,Elapsed
# 根据实际使用量,下次申请时加20-50%余量

# 技巧3:查看分区的空闲资源
sinfo -p normal -o "%N %C %m %G"
# 输出节点名、CPU使用情况、内存、GPU信息

4.3 常见错误

错误原因解决方法
slurmstepd: error: Exceeded memory limit申请的内存不够增加 --mem
TIMEOUT运行时间超过 --time增加时间限制
(QOSMaxJobsPerUserLimit)超过每人最大任务数等现有任务完成
任务一直PD申请资源太多,排不上减少资源申请或换分区

5. 常见SLURM脚本模板

5.1 数组任务(Array Job)—— 批量处理100个样本

#!/bin/bash
#SBATCH --job-name=fastp_array       # 任务名
#SBATCH --array=1-100                # 数组任务:索引从1到100
#SBATCH --cpus-per-task=4            # 每个子任务4核
#SBATCH --mem=8G                     # 每个子任务8G内存
#SBATCH --time=02:00:00              # 每个子任务最多2小时
#SBATCH --output=logs/fastp_%A_%a.out  # %A=主任务ID, %a=数组索引

# 从样本列表文件中读取当前索引对应的样本名
# sample_list.txt 每行一个样本名
SAMPLE=$(sed -n "${SLURM_ARRAY_TASK_ID}p" sample_list.txt)

echo "处理样本 #${SLURM_ARRAY_TASK_ID}: ${SAMPLE}"

module load fastp/1.3.3

fastp \
    --in1 raw/${SAMPLE}_R1.fastq.gz \
    --in2 raw/${SAMPLE}_R2.fastq.gz \
    --out1 clean/${SAMPLE}_R1.fastq.gz \
    --out2 clean/${SAMPLE}_R2.fastq.gz \
    --thread 4

echo "样本 ${SAMPLE} 处理完成"
# 提交数组任务
sbatch fastp_array.sh

# 限制同时运行的子任务数(避免独占太多资源)
#SBATCH --array=1-100%10    # 最多同时跑10个

5.2 多节点并行(MPI任务)

#!/bin/bash
#SBATCH --job-name=mpi_task
#SBATCH --nodes=4                    # 使用4个节点
#SBATCH --ntasks-per-node=16         # 每个节点16个进程
#SBATCH --mem-per-cpu=4G             # 每个CPU核心4G内存
#SBATCH --time=12:00:00

module load openmpi/4.1.5

# 使用srun启动MPI程序(自动分配到所有节点)
srun my_mpi_program --input data.bin --output result.bin

5.3 GPU任务

#!/bin/bash
#SBATCH --job-name=alphafold
#SBATCH --partition=gpu              # GPU分区(名称问管理员)
#SBATCH --gres=gpu:1                 # 申请1块GPU
#SBATCH --cpus-per-task=8            # 8核CPU(GPU任务也需要CPU配合)
#SBATCH --mem=32G
#SBATCH --time=24:00:00

module load cuda/12.0
module load alphafold/2.3

# 检查GPU是否可用
nvidia-smi

# 运行AlphaFold
alphafold --input=query.fasta --output=results/

6. PBS对比

PBS(Portable Batch System)是另一种常见的调度系统(变种有PBS Pro和Torque)。

6.1 PBS核心命令

# ===== 提交任务 =====
qsub my_job.pbs            # 提交PBS脚本(对应SLURM的sbatch)

# ===== 查看任务 =====
qstat                       # 查看任务状态(对应squeue)
qstat -f 12345              # 查看任务详情(对应scontrol show job)
qstat -u $USER              # 只看自己的任务

# ===== 取消任务 =====
qdel 12345                  # 取消任务(对应scancel)

# ===== 查看节点 =====
pbsnodes -a                 # 查看节点信息(对应sinfo)

6.2 PBS脚本示例

#!/bin/bash
#PBS -N fastp_qc                     # 任务名(对应 --job-name)
#PBS -o logs/fastp.out               # 标准输出(对应 --output)
#PBS -e logs/fastp.err               # 错误输出(对应 --error)
#PBS -q normal                       # 队列名(对应 --partition)
#PBS -l nodes=1:ppn=8                # 1节点8核(对应 --nodes + --cpus-per-task)
#PBS -l mem=16gb                     # 内存(对应 --mem)
#PBS -l walltime=04:00:00            # 运行时间(对应 --time)
#PBS -m ae                           # 结束/出错时发邮件(对应 --mail-type)
#PBS -M your@email.com               # 邮箱(对应 --mail-user)

# PBS要手动进入工作目录(SLURM默认就在提交目录)
cd $PBS_O_WORKDIR

module load fastp/1.3.3
fastp --in1 input_R1.fq.gz --in2 input_R2.fq.gz \
      --out1 clean_R1.fq.gz --out2 clean_R2.fq.gz \
      --thread 8

7. 模块管理(module)

集群上的软件通常用 Environment Modules 管理,而不是每个人自己装。

# 查看所有可用模块
module avail                        # 列出集群上装了哪些软件
# 白话:看看货架上有什么

# 搜索特定软件
module avail kraken                 # 搜索包含"kraken"的模块

# 加载模块
module load kraken2/2.1.3           # 加载Kraken2(指定版本)
module load samtools                # 加载samtools(默认版本)
# 白话:把软件从货架上拿下来用

# 查看已加载的模块
module list                         # 显示当前环境中加载了哪些模块

# 卸载模块
module unload kraken2               # 卸载Kraken2
module purge                        # 卸载所有模块(推荐在脚本开头用)
# 白话:把所有东西放回货架,从干净状态开始

# 查看模块信息
module show kraken2/2.1.3           # 显示这个模块设置了哪些环境变量

8. 集群上的conda环境管理

8.1 常见问题

集群上用conda的注意事项:

# 问题1:conda装在哪?
# 答:通常装在该home目录下,但home目录空间有限(通常10-50GB)
# 解决:把conda安装到/data或/scratch等大容量目录
conda config --prepend pkgs_dirs /data/$USER/conda/pkgs
conda config --prepend envs_dirs /data/$USER/conda/envs

# 问题2:在sbatch脚本中激活conda环境
# 错误写法:
conda activate bioinfo  # ← 在非交互式shell中可能失败

# 正确写法:
source activate bioinfo
# 或者:
eval "$(conda shell.bash hook)"    # 先初始化conda
conda activate bioinfo             # 再激活环境

# 问题3:conda初始化写在.bashrc中,导致登录很慢
# 解决:把conda初始化放在脚本中按需执行,不要放在.bashrc

8.2 推荐做法

#!/bin/bash
#SBATCH --job-name=bio_analysis

# 在脚本中初始化和激活conda
eval "$(conda shell.bash hook)"     # 初始化conda(必须)
conda activate bioinfo              # 激活环境

# 验证环境
which python                        # 应该指向conda环境中的python
python --version                    # 确认版本正确

# ... 运行你的分析 ...

conda deactivate                    # 任务结束后退出环境(可选)

9. 生信pipeline在集群上运行

9.1 Snakemake + SLURM

# 方式1:使用 --cluster 参数(传统方式)
snakemake --cluster "sbatch -p normal -c {threads} --mem={resources.mem_mb}M -t {resources.time}" \
    --jobs 50 \                       # 最多同时提交50个任务
    --latency-wait 60                 # 等待60秒让文件系统同步

# 方式2:使用 SLURM executor plugin(Snakemake 8.x+ 推荐方式)
# 先安装插件
pip install snakemake-executor-plugin-slurm

# 运行时指定executor
snakemake --executor slurm \
    --default-resources slurm_partition=normal mem_mb=8000 runtime=240 \
    --jobs 50

在Snakefile中指定资源:

rule fastp:
    input:
        r1 = "raw/{sample}_R1.fastq.gz",
        r2 = "raw/{sample}_R2.fastq.gz"
    output:
        r1 = "clean/{sample}_R1.fastq.gz",
        r2 = "clean/{sample}_R2.fastq.gz"
    threads: 8                             # CPU核心数
    resources:
        mem_mb = 16000,                    # 内存(MB)
        runtime = 120                      # 时间(分钟)
    shell:
        "fastp --in1 {input.r1} --in2 {input.r2} "
        "--out1 {output.r1} --out2 {output.r2} "
        "--thread {threads}"

9.2 Nextflow + SLURM

// nextflow.config 中配置SLURM
profiles {
    slurm {
        process.executor = 'slurm'         // 使用SLURM调度器
        process.queue = 'normal'           // 默认分区
        process.cpus = 4                   // 默认CPU数
        process.memory = '8 GB'            // 默认内存
        process.time = '4h'                // 默认时间
    }
}
# 运行Nextflow pipeline
nextflow run main.nf -profile slurm

10. 面试怎么答

Q1:你用过HPC集群吗?用的什么调度系统?

参考回答: 用过SLURM调度系统。该宏基因组分析流程需要较大的计算资源,比如Kraken2注释需要大内存,MEGAHIT组装需要多核并行,这些都是在集群上通过sbatch提交批处理任务完成的。我会根据不同步骤的需求合理申请资源,比如质控步骤申请8核16G,物种注释申请大内存节点。

Q2:sbatch脚本怎么写?

参考回答: 一个标准的sbatch脚本包括两部分:顶部的#SBATCH指令用于指定资源需求(分区、CPU、内存、时间、输出文件),下面是实际的分析命令。关键是要指定合理的资源量——太少会OOM被杀,太多会排队时间很长。我通常先跑一个小测试,用sacct查看实际资源使用,再调整正式任务的参数。

Q3:怎么批量处理100个样本?

参考回答: 使用SLURM的数组任务(Array Job)。设置#SBATCH --array=1-100,每个子任务通过$SLURM_ARRAY_TASK_ID获取自己的索引,再从样本列表中读取对应的样本名。可以用--array=1-100%10限制同时运行的任务数,避免占用太多资源。

Q4:任务被杀了怎么排查?

参考回答: 分几步排查:首先用sacct -j <jobid> --format=State,ExitCode,MaxRSS查看任务状态和退出码。如果State是OUT_OF_MEMORY,说明内存不够,需要增加--mem。如果是TIMEOUT,说明时间不够。如果是其他错误,查看.err文件中的具体报错信息。

Q5:SLURM和PBS有什么区别?

参考回答: 主要是命令名不同:sbatch对应qsub,squeue对应qstat,scancel对应qdel。脚本指令也不同,SLURM用#SBATCH,PBS用#PBS。功能上差异不大,目前SLURM更主流,大部分新建集群都选SLURM。实际工作中掌握一种,另一种看一下对照表就能快速上手。


11. 速查表

11.1 SLURM命令速查

功能命令说明
提交任务sbatch job.sh提交批处理脚本
交互式运行srun --pty bash申请资源并打开交互式shell
申请资源salloc -n4 -t2:00:00分配资源(不运行命令)
查看队列squeue -u $USER查看自己的任务
取消任务scancel <jobid>取消指定任务
取消全部scancel -u $USER取消自己所有任务
集群状态sinfo查看分区和节点状态
任务详情scontrol show job <id>查看运行中任务的详细信息
历史记录sacct -j <id>查看已完成任务的资源使用
节点详情scontrol show node <name>查看节点配置

11.2 常用sbatch参数

参数示例说明
--job-name--job-name=fastp任务名
--partition--partition=normal分区
--nodes--nodes=1节点数
--ntasks--ntasks=1任务数
--cpus-per-task--cpus-per-task=8每任务CPU核心数
--mem--mem=16G总内存
--mem-per-cpu--mem-per-cpu=4G每核心内存
--time--time=04:00:00最大运行时间
--output--output=logs/%j.out输出文件
--error--error=logs/%j.err错误文件
--array--array=1-100%10数组任务
--gres--gres=gpu:2GPU申请
--mail-type--mail-type=END,FAIL邮件通知类型

11.3 SLURM vs PBS 对照表

功能SLURMPBS/Torque
提交任务sbatchqsub
查看任务squeueqstat
取消任务scancelqdel
查看节点sinfopbsnodes -a
任务详情scontrol show jobqstat -f
脚本指令前缀#SBATCH#PBS
CPU指定--cpus-per-task=8-l nodes=1:ppn=8
内存指定--mem=16G-l mem=16gb
时间指定--time=04:00:00-l walltime=04:00:00
数组任务--array=1-100-t 1-100
工作目录默认在提交目录需手动 cd $PBS_O_WORKDIR
环境变量-任务ID$SLURM_JOB_ID$PBS_JOBID
环境变量-数组索引$SLURM_ARRAY_TASK_ID$PBS_ARRAYID

12. 延伸资源

资源说明
SLURM官方文档最权威的参考,V25.11
SLURM Quick Start官方入门指南
Snakemake SLURM PluginSnakemake 8.x SLURM执行器文档
Nextflow ExecutorsNextflow支持的调度器列表
你所在集群的Wiki/文档每个集群的分区名、资源限制不同,一定要看本地文档

记住: HPC集群的核心思想就三步——写脚本(告诉系统你要干什么、需要多少资源)→ 提交排队(sbatch/qsub)→ 查看结果(squeue/sacct + 输出文件)。不要在登录节点跑大任务,不要申请远超实际需求的资源,这是集群使用的两条基本礼仪。