使用手册
使用前请仔细阅读本手册
远程登录
登录方式
远程控制-登录方式
请务必首先仔细阅读上述远程控制-登录方式内容,并合并覆盖以下内容:
登录节点信息
| Hostname | IP | OS |
|---|---|---|
| login1 | 10.1.0.101 | CentOS 7 |
| login2 | 10.1.0.102 | Rocky 9 |
| login9 | 10.1.0.109 | Rocky 9 |
账号密码
- 账号:集群用户名
- 密码:集群密码
Web
- Web支持图形界面xfwd、命令行界面ssh,文件传输sftp
SSH
- Username: 输入集群用户名 或 集群用户名/登录节点IP/self(如用户名是yaoge需要登录到login9,则输入yaoge/10.1.0.109/self)
SFTP
- Username: 输入集群用户名/登录节点IP/self(如用户名是yaoge需要登录到login9,则输入yaoge/10.1.0.109/self)
注意事项
- 必须通过作业调度系统进行计算,不得在登录节点或计算节点直接运行计算程序,否则会被杀掉进程
- 登录后用 passwd 命令更改密码,密码至少8个字符,包含小写字母、大写字母、数字和特殊字符中至少三种,不能是常见密码
VPN
南京大学 VPN
- 使用南京大学统一身份认证账号、密码登录南京大学VPN
- 南京大学VPN使用方法参考信息化建设管理服务中心网站
eScience中心 VPN
- 从官网(中文) 官网(English)下载安装对应的 VPN 客户端
- 服务器:cm.yaoge123.cn
- 端口:4433
- 用户名、密码:超算的用户名密码,注意密码不含动态口令
- 登录后仅能通过此VPN访问eScience中心的服务
数据传输
- SFTP:使用SFTP客户端浏览并传输文件,适合大文件和整个目录的上下传。
- ZMODEM:在登录节点上可用rz上传文件、sz下载文件,适合单个小文件的上下传。
- 云盘:通过云盘自动同步、传输和备份文件。
- 传输节点:专门的数据传输节点。
- 数据拷贝:直接使用移动硬盘拷贝大量数据文件。
传输节点
独立的数据传输节点,账号与集群用户名一致,密码独立且无动态口令。
数据存储-归档存储
集群借用了stor.nju.edu.cn用于数据传输节点,故请务必首先阅读上述数据存储-归档存储中FTP和SFTP内容,并合并覆盖以下内容:
- 账号:集群用户名
- 密码:~/stor_passwd文件中
开通方式
传输节点账号采用自助开通方式,进行如下操作后需要等待大约1小时生效
- 开通账号:
touch ~/stor_passwd - 查看密码:
cat ~/stor_passwd - 重置密码:
> ~/stor_passwd - 禁用账号:
rm ~/stor_passwd
为安全起见,查看完密码后建议将文件内容改为非空占位文本(如 echo ok > ~/stor_passwd),避免明文长期保留。
数据拷贝
为方便大数据传输,中心提供数据拷贝服务,用户需提供大容量移动存储设备,文件系统格式为 ext4/XFS/exFAT ,并告知需要拷贝数据的目录(绝对路径),保证剩余空间足够。
- 推荐使用文件系统为 ext4/XFS ,Linux可以直接读写,Windows的WSL(Windows Subsystem for Linux)也可以直接读写。
- exFAT 可以方便的同时被 Windows 和 Linux 读写,但是某些情况下无法拷贝文件,且对于机械硬盘不适于长期使用。
集成云盘
独立账号
高性能计算集群用户可以使用集群账号直接登录云盘,用户名为集群账号@hpc.nju.edu.cn,密码即集群账号密码;如集群账号为yaoge,用户名填写yaoge@hpc.nju.edu.cn。首次使用需要登录网页端激活账号,但集群账号不能使用云盘的上下传外链功能。
云盘上的集群账号与南京大学统一身份认证账号相互独立,如集群账号yaoge@hpc.nju.edu.cn和南京大学统一身份认证账号0102003是两个完全独立的账号,需要分别激活才能使用。
文件同步
通过云盘的多平台多终端同步功能,可将集群中的目录和本地计算机的目录同步,对本地目录的操作几乎立刻反应在集群的目录中,不再需要通过 SFTP 上下传文件。
- 计算结果输出到集群同步目录中,本地计算机会自动下载,可在本地直接查看和编辑输出文件;
- 计算输入文件放到本地同步目录中,集群会自动下载,直接引用输入文件即可提交作业。
客户端
登录节点已安装云盘同步客户端和挂载盘客户端
- 同步客户端命令行界面:seaf-cli(Linux命令行同步客户端手册)
- 同步客户端图形化界面:seafile-applet
- 挂载盘客户端命令行界面:seadrive(Linux命令行挂载盘手册)
- 挂载盘客户端图形化界面:seadrive-gui
除官方客户端外,也支持rclone便捷操作。
挂载盘命令行客户端
-
获取Token(
<username>替换为集群账号,<password>替换为密码)curl -d 'username=<username>@hpc.nju.edu.cn' -d 'password=<password>' https://box.nju.edu.cn/api2/auth-token/ -
创建配置文件
~/seadrive.conf,<username>替换为集群账号,<token>替换为上一步的返回值[account] server = https://box.nju.edu.cn username = <username>@hpc.nju.edu.cn token = <token> is_pro = true [general] client_name = hpc-login [cache] size_limit = 10GB clean_cache_interval = 10 -
启动挂载盘,命令在前台运行,新开一个窗口进行其它操作
seadrive -c ~/seadrive.conf -f -d ~/.seadrive/data -l ~/.seadrive/data/logs/seadrive.log ~/SeaDrive -
如果报错
Transport endpoint is not connected,执行:fusermount -u ~/SeaDrive -
~/SeaDrive目录就是云盘挂载在本地的目录,可以直接读写访问
同步命令行客户端
- 创建客户端本地数据目录(目录名可更改)
mkdir ~/Seafile - 初始化客户端并指定本地数据目录(上一步创建的目录)
seaf-cli init -d ~/Seafile - 启动客户端
seaf-cli start - 列出云盘资料库ID(
<username>替换为集群账号)seaf-cli list-remote -s https://box.nju.edu.cn -u <username>@hpc.nju.edu.cn - 将本地目录与云盘资料库同步(
<library-id>替换为上一步列出的某个资料库ID,<folder>替换为本地目录)
将云盘资料库下载到本地目录seaf-cli sync -s https://box.nju.edu.cn -u <username>@hpc.nju.edu.cn -l <library-id> -d <folder>seaf-cli download -s https://box.nju.edu.cn -u <username>@hpc.nju.edu.cn -l <library-id> -d <folder> - 查看当前同步状态
seaf-cli status - 解除本地目录同步
seaf-cli desync -d <folder> - 停止客户端
seaf-cli stop
使用 rclone 进行云端文件操作
rclone 是一个强大的云存储管理工具,云盘也在其支持的存储类型内。使用rclone可以更加符合命令行用户使用习惯地去存取云盘文件。
- (登录后第一次需要)启用
rclone工具module load rclone - (仅需设置一次)初次使用
rclone需要进行设置。在~/.config/rclone/目录下创建一名为rclone.conf的文件,内容(<username>替换为集群账号)如下:;不一定必须叫 hpc_box,你可以任意设置这个标签,但是后文必须相应地使用该标签 [hpc_box] type = seafile url = https://box.nju.edu.cn user = <username>@hpc.nju.edu.cn ;如果开启了两步认证,下条设置为true 2fa = false - (仅需设置一次)设置密码。
<password>替换为密码:rclone config update hpc_box pass <password> - 设置完毕后,之后按照下方使用即可。列出云端目录:
rclone lsd hpc_box: - 创建云端资料库(
<library>替换为资料库名):rclone mkdir hpc_box:<library> --seafile-create-library #例如, rclone mkdir hpc_box:test --seafile-create-library 将在云盘创建一个名为`test`的资料库。 - 向云端上传文件。
<destination_path>替换为需要上传的本地路径,<source_path>替换为云端路径:rclone copy <destination_path> hpc_box:<source_path> #例如,假设本地当前目录下有个 myfile.txt 文件: #rclone copy myfile.txt hpc_box:test 将把本地当前目录的 myfile.txt 文件上传至云端的 test 资料库下。 #再例如,假设本地当前目录下有个 myfolder 文件夹,里面有很多文件: #rclone copy myfoler hpc_box:test 将把本地当前目录的 myfolder 文件夹内的所有文件夹和文件(不包括 myfolder 自身)上传至云端的 test 资料库下。 - 从云端下载文件:
rclone copy hpc_box:<source_path> <destination_path> #例如,假设云端资料库`test`下有个 myfile.txt 文件: #rclone copy hpc_box:test/myfile.txt . 将把云端资料库`test`下的 myfile.txt 下载至本地当前目录。 #例如,假设云端资料库`test`下有个 myfolder 文件夹,里面有很多文件: #rclone copy hpc_box:test/myfolder . 将把云端资料库`test`下的 myfolder 文件夹内的所有文件夹和文件(不包括 myfolder 自身)下载至本地当前目录。 - 在传输过程中,如果加上
-P会显示进度条,强烈建议添加;如果上传或下载过程中,文件较多,建议再加上--no-traverse避免列出文件导致传输时间过长:rclone copy hpc_box:<source_path> <destination_path> -P --no-traverse #例如,假设云端资料库`test`下有个 myfile.txt 文件: #rclone copy hpc_box:test/myfolder . -P --no-traverse 将把云端资料库`test`下的 myfolder 文件夹内的所有文件夹和文件(不包括 myfolder 自身)下载至本地当前目录,且显示进度条,不列出所有文件。 - 更多
rclone的用法见rclone - commands;若有加密资料库等其他云盘需求,或查看rclone对云盘的支持功能,请参考rclone - seafile或rclone - storage systems。
环境变量
集群使用Environment Modules以模块的形式对环境变量进行管理。在高性能计算集群系统中,安装有多种软件及其不同版本,它们需要设置不同的环境变量,Environment Module可以将这些环境变量做成模块文件(modulefile)。模块可以被加载(load)、卸载(unload)、切换(switch)等,这些操作会改变相应的环境变量设置,让用户方便的在不同环境之间切换。相比将环境变量设置写入/etc/profile、~/.bashrc或~/.bash_profile,Environment Module操作只影响当前用户的当前登录环境;相比直接source文件,Environment Module的操作可以撤销(卸载)。普通用户还可以自己编写module,具有很好的定制性。用户不仅可以在命令行中Environment Modules,也能在作业提交脚本中使用,对编译和计算环境都能够很好的控制。
常用命令
- 显示module帮助:module help
- 显示所有可用模块:module avail
- 显示已加载模块:module list
- 加载模块:module load MODULEFILE
- 卸载模块:module unload MODULEFILE
- 切换模块:module switch OLD_MODULEFILE NEW_MODULEFILE(等价于:module unload OLD_MODULEFILE; module load NEW_MODULEFILE)
- 卸载所有已加载模块:module purge
- 显示模块说明:module whatis MODULEFILE
- 显示模块内容:module display MODULEFILE
- 增加搜索目录:module use
- 减少搜索目录:module unuse
非 Bash
使用非 Bash 作为 Login Shell 的用户,请在作业提交脚本的首行指明 Shell 或使用 bsub 选项 -L 指定作业运行时 Login Shell 为 Bash
如 Login Shell 为 tcsh,使用下面两种方法中的一种
#!/bin/tcsh #首行指明Shell
#BSUB ...
...
...
#BSUB -L /bin/bash #指定运行时Login Shell为Bash
...
加载模块示例
$ module avail #查看所有可用模块
------------------------------ /fs00/software/modulefiles ------------------------------
gcc/5.2.0 impi/5.0.3.048
iccifort/15.0.3 ips/2011sp1u3
ics/2013 ips/2015u3
ics/2013sp1u1 openmpi/1.10.0-gcc-5.2.0
imkl/11.2.3 openmpi/1.10.0-iccifort-15.0.3
$ module list #显示已加载模块
No Modulefiles Currently Loaded. #没有模块被加载
$ icc --version #故icc找不到
-bash: icc: command not found
$ module whatis ips/2015u3 #查看模块说明
ips/2015u3 : Intel Parallel Studio XE 2015 Update 3 Cluster Edition
$ module load ips/2015u3 #加载模块
$ icc --version
icc (ICC) 15.0.3 20150407
Copyright (C) 1985-2015 Intel Corporation. All rights reserved.
$ module list #显示已加载模块
Currently Loaded Modulefiles:
1) ips/2015u3
$ module unload ips/2015u3 #卸载模块
搜索路径示例
$ module use
Search path for module files (in search order):
/fs00/software/modulefiles
$ module avail
--- /fs00/software/modulefiles ---
gcc/12.1.0
……
$ module use /fs00/software/modulefiles/oneapi/2024.0 #添加MODULEPATH搜索目录
$ module use
Search path for module files (in search order):
/fs00/software/modulefiles/oneapi/2024.0
/fs00/software/modulefiles
$ module avail
--- /fs00/software/modulefiles/oneapi/2024.0 ---
mkl32/2024.0
compiler/2024.0.2
mkl/2024.0
……
--- /fs00/software/modulefiles ---
gcc/12.1.0
……
提交作业
集群使用作业调度系统管理所有计算作业,该系统接受用户的作业请求,并将作业合理的分配到合适的节点上运行,因此所有用户均应通过作业调度系统提交计算作业,不可直接在任何节点上直接运行。
LSF
用户使用bsub命令向作业调度系统提交作业,bsub选项非常繁多,可对作业进行非常细致的控制,这里简要介绍常用选项和方法。
bsub 使用方式
命令行方式
bsub [options] command [arguments]
[options]为 bsub 的选项,可以设定队列、CPU核数等command为计算程序,如果是 MPI 并行程序需要使用 mpirun 启动[arguments]为计算程序的参数
例:提交一个作业到 e5v3ib 队列,需要24核的 MPI 并行程序
$ bsub -q e5v3ib -n 24 "module load oneapi/2024.0/mpi && mpirun ./app" Job <3206000> is submitted to queue <e5v3ib>
脚本方式
bsub < jobfile
jobfile 为作业的 shell 脚本文件,文件名任意且不需要运行权限,脚本内容如下:
#BSUB [options]
command [arguments]
脚本中以#BSUB开头的行后跟bsub的选项,其它行为作业运行脚本
例:提交一个作业到 e5v3ib 队列,需要48核,需要大内存节点,作业名为 MgSiO3,标准输出文件为
out,标准错误输出文件为err,Intel MPI 的并行作业0$ cat job.lsf #BSUB -q e5v3ib #BSUB -n 48 #BSUB -J MgSiO3 #BSUB -o out #BSUB -e err module load ips/2018u4 mpirun ./app $ bsub < job.lsf Job <3207099> is submitted to queue <e5v3ib>.等价如下命令行方式
$ bsub -q e5v3ib -n 48 -J MgSiO3 -o out -e err "module load ips/2018u4;mpirun ./app" Job <3207099> is submitted to queue <e5v3ib>.
bsub 常用选项
-J job_name:作业名称
资源请求
-n min_tasks[,max_tasks]:作业需要CPU核数;例:需要四核-n 4;需要4~8核均可-n 4,8-m:作业运行的节点或节点组,多个节点写在双引号内并用空格分隔,节点组对应的具体节点可用bmgroup命令查看,此选项很复杂。在 hostname/hostgroup 前后可用这些符号:后加!指定头结点、后加+[num]指定节点使用顺序。例:指定在 c04n01 和 c04n02 运行-m "c04n01 c04n02";指定可在 f01n01~n03,但是最希望在 f01n01、次希望在 f01n02-m "f01n01+2 f01n02+1 f01n03";-R "res_req":资源请求串,此选项非常复杂;例:有的队列某些节点内存较大,需要大内存节点可以指定 -R largemem-R "select[hname!=host_name]":排除host_name节点,如果要排除多个节点中间用&&连接,如-R "select[hname!=x001 && hname!=x002]"排除x001和x002节点-x:作业需要独占节点,无论申请多少核,作业均独占所运行的节点-W [hour:]minute:作业运行最长时间,超过这个时间则被 kill
CPU绑定
-R affinity[core:cpubind=core:membind=localprefer:distribute=pack]:作业调度系统将进行CPU亲和性绑定,注意可能会和程序本身(如MPI)的绑定冲突,使用前请测试!
自动重运行
-r:如果计算节点或系统故障则自动重新运行作业-Q "exit_code [exit_code ...]":根据作业退出码自动重新提交作业。使用空格分隔多个退出码,all指所有退出码,加~排除一个或多个退出码。
输入输出
-I:交互式作业,可在作业运行期间和程序进行交互(如输入参数等),可在调试期间使用,正常计算请勿使用-K:等待作业执行完才返回-i input_file:标准输入文件-o output_file:标准输出文件-e error_file:标准错误输出文件- 以上三个选项的文件名中可以包含
%J用于表示 JOBID。如果没有用-o或-oo指定标准输出文件,那么系统会自动设定为output_%J;如不想要输出文件请设置-o /dev/null
更多选项见官方文档
GPU 作业
提交作业时使用 -gpu 选项申请所需的 GPU 资源,计算进程只可见作业调度系统分配的 GPU。CPU 核自动按照申请节点 GPU 的比例分配,如一节点8个 GPU 和40个 CPU 核,申请2个 GPU 则分配10个 CPU 核。
-gpu 的各个选项用:分隔,默认值为num=1:mode=shared:mps=no:j_exclusive=yes,常用选项如下
num=number:每台主机需要GPU的数量mode=shared | exclusive_process:GPU运行模式,shared对应 Nvidia/AMD DEFAULT compute mode、exclusive_process对应 Nvidia EXCLUSIVE_PROCESSmps=yes | no:开启或关闭Nvidia Multi-Process Service (MPS)。关闭MPS,多进程通过时间分片的方式共享GPU;开启MPS,多进程共享一个CUDA Context并发执行,增加了GPU利用率aff=yes | no:是否强制进行严格的 GPU-CPU 亲和性绑定,还需要配合-R affinity[core:cpubind=core:membind=localprefer:distribute=pack]才能一同完成GPU-CPU亲和性绑定
作业依赖
一个计算任务可能分成几步,而每一步对资源的需求不同,因此需要分开提交,但这些作业之间又具有依赖关系,bsub 可使用选项 -w 'dependency_expression'指定依赖关系。如果计算任务分成几步,但是每步对资源需求一样,那么请写在一个作业任务中依次执行。
-w 'done(job_ID | "job_name")':需要 job_ID 或 job_name 作业完成且状态为 DONE,即退出码为0-w 'ended(job_ID | "job_name")':需要 job_ID 或 job_name 作业完成或退出,状态为 EXIT 或 DONE- 支持逻辑表达式&& (AND)、|| (OR)、! (NOT)
- 孤儿作业(即依赖条件不可能满足的)1分钟后会被自动终止
更多详细信息见官方文档
MPI/OpenMP 混合作业
OpenMP (Open Multi-Processing) 是一种共享内存方式的单进程多线程并行编程技术;MPI (Message Passing Interface) 是一种多进程基于信息传递的并行编程技术。OpenMP 的特点是单节点、进程内、多线程、基于共享内存的并行运算;MPI 的特点是单或多节点、进程间、非共享内存、基于消息传递的并行运算。
混合并行编程模型构建的应用程序可以同时使用 OpenMP 和 MPI ,节点内NUMA内进程内使用 OpenMP 共享内存并行可降低内存需求,跨节点跨NUMA跨进程使用 MPI 消息传递可大规模并行。需要注意的是,并不是一个节点一个MPI进程是最优的,这往往会导致跨NUMA的内存访问,因此需要通过测试确定最佳配比。
mpirun一般会根据环境变量LSB_MCPU_HOSTS启动相应的MPI进程,因此可以通过下列方法改变此环境变量中每个节点的CPU核数,以匹配MPI/OpenMP混合作业的MPI进程分布:
#BSUB -n指定的仍然是总CPU核数- 提交作业脚本中需要在计算命令前首先运行
source /fs00/software/lsf/misc/ompthreads.sh [N] - 每个 MPI 进程的 OpenMP 线程数量可以用环境变量
OMP_NUM_THREADS指定或上述命令行参数指定,同时指定时命令行参数优先,需要保证每个节点的 CPU核数可以被线程数整除!
常用环境变量
作业运行时
- LSB_JOBID:作业ID
- LSB_QUEUE:队列名称
- LSB_JOBNAME:作业名称
- LSB_DJOB_NUMPROC:分配的CPU总核数
- LSB_DJOB_HOSTFILE:分配的节点列表文件,每行一个
- LSB_HOSTS:分配的节点列表,每个CPU核一个节点名的纯节点列表
- LSB_MCPU_HOSTS:分配的节点和核数列表,每个节点名和CPU核数的列表
LSB_DJOB_NUMPROC=6
LSB_HOSTS="node1 node1 node1 node2 node2 node2"
LSB_MCPU_HOSTS="node1 3 node2 3"
$ cat $LSB_DJOB_HOSTFILE
node1
node1
node1
node2
node2
node2
LSB_HOSTS 和 LSB_MCPU_HOSTS 以不同的格式包含相同的信息,LSB_MCPU_HOSTS 比 LSB_HOSTS 更短更精简,如果 LSB_HOSTS 超过 4096 字节,则仅有 LSB_MCPU_HOSTS。
作业脚本示例
串行作业
提交一个串行作业到 e52660 队列,命令行方式和脚本方式分别为:
$ bsub -q e52660 ./app
Job <3279929> is submitted to queue <e52660>.
$ cat job.lsf
#BSUB -q e52660
./app
$ bsub < job.lsf
Job <3279930> is submitted to queue <e52660>.
MPI 并行作业
MPI程序需要使用mpirun启动
提交一个需要48核的 Intel MPI 并行作业到 e5v3ib,命令行方式为:
$ bsub -q e5v3ib -n 48 "module load ips/2018u4;mpirun ./app"
Job <3280120> is submitted to queue <e5v3ib>.
提交一个需要48核的 Open MPI 并行作业到 e5v3ib,脚本方式为:
$ cat job.lsf
#BSUB -q e5v3ib
#BSUB -n 48
module load iccifort/15.0.3 imkl/11.2.3 openmpi/1.10.0-iccifort-15.0.3
mpirun ./app
$ bsub < job.lsf
Job <3280122> is submitted to queue <e5v3ib>.
OpenMP 并行作业
OpenMP 不能跨节点,因此-n不能指定超过一个节点的CPU核数
提交一个需要64核的 OpenMP 并行作业到 e7v4ib,使用程序参数 -nt 指定线程数量,命令行方式为:
$ bsub -q e7v4ib -n 64 "./app-nt \$LSB_DJOB_NUMPROC"
Job <3348175> is submitted to queue <e7v4ib>.
提交一个需要64核的 OpenMP 并行作业到 e7v4ib,使用环境变量OMP_NUM_THREADS指定线程数量,脚本方式为:
$ cat job.lsf
#BSUB -q e7v4ib
#BSUB -n 64
OMP_NUM_THREADS="$LSB_DJOB_NUMPROC"
./app
$ bsub < job.lsf
Job <3348182> is submitted to queue <e7v4ib>.
MPI/OpenMP 混合作业
每个MPI进程跑6个OpenMP线程
通过环境变量OMP_NUM_THREADS指定
#BSUB -q 6140ib
#BSUB -n 72
export OMP_NUM_THREADS=6
source /fs00/software/lsf/misc/ompthreads.sh
module load ips/2018u4
mpirun ./run
通过命令行参数指定(有些计算程序需要通过命令行参数指定线程数量)
#BSUB -q 6140ib
#BSUB -n 72
source /fs00/software/lsf/misc/ompthreads.sh 6
module load ips/2018u4
mpirun ./openmx -nt 6
GPU 作业
提交一个需要1个 GPU 的作业到 e5v4p100ib 队列
bsub -q e5v4p100ib -gpu num=1 ./gpu_app
提交一个需要4个 GPU 的作业到 62v100ib 队列,进行 GPU-CPU 绑定
bsub -q 62v100ib -gpu "num=4:aff=yes" ./gpu_app
Slurm
在 Slurm 中,sbatch 用于提交批处理作业;srun 用于启动作业步骤,通常用于运行并行程序,也可用于启动交互式任务。
Slurm 作业提交方式
批处理作业方式 (sbatch)
sbatch 用于提交批处理作业。用户将资源需求、环境配置和任务执行命令写入脚本,通过 sbatch 提交,由 Slurm 调度系统负责资源分配、作业调度和任务启动。
sbatch job.slurm
提交成功后,Slurm 返回作业 ID。
sbatch 直接读取脚本内容,因此 job.slurm 脚本文件不需要执行权限,其基本结构如下:
#!/bin/bash
#SBATCH [options]
command [arguments]
脚本中以 #SBATCH 开头的行用于向 Slurm 指定作业参数,包括资源需求、作业名称、输出文件、运行时间等。
示例:通过
sbatch提交一个 MPI 并行作业$ cat job.slurm #!/bin/bash #SBATCH -p Partition # 指定分区 #SBATCH -J MyMPIJob # 作业名称 #SBATCH -N 2 # 请求 2 个节点 #SBATCH --ntasks-per-node=24 # 每个节点启动 24 个 task(MPI rank) #SBATCH -o output_%j.log # 标准输出文件 (%j 会被替换为 Job ID) #SBATCH -e error_%j.log # 标准错误文件 module load <MPI环境> srun ./app $ sbatch job.slurm Submitted batch job 3207099
交互式与单行命令方式 (srun)
srun 用于在分配到的资源上启动任务。配合 --pty 可以开启交互式终端,常用于代码调试:
# 申请 1 个节点、4 个核心,开启一个交互式 bash 终端
$ srun -p e5v3ib -N 1 -c 4 --pty bash
如果是临时提交一条简单的非交互命令,可以使用 sbatch --wrap:
$ sbatch -p e5v3ib -n 24 --wrap="srun ./app"
常用 sbatch/srun 选项
基础选项
-
-p, --partition=partition_name:指定作业提交的分区(队列)。 -
-J, --job-name=job_name:指定作业名称。 -
-t, --time=[days-]hours:minutes:seconds:作业运行的最长时间。超时会被系统自动 kill。- 示例:
-t 10(10分钟),-t 02:30:00(2小时30分),-t 1-00:00:00(1天)。
- 示例:
核心资源请求
在 Slurm 中,必须严格区分“任务 (Task/进程)”与“CPU核心 (CPU Core/线程)”。
-N, --nodes=num:作业申请的节点总数。-n, --ntasks=num:作业申请的总任务数(通常对应 MPI 进程数)。如果不指定--cpus-per-task,默认每个任务分配 1 个 CPU 核心。--ntasks-per-node=num:每个节点上运行的任务数。-c, --cpus-per-task=num:每个任务需要的 CPU 核心数(通常用于多线程程序,如 OpenMP)。作业请求的总 CPU 核数 =ntasks×cpus-per-task。--mem=<size>[K|M|G|T]:每个节点申请的内存大小(如--mem=16G)。若未指定,系统会分配默认内存值,超出可能被 kill。--mem-per-cpu=MB:按每个 CPU 核心申请内存。- 对于纯MPI作业,
cpus-per-task默认为1;对于 OpenMP 或混合作业,必须显式设置-c。
节点选择与控制
-w, --nodelist=host_list:指定作业必须运行在哪些节点上,多个节点用逗号分隔(如-w "node01,node02")。-x, --exclude=host_list:排除发生故障或不希望运行的节点。-C, --constraint=features:请求具有特定属性(如大内存、特定 CPU 型号)的节点(如-C largemem)。--exclusive:作业独占整个计算节点,即使只申请了部分核心,其他用户的作业也无法调度到该节点。
输入输出控制
-o, --output=filename:标准输出文件。可以使用%j代表作业 ID。若未显式指定,默认为slurm-%j.out。-e, --error=filename:标准错误输出文件。-W, --wait:阻塞模式,等待作业执行完毕才返回终端提示符。
作业依赖
如果计算任务分多步进行,可以使用 -d, --dependency=dependency_expression 控制先后执行顺序。
-d afterok:job_ID:当前作业需等待job_ID完成且成功退出(退出码为0)后才开始。-d afternotok:job_ID:当前作业需等待job_ID完成且失败退出(退出码非0)后才开始(常用于错误处理)。-d afterany:job_ID:无论job_ID成功与否,只要它运行结束,当前作业即开始。- 支持多个依赖条件,用逗号
,分隔或使用问号?分割,但分隔符只能同时使用其中一种,不能混用。
GPU 作业分配
申请 GPU 资源时,必须显式指定需要的 GPU 数量。系统默认不会根据 GPU 数量自动为您分配相应比例的 CPU 或内存,您应当手动搭配所需的 CPU 核心数。
--gres=gpu:number:每个节点申请number个 GPU。--gpus=number:作业申请的总 GPU 数量。--gpus-per-node=number:每个节点申请的 GPU 数量。
示例:单节点 4 卡 GPU 作业
#!/bin/bash
#SBATCH -p gpu_part
#SBATCH -N 1
#SBATCH --gres=gpu:4 # 申请 4 张 GPU
#SBATCH -c 16 # 为这 4 张显卡显式搭配 16 个 CPU 核心处理数据
#SBATCH --mem=64G # 显式申请内存
srun python train.py
- 若单个节点有多个型号GPU,需要指定GPU型号则使用
#SBATCH --gpus-per-node=<gpu_type>:<gpu_number>
示例:指定一块A100显卡
#SBATCH --gpus-per-node=a100:1
控制作业
LSF
常用控制命令
| 命令 | 功能 |
|---|---|
bjobs |
查看自己未结束的作业 |
bjobs -l JOBID |
查看某个未结束作业的详情 |
bhist |
查看自己已结束的历史作业 |
bhist -l JOBID |
查看某个已结束历史作业的详情 |
bpeek JOBID |
查看正在运行某个作业的stdout/stderr |
bkill JOBID |
终止某个作业 |
btop JOBID |
设置作业最先运行 |
bbot JOBID |
设置作业最后运行 |
作业状态
bjobs命令的作业状态可能值包括:
| 状态 | 描述 |
|---|---|
| PEND | 作业正在等待中。也就是说,作业尚未开始。 |
| PROV | 作业已被派发到一个正在唤醒的节能状态主机。在作业可以发送到 sbatchd之前,它处于PROV状态。 |
| PSUSP | 作业在等待期间被挂起,可能是作业所有者或LSF管理员操作的。 |
| RUN | 作业当前正在运行。 |
| USUSP | 作业在运行期间被挂起,可能是作业所有者或LSF管理员操作的。 |
| SSUSP | 作业被LSF挂起。 |
| DONE | 作业以状态0终止。 |
| EXIT | 作业以非零状态终止。 |
| UNKWN | 一般是两种情况之一,如果作业状态长时间处于UNKWN状态,一般来 说就是计算节点坏了可以直接杀掉作业。①因为计算节点负载过高,未 能及时获取作业状态导致状态未知,这种情况一般只需要等待即可,待 负载下降获取状态后就正常了。②因为计算节点出现故障且长时间未恢 复,调度系统无法获取作业状态,此时如果登录不到相应的计算节点, 可以直接杀掉作业。 |
| WAIT | 对于提交到块作业队列的作业,块作业中的成员正在等待运行。 |
| ZOMBI | ①当sbatchd在执行主机上不可达时,非可重新运行的作业被bkill杀死,并且作业显示为UNKWN。 ②运行可重新运行作业的主机不可用,并且LSF 已将作业重新排队,分配了新的作业ID,就像提交了新作业一样。 ③在执 行主机可用之后,LSF尝试杀死ZOMBI作业。ZOMBI作业成功终止后,作业 的状态将更改为EXIT。 使用MultiCluster时,当在远程执行群集上运行的作 业变为ZOMBI作业时,执行群集将像本地ZOMBI作业一样处理该作业。此外, 它还会通知提交群集作业处于ZOMBI状态,并且提交群集将重新排队作业。 |
作业等待
bwait -w "wait_condition" [-t timeout]
暂停并等待作业条件满足,不满足一直暂停等待,满足则执行完毕返回。
典型用法:在脚本中不要循环使用bjobs判断作业状态,而用bwait等待作业运行完成,这样更优雅且能显著降低对集群的压力。
-w wait_condition:要满足的等待条件,此表达式与上述bsub -w选项的格式相同。-t timeout:等待条件的超时,范围为1-525600分钟,默认为一年。
Slurm
常用控制命令
| 命令 | 功能 |
|---|---|
squeue --me (或 squeue -u $USER) |
查看自己正在排队或运行的未结束作业 |
scontrol show job JOBID |
查看某个未结束作业的详细配置(如分配节点、环境变量、资源限制等) |
sacct |
查看自己历史作业的简要信息 |
sacct -j JOBID -l |
查看某个已结束历史作业的详细统计信息(包括内存峰值、CPU使用效率、退出状态等) |
tail -f slurm-JOBID.out |
查看正在运行作业的标准输出(注:Slurm 没有直接对应的 bpeek,通常直接查看其定义的输出文件即可) |
scancel JOBID |
终止某个作业 |
scancel -u $USER |
终止属于该用户的所有作业(排队与运行中的) |
scontrol top JOBID |
请求将处于排队状态的作业置于队列顶部(需系统配置允许,仅影响自己的作业优先级排序) |
scontrol hold JOBID |
挂起作业(暂停排队) |
scontrol release JOBID |
解除挂起(允许作业继续排队调度) |
作业状态
squeue 或 sacct 命令输出中的状态标识(通常简写为两个字母)可能包括以下常见值:
| 状态 (简写) | 描述 |
|---|---|
| PENDING (PD) | 作业正在等待资源分配。即作业仍在排队中尚未开始。 |
| CONFIGURING (CF) | 资源已被分配,但计算节点正在启动或配置环境(例如从节能模式唤醒)。 |
| RUNNING (R) | 作业当前正在计算节点上运行。 |
| COMPLETING (CG) | 作业正在结束,系统正在回收资源和清理进程。 |
| COMPLETED (CD) | 作业以状态 0 成功终止(所有进程均正常退出)。 |
| FAILED (F) | 作业以非零状态终止,或其他严重错误导致运行失败。 |
| CANCELLED (CA) | 作业被用户或管理员手动取消(如使用 scancel 命令)。 |
| TIMEOUT (TO) | 作业运行时间超过了申请的限制时间 (-t),被调度器强制终止。 |
| OUT_OF_MEMORY (OOM) | 作业使用的内存超出了申请的上限,被系统内核 OOM Killer 杀掉。 |
| SUSPENDED (S) | 作业在运行期间被挂起。通常是因为高优先级作业抢占资源,或管理员手动操作。 |
| NODE_FAIL (NF) | 作业所在节点发生硬件故障或失联导致作业非正常终止。 |
| UNKNOWN (UN) | 调度系统无法获取作业状态。一般是因为计算节点长时间故障或与控制节点断开连接。此时如果登不上计算节点,可以直接 scancel 杀掉作业。 |
作业等待与依赖控制
在 LSF 中存在独立的 bwait 工具。在 Slurm 中,严禁在 Shell 脚本中使用 while 循环加 squeue 的方式高频轮询作业状态,这会对调度器数据库造成灾难性的压力。
请使用以下优雅的标准替代方案:
提交并阻塞等待 (--wait)
如果你希望在终端或外部脚本中提交作业后挂起,直到该作业执行完毕才继续往下走,请在提交时添加 -W, --wait 选项:
sbatch -W job.slurm
此命令会一直挂起,直到 job.slurm 执行完毕(无论成功或失败)才会返回终端提示符。
利用调度器依赖树 (--dependency)
如果你有一个作业 B 必须在作业 A 完成后才能运行,应在提交作业 B 时声明依赖关系交由系统管理:
# 假设提交作业 A 后返回的 JOBID 为 10001
sbatch --dependency=afterok:10001 job_B.slurm
作业 B 会被调度器以 Dependency 的原因置于 PENDING 状态。作业 A 成功结束后,B 才会开始参与资源调度分配。
脚本中等待已经运行的作业 (伪作业阻塞法)
如果确实需要在一个独立的 Shell 脚本中阻塞等待一个已经提交并正在运行的作业(例如 JOBID 10001)结束,可以向系统提交一个零操作的极轻量级伪作业,并配合 --wait:
sbatch -W --dependency=afterany:10001 --wrap="exit 0"
此时当前 Shell 脚本将暂停。一旦 10001 结束,这个包装作业会被立刻触发执行并瞬间结束,Shell 脚本随之恢复运行。这完美替代了 bwait 功能且对集群完全无害。
海量作业
作业组
为了便于管理海量的作业,可以对作业定义作业组。
作业组的名字是类似于Linux的路径名的树状结构,如作业组 /test ,而 /test/1 和 /test/2 都属于 /test
需要注意的是作业组是全局的,创建者是这个作业组的拥有者,作业组拥有者可以对这个作业组及其子组内的所有作业进行控制(哪怕这个作业是其他人提交的,拥有者也能进行控制)。如果您不想作业被别人控制,请确保提交到的作业组从/开始拥有者都是自己。
创建作业组
bgadd /test #显式创建作业组
bsub -g /test #使用bsub提交作业时指定一个不存在的作业组,则作业组会被隐式创建
查看作业组
bjgroup /test #最后一列就是作业组的拥有者,请注意拥有者也是层次继承的
删除作业组
bgdel /test #集群已经配置自动清理空的隐式创建的作业组
有了作业组以后就可以对一组作业进行控制了
bjobs -g /test #查看指定作业组的作业
bkill -g /test 0 #终止指定作业组的所有作业
作业序列
作业序列是一系列作业,这些作业执行相同的操作和资源要求,但是输入输出文件不同。这些作业共享同一个作业ID,并可以通过索引来区分每个子作业。
bsub 使用 -J "arrayName[indexList, ...]" 参数命名并创建一个作业序列,也可以理解为一个作业数组,中括号里面就是数组的下标,可以是一维数组也可以是多维数组。indexList = start[-end[:step]] 下标的起始、结束和步长均可指定。
作业调度系统提供了两个运行时变量 %I 和 %J,%I 为子作业的索引值,%J 为作业ID,一般用于输入输出文件名中;以及运行时环境变量 LSB_JOBINDEX
bsub -J "myArray[1-10]" myJob #提交一个有10个子作业的作业
bsub -J "myArray[1-10]" -i "input.%I" -o "output.%I" myJob #每个子作业定义不同的输入输出文件
bkill 123[1] #杀掉 jobid 是123的第一个子作业
bkill 123 #杀掉 jobid 是123的整个作业
海量作业
提交大量的作业,将使得作业的管理将变得困难,虽然可以用上述作业组和作业序列进行批量管理,但是海量作业仍然对调度系统会造成很大的压力,特别是分钟级或秒级的短作业在调度时会浪费大量的时间,因此可以根据作业情况将多个作业合并为一个作业提交。对于不同的作业可以用两种方法来进行合并:
多作业串行执行
申请1个CPU核,顺序执行每个串行作业,前一个运行完成后再运行下一个,可以将非常多的串行作业合并成一个。对于每个串行作业运行时间都很短且运行时间不一定相同的适用这种方式提交。
4个串行作业串行执行合并为一个作业,提交到x5650队列,脚本方式为:
$ cat job.lsf
#BSUB -q x5650
./a.out >& 1.out
./a.out >& 2.out
./a.out >& 3.out
./a.out >& 4.out
$ bsub < job.lsf
Job <3366369> is submitted to queue <x5650>.
多作业并行执行
申请N个CPU核,同时执行N个串行作业,N不可大于单节点CPU核数,每个串行作业运行时间需要相同,最后需要 wait 命令等待所有作业运行完毕返回。对于每个串行作业运行时间较长且运行时间都完全相同的适用这种方式提交。
12个串行作业并行执行合并为一个作业,提交到x5650队列,脚本方式为:
$ cat job.lsf
#BSUB -q x5650
#BSUB -n 12
( ./a.out >& 1.out )&
( ./a.out >& 2.out )&
( ./a.out >& 3.out )&
( ./a.out >& 4.out )&
( ./a.out >& 5.out )&
( ./a.out >& 6.out )&
( ./a.out >& 7.out )&
( ./a.out >& 8.out )&
( ./a.out >& 9.out )&
( ./a.out >& 10.out )&
( ./a.out >& 11.out )&
( ./a.out >& 12.out )
wait
$ bsub < job.lsf
Job <3366370> is submitted to queue <x5650>.
查看信息
查看队列
查看所有队列:bqueues
$ bqueues
QUEUE_NAME PRIO STATUS MAX JL/U JL/P JL/H NJOBS PEND RUN SUSP
x7542! 50 Open:Active - - - - 24 0 24 0
e5645! 50 Open:Active - - - - 0 0 0 0
e52643tgb! 50 Open:Active - - - - 8 0 8 0
……
6226rib 30 Open:Active - - - - 0 0 0 0
5218 30 Open:Active - - - - 0 0 0 0
6230r 30 Open:Active - - - - 32 0 32 0
-
QUEUE_NAME:队列名称 -
PRIO:队列优先级,越大优先级越高 -
STATUS:队列状态。Open/Closed 表示是否可以提交,即用户是否可以提交作业到该队列;Active/Inact 表示否可以派发,即该队列的作业是否会被分发到计算节点运行。Open:Active 表示可提交可派发,Open:Inact 表示可提交但是不派发。 -
NJOBS:排队、运行和挂起的作业所占总CPU核数 -
PEND:排队中的作业所需总CPU核数 -
RUN:运行中的作业所占总CPU核数 -
SUSP:挂起的作业所占总CPU核数
查看队列详细信息:bqueues -l
$ bqueues -l e5v3ib
QUEUE: e5v3ib
-- CPU: 2*E5-2680v3, RAM: 256GB/128GB, NET: 56Gb FDR InfiniBand
……
SCHEDULING POLICIES: FAIRSHARE EXCLUSIVE
FAIRSHARE_QUEUES: e5v3ib e5v3ib! e7v4ib x5650ib 6140ib 62v100ib 722080tiib 72rtxib 7702ib ……
DISPATCH_ORDER: QUEUE
USER_SHARES: [root=, 999999] ……
SHARE_INFO_FOR: e5v3ib/
USER/GROUP SHARES PRIORITY STARTED RESERVED CPU_TIME RUN_TIME ADJUST GPU_RUN_TIME
root= 999999 202255.328 0 0 8456.5 1542 0.000 0
……
USERS: all ~test/
HOSTS: f01+10 f02+10 f03+10 f04+10 f05s+10 f05l/
RES_REQ: span[ptile=24]
Maximum slot reservation time: 43200 seconds
查看节点
lshosts #查看节点配置和资源
lshosts -gpu #查看节点GPU配置和拓扑结构
lsload #查看节点当前负载信息
lsload -gpu #查看节点GPU整体负载
lsload -gpuload #查看节点每个GPU负载
bhosts #查看所有节点状态
自动关机
集群会对动力环境进行监控,遇市电中断或温度过高,将会自动终止所有作业,按照安全顺序进行关机操作。
关机时会在 /fs00/reports/bjobs/ 目录下会自动保存一份作业列表备查。如文件 /fs00/reports/bjobs/bjobs.20130728070457 表明2013年07月28日07点04分57秒时刻所有作业的状态(bjobs -uall -w 的输出),同时也说明这个时间点开始自动关机。
如果温度未触及高点,但已明显增高,为了防止温度继续增高,集群会停止派发新作业,并且关闭空闲节点。
进程监督
用户只能登录到登录节点,且可从登录节点登录到有自己正在运行作业的计算节点。
所有节点的用户进程都会被检查,如果发现如下情况,将会杀掉该节点此用户所有进程,并记录在 /fs00/reports/process 中
- 计算节点有进程未通过作业调度系统提交运行的
- 计算节点用户进程占用的CPU资源明显高于在作业调度系统中请求的CPU资源
- 登录节点用户占用大于2个CPU核心的
容器化
容器技术
容器技术能够对应用及其整个运行时环境(包括全部所需文件)一起进行打包或隔离。从而可以在不同环境(如开发、测试和生产等环境)之间轻松迁移应用,同时还可保留应用的全部功能。有了容器不再需要管理员为你安装任何东西。容器是一个独立的系统,你可以在里面做任何想做的事情。
Apptainer
2021年11月,Singularity 开源项目加入 Linux 基金会,并更名为 Apptainer。Apptainer 是一套类似于 Docker 的容器解决方案,是用于HPC容器系统。Apptainer 兼容 Singularity Image File (SIF)、Singularity 的环境变量、Singularity 的命令、自动迁移 Singularity 的用户配置。
镜像
一般保存为压缩只读Singularity Image File (SIF)格式的镜像文件。
公共镜像
在 /fs00/software/singularity-images/ 已存放了许多常用的SIF镜像文件,可直接使用。
导入镜像
以从 Docker Hub 等镜像仓库或镜像文件直接创建SIF镜像文件
- 从 Docker Hub 导入镜像:
apptainer build ubuntu.sif docker://docker.nju.edu.cn/library/ubuntu - 从 NVIDIA NGC 导入镜像:
apptainer build ngc_cuda.sif docker://ngc.nju.edu.cn/nvidia/cuda - 从 docker save 保存的镜像文件导入镜像:
apptainer build abc.sif docker-archive://abc.tar
制作镜像
- 创建沙盒目录:
apptainer build --fix-perms --sandbox build docker://docker.nju.edu.cn/library/ubuntu - 进入沙盒容器:
apptainer shell build/ - 在容器中安装和编译软件:如
aptmake - 退出容器:
exit - 将沙盒打包成SIF镜像文件:
apptainer build abc.sif build
因登录节点无root权限,可能出现问题,因此建议在自己的系统上制作镜像。
CI创建镜像
用 git.nju.edu.cn 上的 CI/CD 自动调用 kaniko 构建 Docker 镜像,详见官方文档,然后再导入apptainer build ocr.sif docker://reg.nju.edu.cn/yaoge123/ocr
一个简单的示例见:CI/CD自动化构建Docker镜像
提交作业
提交容器作业的示例脚本
#BSUB -q 62v100ib
#BSUB -gpu num=4
apptainer exec --nv cuda.sif app
常用选项
-
--nv:提供NVIDIA GPUs & CUDA支持 -
--bind/-B src[:dest[:opts]]:绑定额外的路径
相关网站
常见问题
网络
登录节点进行网络接入认证
在登录节点登录校园网账号
集群中的登录节点进行网络接入认证(即登入南京大学校园网认证p.nju.edu.cn)后才可访问互联网,认证后登录节点所有用户均可访问互联网(相当于整个登录节点共享),请注意网络与账号隐私安全!
命令行登录和登出p.nju.edu.cn的方法有:
curl -X POST https://p.nju.edu.cn/api/portal/v1/login -H "Content-type: application/json" -d '{"username":"<username>","password":"<password>"}'
curl -X POST https://p.nju.edu.cn/api/portal/v1/logout -H "Content-type: application/json" -d '{}'
curl -s "http://p2.nju.edu.cn/portal_io/login?username=<username>&password=<password>"
curl -s http://p2.nju.edu.cn/portal_io/logout
**【强烈推荐】**如果有一些软件源需求,如conda、pip等包管理,或者需要外部代码库、容器,您可以通过中心提供的下列服务直接在集群上使用,无需登录校园网认证:
计算节点访问网络
所有计算节点均不能自由无限制的访问外网(含校园网和互联网),如需访问可以单独申请开放。当前已经放开的网络访问
SSH/SFTP登录时报 no matching host key type found
SSH/SFTP登录时报错no matching host key type found. Their offer: ssh-rsa,ssh-dss,命令行添加选项-o HostKeyAlgorithms=+ssh-rsa或在~/.ssh/config中增加HostKeyAlgorithms +ssh-rsa
安装
pip安装包到自己的目录下
Python的大多数包不需要root权限也能安装,只需在pip install后加-t指定安装目录即可,如:
cd scikit-opt-master
pip install -t $HOME .
这样就装到自己的家目录下。在~/.bashrc里或者作业脚本中加上环境变量
export PYTHONPATH=$HOME:$PYTHONPATH
作业
作业运行时实际占用CPU核数过多
- 在作业中限定使用的CPU核数与申请核数相同,否则超过申请核数使用资源的作业会被杀掉。
特别是MATLAB/Python,很多Python包会自动多核并行计算,需要使用环境变量(如 OMP_NUM_THREADS、NUMEXPR_NUM_THREADS、OPENBLAS_NUM_THREADS、MKL_NUM_THREADS)等方式设定线程数,与进程数一起匹配申请的核数。
export OMP_NUM_THREADS=$LSB_DJOB_NUMPROC
export NUMEXPR_NUM_THREADS=$LSB_DJOB_NUMPROC
export OPENBLAS_NUM_THREADS=$LSB_DJOB_NUMPROC
export MKL_NUM_THREADS=$LSB_DJOB_NUMPROC
- 可以尝试在提交作业时添加如下参数,做CPU亲和绑定
#BSUB -R affinity[core:cpubind=core:membind=localprefer:distribute=pack]
- 如果实在不行可以
#BSUB -x独占节点运行作业
排队作业数上限
动态限制用户排队作业数不能超过MAX(1000,MIN((30000-总作业数)/10,(20000-总排队作业数)/6))
即用户排队作业数,不超过三万减去总作业数的十分之一,也不超过二万减去总排队作业数的六分之一,但保底一千个。
作业状态UNKWN
一般是两种情况之一,如果作业状态长时间处于UNKWN状态,一般来说就是计算节点坏了可以直接杀掉作业。
- 因为计算节点负载过高,未能及时获取作业状态导致状态未知,这种情况一般只需要等待即可,待负载下降获取状态后就正常了。
- 因为计算节点出现故障且长时间未恢复,调度系统无法获取作业状态,此时如果登录不到相应的计算节点,可以直接杀掉作业。
路径
$HOME相对路径
让/bbfs相应目录保持在$HOME下的相对路径,这样可以轻松应对未来路径的变更
[yaoge123@login1 ~]$ ln -s /bbfs$HOME cache
[yaoge123@login1 ~]$ ln -s /bbfs/scratch/$USER scratch
[yaoge123@login1 ~]$ ls -l|grep bbfs
lrwxrwxrwx 1 yaoge123 yaoge 26 Mar 16 11:45 cache -> /bbfs/fsb/home/yaoge/yaoge123
lrwxrwxrwx 1 yaoge123 yaoge 20 Mar 16 11:45 scratch -> /bbfs/scratch/yaoge123
连接
VSCode 远程连接集群
VSCode 的 Remote-SSH 插件是远程开发的利器,但由于集群启用了两步认证(2FA),且登录节点(entry)不支持隧道转发,因此无法直接通过常规方式连接。解决方案是:在计算节点上启动一个用户态 SSH 服务,绑定一个高位端口,然后使用公钥直连该端口。
下面以在计算节点 m002 上操作为例(假设你已通过 srun --pty bash 或 ssh m002 进入了计算节点)。
1、在计算节点上配置用户态 SSH 服务
-
创建服务目录并生成主机密钥
mkdir -p ~/.sshd ssh-keygen -t rsa -f ~/.sshd/ssh_host_rsa_key -N "" -
编写配置文件
~/.sshd/sshd_configvim ~/.sshd/sshd_config写入以下内容(端口可自定义,此处以
2222为例):Port 2222 ListenAddress 0.0.0.0 HostKey ~/.sshd/ssh_host_rsa_key PasswordAuthentication no ChallengeResponseAuthentication no UsePAM yes PrintMotd no Subsystem sftp internal-sftp -
配置公钥登录(本地公钥写入服务器)
- 在本地(你的电脑)获取公钥内容。Windows PowerShell 中执行:
若使用 ED25519 则替换为type $env:USERPROFILE\.ssh\id_rsa.pubid_ed25519.pub。 - 若本地无公钥则新建。Windows PowerShell 中执行:
若使用 ED25519 则在 Windows PowerShell 中执行:ssh-keygen -t rsa -b 4096 -C "你的邮箱@example.com"
执行后会提示你保存文件的位置,直接按回车使用默认路径。接着提示设置密码短语(passphrase),按回车留空(不设密码)。然后就可以执行获取公钥内容的步骤。ssh-keygen -t rsa -b 4096 -C "你的邮箱@example.com" - 回到计算节点,将公钥写入
~/.ssh/authorized_keys:mkdir -p ~/.ssh chmod 700 ~/.ssh vim ~/.ssh/authorized_keys # 粘贴公钥内容,保存退出 chmod 600 ~/.ssh/authorized_keys chmod 755 ~ # 修复主目录权限,避免认证失败
- 在本地(你的电脑)获取公钥内容。Windows PowerShell 中执行:
-
启动用户态 sshd(务必使用非 debug 模式)
/usr/sbin/sshd -f ~/.sshd/sshd_config验证监听端口是否成功:
ss -tlnp | grep 2222应看到类似
0.0.0.0:2222的输出。
2、本地连接测试
在本地终端中测试 SSH 连接(替换 IP 为计算节点的校园网 IP,可通过 hostname -I 查看):
ssh -p 2222 用户名@210.28.xxx.xxx
若测试成功,再测试 SFTP(VSCode 依赖):
sftp -P 2222 用户名@210.28.xxx.xxx
正常进入 sftp 交互界面即表示一切就绪。
3、配置 VSCode
-
编辑本地 SSH 配置文件(路径
~/.ssh/config),加入主机条目:Host cluster-dev HostName 210.28.xxx.xxx User 你的集群用户名 Port 2222 IdentityFile ~/.ssh/id_rsa # 或 id_ed25519,与本地公钥对应 -
在 VSCode 中连接
- 安装插件 Remote - SSH(如未安装)。
- 按下
F1或点击左下角齿轮图标,选择 Remote-SSH: Connect to Host...,然后输入cluster-dev。 - 首次连接时,VSCode 会自动在计算节点上安装
.vscode-server,稍等片刻即可。 - 连接成功后,打开远程文件夹(如你的作业目录),即可像本地一样编辑、调试和运行代码。
注意:若 VSCode 连接后打开文件夹时断开,通常是因为 sshd 以 debug 模式运行(
-d参数)导致的,请确保启动命令不包含-d。若出现该问题,先pkill -u $USER sshd结束所有用户态 sshd,再重新用正确命令启动。
4、进程管理(可选)
- 查看当前用户启动的 sshd:
ps -ef | grep sshd | grep $USER - 关闭所有用户态 sshd:
pkill -u $USER sshd
安全提醒:该直连方式仅在校园网或 VPN 环境下使用,切勿暴露至公网;建议关闭密码登录(仅保留公钥)以防范暴力破解。
5、备选方案:网页版 VSCode(code-server)
若 SSH 方案不稳定,也可在计算节点上部署 code-server,通过浏览器访问:
# 需先安装或使用模块
code-server --bind-addr 0.0.0.0:8080
然后在本地浏览器访问 http://210.28.xxx.xxx:8080 即可获得浏览器版 VSCode 界面(注意密码保护,建议设置 --auth password)。