☰
Ubuntu 18.04 上 Vina 1.1.2+MGLTools 1.5.6+Slurm 批量对接
2026/11/3 19:33:52 网站建设 项目流程

简介:这份 PDF 面向生物信息、计算化学方向的学习者与科研人员,围绕 Linux 环境下 AutoDock Vina 分子对接与 Slurm 集群调度的配合展开,适合希望把单机对接流程迁移到批量化、集群化任务中的中级读者。压缩包内仅有 1 个 PDF 文件,大小约 1013KB,篇幅集中,便于按安装配置、脚本组织和作业调度等主题查阅。资料内容涉及 Ubuntu 18.04 下的依赖准备、Open Babel 与 MGLTools 的配合使用、受体与配体预处理、vina 配置文件及循环批量对接脚本思路,也延伸到 munge 认证、slurm.conf 参数编写以及 slurmctld、slurmd 服务启动等集群侧配置。对 vina.sh 中 PATH 环境变量设置、conf.txt 参数控制、pdbqt 到 sdf 的结果转换等细节也有交代,适合课程实践、课题组小型集群部署前的技术预研与流程验证。已有 5264 人学习,可作为搭建小规模分子对接流水线、理解作业调度参数、核对环境依赖与排查常见配置问题的参考。

1. 装 Vina 不难,难的是让它在一堆节点上老实排队

第一次在 Ubuntu 18.04 上做 AutoDock Vina 批量分子对接,我按教程敲完vina --config conf.txt,单个分子几十秒出结果,心里还挺得意。真正翻车的时刻在第二天:三百多个小分子要挨个跑,本机八核跑到 100% 还占着机器干不了别的,于是想着上 Slurm 排队。结果 Slurm 装完,sbatch一提交就是Invalid qos specification,sinfo里节点全挂着 drain 状态。

这套环境之所以常见,是因为它把「化学格式转换」「对接计算」「作业调度」三件事串成了一条链:Open Babel 负责格式搬运,Vina 1.1.2 负责算,MGLTools 1.5.6 负责把蛋白和配体洗成 pdbqt,Slurm 负责排队。链条上任何一环版本对不上,报出来的错都跟真实原因差着十万八千里。这篇笔记按我实际装过一遍的顺序写,从版本选择到三节点并行,再到装坏了怎么救,新手能照着走,熟手可以直接跳到 5、6 章看坑。

2. 定版本:Ubuntu 18.04 上 Vina 1.1.2 与 MGLTools 1.5.6 的依赖清单

动手之前先把版本钉死,这是整套环境里最省时间的一步。Ubuntu 18.04 自带 Python 2.7,这个特性决定了后面一大半的坑:MGLTools 1.5.6 是纯 Python 2 代码,而 18.04 之后的发行版默认只给 Python 3,装到 20.04 上install.py会直接语法错误。所以「Ubuntu 18.04 + Python 2.7 + MGLTools 1.5.6」是一组绑定关系,不要随意拆开。

2.1 四个组件的版本对照

先把这套环境里每个组件的位置和来源列清楚,后面所有命令都围绕这张表展开。

组件版本安装形态在流水线里的角色
Open Babel由 Ubuntu 源决定apt install openbabelsdf 转 mol2、pdbqt 回转 sdf
AutoDock Vina1.1.2预编译二进制 tar.gz对接打分,出构象和亲和能
MGLTools1.5.6tar.gz +python install.pyprepare_receptor4.py / prepare_ligand4.py
Slurm由 Ubuntu 源决定(slurm-wlm)apt install slurmd slurmctld多节点作业排队

需要说明的是 Open Babel 和 Slurm 的版本号,我从没在笔记里写死过——apt-cache policy openbabel slurm-wlm输出什么就是什么,Ubuntu 18.04 源里能装到的版本足够跑通整条链路。真正必须锁死的是 Vina 1.1.2 和 MGLTools 1.5.6 这两个手工安装的包,因为它们不走包管理器,装错版本不会有人提醒你。

提示:Vina 1.1.2 的 Linux 预编译包是 x86 架构的静态可执行文件,不需要编译,解压即用。它不依赖 Python,也不依赖 MGLTools,单独跑就能出结果,这一点在排查时很有用——先确认 vina 自己能跑,再去怀疑格式转换。

2.2 依赖包为什么一个都不能省

原始笔记里那串apt-get install看着长,但每一行都有明确用途,少装一个,报错信息通常不会告诉你缺了它。我拆开说。

sudo apt-get update sudo apt-get install -y \ build-essential \ libxt-dev libglu1-mesa-dev libxmu-dev libxi-dev \ libpng-dev libjpeg-dev libtiff-dev \ csh \ python-tk python-numpy python-dev python-pmw

这一条命令的逻辑是:把「编译工具链」「X11/OpenGL 图形库」「图片编解码库」「csh 解释器」「Python 2 的 Tk 与扩展」五组依赖一次装齐。

  • build-essential:MGLTools 的install.py只做拷贝,但某些包里的扩展模块在缺编译器时会报错。装上是保险。
  • libxt-dev libglu1-mesa-dev libxmu-dev libxi-dev:MGLTools 里的pmv和 AutoDockTools 的图形界面依赖 X11 与 OpenGL 头文件,缺了会在启动时报ImportError: libGLU.so.1一类错误。
  • libpng-dev libjpeg-dev libtiff-dev:分子可视化组件读图片格式时要链接这几个库。
  • csh:这是最容易漏的一个。MGLTools 的bin/目录下有一批脚本的 shebang 是#!/bin/csh,系统没有 csh 时,执行这些脚本会返回No such file or directory——注意,报的错不是「找不到 csh」,而是「找不到这个文件」,非常误导人。
  • python-tk:pmv的 Tk 界面。
  • python-numpy、python-dev:MGLTools 内部大量用 numpy 做坐标运算,python-dev提供 Python 2 头文件。
  • python-pmw:Pmw 是 Tk 的扩展组件,AutoDockTools 的界面框架基于它。

注意这里所有 Python 包都是 Python 2 版本(python-前缀,不是python3-)。如果你在执行时看到 apt 试图安装 Python 3 的同名包,说明命令写错了,停下来检查。

2.3 目录布局与账号约定

我一般把整套环境固定放在/home/autodock下面,所有脚本用绝对路径引用,避免换用户之后 PATH 失效。

mkdir -p /home/autodock cd /home/autodock

装完之后的目录结构大致是这样:

/home/autodock/ ├── autodock_vina_1_1_2_linux_x86/ # Vina 解压目录 │ └── bin/vina ├── mgltools_x86_64Linux2_1.5.6/ # MGLTools 安装目录 │ ├── bin/ │ └── MGLToolsPckgs/AutoDockTools/Utilities24/ ├── pro.pdb # 受体原始结构 ├── testset.sdf # 配体集合(多分子 sdf) ├── conf.txt # Vina 对接参数 ├── vina.sh # 串行批处理脚本 └── mols/ # 单个配体的工作目录

后面扩到三节点时,这个目录会整体搬到 NFS 共享盘上挂到/vina,脚本里的路径也要跟着改,这一点在第 4 章会具体处理。

3. 装对接三件套:Open Babel、Vina 1.1.2 与 MGLTools 1.5.6

这一章是从零到「单个分子能跑出结果」的完整过程。我的建议是严格按顺序来:先 Open Babel,再 Vina,最后 MGLTools。因为格式转换工具先就位,后面验证 prepare 脚本输出的时候才有东西可以对照。

3.1 一条命令装齐系统依赖

依赖安装和上一章列的一致,这里给可直接复制的版本,多加了第二次apt-get update,是因为有些镜像源在长时间挂机后会失效。

sudo apt-get update sudo apt-get install -y build-essential libxt-dev libglu1-mesa-dev \ libxmu-dev libxi-dev libpng-dev libjpeg-dev libtiff-dev \ csh python-tk python-numpy python-dev python-pmw sudo apt-get update

第二次 update 不是玄学,是踩过坑的:Ubuntu 18.04 的python-pmw在某些镜像上会落到universe源,如果第一次 update 时缓存过期,apt 会报Package 'python-pmw' has no installation candidate,重跑一次 update 基本就解决了。

3.2 Open Babel 与格式转换的那点事

apt install -y openbabel obabel -V

-V打出版本号就说明装好了。Open Babel 在这条流水线里干两件事:把多分子 sdf 拆成 mol2 喂给 MGLTools,以及把 Vina 输出的 pdbqt 转回 sdf 做后续分析。

# 把多分子 sdf 整体转成 mol2(此时还是一个文件,包含多个分子块) obabel -isd testset.sdf -omol2 -O testset.mol2 # -m 表示按分子拆分:一个 mol2 拆成 vs1.mol2、vs2.mol2…… obabel ../testset.mol2 -O vs.mol2 -m

参数逐个说:

  • -i指定输入格式,-o指定输出格式,-O(大写)指定输出文件名。
  • -m是拆分开关,只有配体集合转换时才加。它会按分子在文件中的顺序编号输出,生成vs1.mol2、vs2.mol2这样的文件名,而不是原文脚本里循环读取的*.mol2通配符能直接匹配到的形式——这点要留意,文件名对不上后面循环就空转。
  • 转换过程不改变坐标,只改格式。如果 sdf 带电荷信息不全,mol2 里的电荷可能缺失,MGLTools 在prepare_ligand4.py阶段会补默认电荷,所以这一步不用纠结。

3.3 解压 Vina 1.1.2 并验证二进制能跑

cd /home/autodock tar -zxvf autodock_vina_1_1_2_linux_x86.tgz ./autodock_vina_1_1_2_linux_x86/bin/vina --version

tar -zxvf里-z解 gzip、-x解包、-v显示文件列表、-f指定文件。原文脚本写成-xvfz,GNU tar 能容忍这个顺序,但换到 busybox 的 tar 上就会报错,养成写规范顺序的习惯省事。

vina --version输出1.1.2就对了。如果报Permission denied,补一句chmod +x bin/vina;如果报cannot execute binary file,说明架构不对,Vina 1.1.2 的这包是 x86_64 的,别在 ARM 机器上试。

提示:Vina 是静态链接的,先单独确认它能跑,再往后装 MGLTools。顺序倒过来排查时会多绕一大圈——我就干过把所有问题都怀疑到 MGLTools 身上,结果发现是 vina 二进制没执行权限。

3.4 MGLTools 1.5.6 的 install.py 怎么过

cd /home/autodock tar -zxvf mgltools_x86_64Linux2_1.5.6.tar_.gz cd MGLTools-1.5.6 python install.py

install.py会交互式问你安装路径,直接回车用当前目录即可。执行前先确认python指向 2.7:

python -V # 期望输出:Python 2.7.17 之类的 2.x 版本

如果输出是 Python 3.x,install.py会在第一段字符串处理处就抛SyntaxError。解决办法不是改脚本,而是显式用 python2 跑:

python2 install.py

安装完成后,MGLTools-1.5.6/目录就是最终目录,我把它的父目录mgltools_x86_64Linux2_1.5.6作为安装根,后面 PATH 里引用的都是这个路径。如果你解压出来的目录名不同,后面三行 export 里的路径也要跟着改,别照抄。

MGLTools 装完之后,bin/下有prepare_receptor4.py、prepare_ligand4.py的软链,真正的脚本在MGLToolsPckgs/AutoDockTools/Utilities24/下。这两个脚本是整条流水线的入口,它们的 shebang 同样是#!/usr/bin/env python,所以 Python 2 必须是系统默认的那个python。

3.5 把 PATH 写进 vina.sh:环境变量三行拆解

原始脚本最前面那三行 export 是关键,它决定了后面所有命令能不能找到。

# Vina 二进制目录 export PATH=/home/autodock/autodock_vina_1_1_2_linux_x86/bin/:$PATH # MGLTools 的 bin 目录(pmv、adt 等) export PATH=/home/autodock/mgltools_x86_64Linux2_1.5.6/bin/:$PATH # prepare_receptor4.py / prepare_ligand4.py 所在目录 export PATH=/home/autodock/mgltools_x86_64Linux2_1.5.6/MGLToolsPckgs/AutoDockTools/Utilities24/:$PATH

三行的顺序无所谓,但第三行的路径必须指向Utilities24,而不是bin。很多人把bin加到 PATH 之后就以为prepare_ligand4.py能直接调,实际上bin里的同名文件是软链,指向Utilities24下的真实脚本,软链断了就会报command not found。

如果执行prepare_ligand4.py时报ImportError: No module named MolKit或No module named AutoDockTools,补一条 PYTHONPATH:

export PYTHONPATH=/home/autodock/mgltools_x86_64Linux2_1.5.6/MGLToolsPckgs:$PYTHONPATH

这条我一般会直接写进vina.sh开头,反正不影响正确性,只在真出问题时才起作用。

3.6 串行版 vina.sh:先跑通一个分子

在并行化之前,先把串行脚本跑通,这是后面所有改造的基线。

#!/bin/bash # 串行批量对接脚本:一次处理一个配体 export PATH=/home/autodock/autodock_vina_1_1_2_linux_x86/bin/:$PATH export PATH=/home/autodock/mgltools_x86_64Linux2_1.5.6/bin/:$PATH export PATH=/home/autodock/mgltools_x86_64Linux2_1.5.6/MGLToolsPckgs/AutoDockTools/Utilities24/:$PATH export PYTHONPATH=/home/autodock/mgltools_x86_64Linux2_1.5.6/MGLToolsPckgs:$PYTHONPATH cd /home/autodock # 每次重跑先清空工作目录,避免上一轮的残留配体混进来 if [ -d "mols" ]; then rm -rf mols; fi mkdir mols # 受体只需要准备一次 prepare_receptor4.py -r pro.pdb -e -o receptor.pdbqt # 配体集合整体转 mol2,再拆分 obabel -isd testset.sdf -omol2 -O testset.mol2 cd mols obabel ../testset.mol2 -O vs.mol2 -m rm -f output.sdf for mol2 in *.mol2; do prepare_ligand4.py -l $mol2 -o ligand.pdbqt vina --config ../conf.txt --cpu 1 --out out.pdbqt --log log.txt obabel -ipdbqt out.pdbqt -osd -O temp.sdf cat temp.sdf >> output.sdf rm -f log.txt ligand.pdbqt out.pdbqt temp.sdf done cd ..

几个参数必须说清楚:

  • prepare_receptor4.py -r pro.pdb -e -o receptor.pdbqt:-r是输入受体,-o是输出。-e是个不带值的开关,作用是让脚本在准备受体时剔除某些非标准残基;不同小版本对它的处理略有差异,如果你发现输出少原子,把-e去掉再跑一次对比就知道是不是它干的。
  • vina --cpu 1:这一条在串行脚本里看着多余,但它是并行化的前提。Vina 默认会吃满所有核,一旦进了 Slurm,每个任务只分到一个核,它还在那里抢,结果就是节点负载飙到几十、作业互相拖死。
  • obabel -ipdbqt out.pdbqt -osd -O temp.sdf:把某一个配体的对接结果转成 sdf,然后cat追加到output.sdf。这种累加写法在串行下没问题,并行下会出大问题,第 5 章细说。

conf.txt是 Vina 的对接参数文件,原始笔记里没有贴内容,我给一份最小可用的:

receptor = ../receptor.pdbqt ligand = ligand.pdbqt center_x = 12.5 center_y = 8.3 center_z = -4.1 size_x = 20 size_y = 20 size_z = 20 exhaustiveness = 8 num_modes = 9 energy_range = 3

center_*和size_*是搜索盒子的中心和边长,单位是埃。常见做法是在 MGLTools 的图形界面里打开受体,用 Grid → Grid Box 拖出范围,把面板上的 Center 数值抄过来。盒子太小会导致配体跑不出构象,盒子太大则计算量翻倍且打分变差。exhaustiveness是搜索强度,默认 8,调高更准更慢。--cpu与exhaustiveness是乘数关系,两个一起调高才会真的变慢。

跑通之后,mols/output.sdf里的分子数应该等于testset.sdf里的分子数。数量对不上,先别急着上 Slurm,回到这一步查。

4. 装 Slurm 调度器:munge 认证与 slurm.conf 的最小可用集

单机跑通之后,下一步是让它排队。Slurm 的安装分三段:认证服务 munge、核心守护进程、配置文件。这三段任何一段没对齐,表现出来都是「节点不响应」或者「服务起不来」,而这两个错误的信息量极低,所以我会一段一段单独验证。

4.1 munge 认证:先把 key、权限对齐

munge 是 Slurm 节点之间互相认证的组件,它靠一个共享密钥文件工作。单机装的时候一切正常,扩到多节点时最容易死在这里。

apt-get install -y make hwloc libhwloc-dev libmunge-dev libmunge2 munge mariadb-server libmysqlclient-dev systemctl enable munge systemctl start munge systemctl status munge

systemctl status显示active (running)才算过。没起来的话先看密钥:

ls -l /etc/munge/munge.key # 期望:-r-------- 1 munge munge

权限必须是0400、属主必须是munge。如果权限不对,munge -n会报Failed to access "/etc/munge/munge.key"。修法:

chown munge:munge /etc/munge/munge.key chmod 400 /etc/munge/munge.key systemctl restart munge

libmysqlclient-dev和mariadb-server是为 Slurm 的记账功能(slurmdbd)准备的。如果不打算做作业记账,这两个其实可以不装,但它们是 Slurm 包的依赖链之一,装上也占不了多少空间,我一般顺手带上。

4.2 装 slurm-wlm 与 spool 目录准备

apt update apt install -y slurm-wlm slurmd slurmctld

三个包各管一段:slurm-wlm是元包,带工具和文档;slurmd是每台机器都要跑的计算节点守护进程;slurmctld只在控制节点跑。

装完之后有个路径问题必须处理清楚:Ubuntu 的 deb 包默认读/etc/slurm-llnl/slurm.conf,而很多笔记里写的是/etc/slurm/slurm.conf。两个目录都存在,但服务只认前者。

ls -ld /etc/slurm-llnl /etc/slurm

确认服务实际读哪个:

systemctl cat slurmctld | grep -i conf

拿到真实路径之后,所有配置都写在那一个文件里,别两边都写——两边都写的结果是改了一份、生效的是另一份,排查能耗掉一晚上。

然后是 spool 目录。配置文件里写什么路径,就得有什么目录,而且权限要对:

mkdir -p /var/spool/slurmd mkdir -p /var/spool/slurmctld chown -R slurm:slurm /var/spool/slurmd /var/spool/slurmctld

原始笔记里用的是/var/lib/slurm-llnl/和/var/spool/slurm/,那套路径也能用,前提是slurm.conf里的SlurmdSpoolDir、StateSaveLocation与之一一对应,并且目录提前建好、属主改对。我选/var/spool/这套是因为它和 Ubuntu 包自带的 logrotate、tmpfiles 配置对得上,少操心。

4.3 slurm.conf 关键参数逐项过一遍

完整的slurm.conf有上百行,绝大多数是注释。真正决定集群能不能起来的就下面这些,我先给单节点可用版本,再逐项解释。

# 集群标识,随便起,所有节点必须一致 ClusterName=cluster # 控制节点的主机名与地址 ControlMachine=node01 ControlAddr=10.0.0.11 # Slurm 守护进程运行的账号 SlurmUser=slurm # 端口,默认即可,防火墙要放行 SlurmctldPort=6817 SlurmdPort=6818 # 状态与日志目录 StateSaveLocation=/var/spool/slurmctld SlurmdSpoolDir=/var/spool/slurmd SlurmctldLogFile=/var/log/slurm-llnl/slurmctld.log SlurmdLogFile=/var/log/slurm-llnl/slurmd.log SlurmctldDebug=3 SlurmdDebug=3 # 认证与进程追踪 CryptoType=crypto/munge ProctrackType=proctrack/pgid SwitchType=switch/none TaskPlugin=task/none MpiDefault=none # 调度器 SchedulerType=sched/backfill SelectType=select/linear ReturnToService=1 # 注意:Default=YES 全集群只能有一个 NodeName=node01 NodeAddr=10.0.0.11 CPUs=1 RealMemory=1800 PartitionName=debug Nodes=node01 Default=YES MaxTime=INFINITE State=UP

逐项说取舍:

  • ControlMachine和ControlAddr:前者是主机名,后者是 IP。两者都写,Slurm 优先用地址。主机名必须能被解析,ping node01通不通是第一个自检点。
  • SlurmUser=slurm:原始笔记写的是root,能跑,但 Ubuntu 包已经建好了slurm用户,用slurm更省事——spool 目录的属主天然对得上。如果你坚持用 root,记得把所有 spool 目录的属主改成 root,否则slurmctld起不来且日志里只说「权限不足」。
  • StateSaveLocation:作业状态落盘的位置,节点重启后能不能恢复队列就看它。目录不存在会直接导致slurmctld启动失败。
  • ProctrackType=proctrack/pgid:按进程组追踪任务。单机小集群够用,多节点大规模场景一般换proctrack/cgroup,但那需要额外配 cgroup,这里不折腾。
  • SelectType=select/linear:按节点整体分配,不细分到核。三节点的小集群用这个最简单,select/cons_res更适合需要精细分配核数的场景。
  • SchedulerType=sched/backfill:回填调度,小作业可以插空跑,比默认的sched/builtin利用率高。
  • FastSchedule=1:让 Slurm 相信配置文件里写的 CPU 和内存数,不去实际探测。这个参数在较新版本已废弃,Ubuntu 18.04 源里的版本还认,写上能避免节点资源被探测成 0。
  • NodeName行里的CPUs=1 RealMemory=1800:必须和实际机器匹配。写成 1 核就真的按 1 核调度,写大了会导致作业超配。

注意:PartitionName行里的Default=YES,整个集群只能出现一次。原始笔记的三节点配置里p1、p2、p3三个分区都写了Default=YES,这是slurmctld起不来的经典原因,日志里报的是分区配置非法。只留一个。

4.4 启动服务并提交第一个作业

systemctl enable slurmd slurmctld systemctl start slurmd systemctl start slurmctld systemctl status slurmd slurmctld

两个都是active (running)之后,别急着提交作业,先看集群状态:

sinfo scontrol show nodes

sinfo里节点状态是idle才算正常。如果是down或drain,先scontrol update NodeName=node01 State=RESUME,还不行就看/var/log/slurm-llnl/slurmctld.log。

第一个测试作业,就三行:

#!/bin/bash #SBATCH -o job.%j.out #SBATCH -p debug #SBATCH -J myFirstJob #SBATCH --nodes=1 #SBATCH --ntasks-per-node=1 hostname
sbatch job1.sh squeue cat job.*.out

-o job.%j.out里的%j会被替换成作业号,所以每个作业的输出文件不重名,这一点在批量提交时非常重要。hostname打出来的应该是node01,说明作业真的被调度到计算节点上跑了,而不是在提交节点本地执行。

如果sbatch报Invalid qos specification,说明脚本里写了--qos=low但集群没配 QOS。两个选择:删掉--qos那行,或者用sacctmgr add qos low建一个。小集群我一般直接删,QOS 是给需要配额管理的场景用的。

5. 扩到三节点:NFS 共享 /vina 与 sbatch 并行改造

单节点跑通之后,扩到三节点的工作量比想象中小,但有几个地方必须做到「三台机器完全一致」,否则 Slurm 会以各种奇怪的方式拒绝工作。

5.1 主机名、hosts 与 munge 密钥的三节点一致性

先在三台机器上分别设主机名,node01是控制节点,node02、node03是计算节点。

hostnamectl set-hostname node01 # 另外两台分别设 node02、node03

然后三台的/etc/hosts都要有这三行:

10.0.0.11 node01 10.0.0.12 node02 10.0.0.13 node03

ping node02通不通,是排查「节点不响应」的第一步。Slurm 靠主机名匹配NodeName,NodeName必须和hostname输出完全一致,大小写也要一致。

munge 密钥必须三台一致。做法是从 node01 复制:

# 在 node01 上 scp /etc/munge/munge.key root@node02:/etc/munge/munge.key scp /etc/munge/munge.key root@node03:/etc/munge/munge.key # 在 node02、node03 上分别执行 chown munge:munge /etc/munge/munge.key chmod 400 /etc/munge/munge.key systemctl restart munge

验证方式:在 node01 上munge -n | unmunge能解出内容,在 node02 上对 node01 发起的凭据也能验证通过,说明密钥一致。密钥不一致的表现是节点全部drain,日志里只说认证失败,不说原因。

时钟也要对齐,timedatectl set-ntp true三台都开。时间差超过SlurmdTimeout(默认 300 秒)会导致节点被判死。

slurm.conf三台必须完全一样,改完一台就scp到另外两台,然后三台都systemctl restart slurmd,控制节点再systemctl restart slurmctld。

5.2 NFS 把 /vina 挂到三台机器

三节点的作业要读同一份配体文件、写同一份结果,共享存储是前提。NFS 是最省事的方案。

在 node01(同时也是 NFS 服务端)上:

apt install -y nfs-kernel-server mkdir -p /vina chmod 777 /vina echo "/vina 10.0.0.0/24(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports exportfs -ra systemctl enable nfs-kernel-server systemctl restart nfs-kernel-server

在 node02、node03 上:

apt install -y nfs-common mkdir -p /vina mount -t nfs 10.0.0.11:/vina /vina

挂载参数说明:rw读写,sync同步写入保证一致性,no_subtree_check关掉子树检查提升稳定性,no_root_squash让 root 用户保留权限(小集群内部用,公网环境不要这么配)。写进/etc/fstab才能开机自动挂:

echo "10.0.0.11:/vina /vina nfs defaults 0 0" >> /etc/fstab

装好的三件套要整体搬到/vina下,因为计算节点上跑的是同一份脚本:

cp -r /home/autodock/* /vina/

然后在三台机器上验证同一份文件可见:

# 在 node01 上 echo test > /vina/.probe # 在 node02、node03 上 cat /vina/.probe

三台都能读到,共享盘才算通了。

5.3 把 vina.sh 改成 sbatch 模板

并行化的核心思路是:一个配体一个作业,Slurm 负责把它们分到三个节点上同时跑。脚本头部加 SBATCH 指令即可。

#!/bin/bash #SBATCH -J vina_pair #SBATCH -p p1 #SBATCH -o /vina/logs/job.%j.out #SBATCH --nodes=1 #SBATCH --ntasks-per-node=1 #SBATCH --cpus-per-task=1 export PATH=/vina/autodock_vina_1_1_2_linux_x86/bin/:$PATH export PATH=/vina/mgltools_x86_64Linux2_1.5.6/bin/:$PATH export PATH=/vina/mgltools_x86_64Linux2_1.5.6/MGLToolsPckgs/AutoDockTools/Utilities24/:$PATH export PYTHONPATH=/vina/mgltools_x86_64Linux2_1.5.6/MGLToolsPckgs:$PYTHONPATH cd /vina/mols mol2=$1 prefix=${mol2%.mol2} prepare_ligand4.py -l $mol2 -o ${prefix}.pdbqt vina --config /vina/conf.txt --cpu 1 --out ${prefix}_out.pdbqt --log ${prefix}.log obabel -ipdbqt ${prefix}_out.pdbqt -osd -O ${prefix}.sdf

关键改动有四处:

  • cd /vina/mols用绝对路径。sbatch 提交时的工作目录是提交者当前目录,但到了计算节点上不一定还在那儿,写绝对路径最稳。
  • --cpus-per-task=1配合vina --cpu 1,一个作业占一个核,不抢别人的。
  • 输出文件带${prefix}前缀。原来所有作业都往output.sdf里追加,三个节点同时写同一个文件,结果是内容交错、分子丢失,而且没有任何报错。这是我见过最难查的一个问题。
  • 日志写到/vina/logs/,先mkdir -p /vina/logs建好,%j自动带作业号。

配体列表怎么喂进去?最简单的做法是用一个提交循环:

cd /vina/mols for f in *.mol2; do sbatch /vina/vina_job.sh $f done squeue

每个 mol2 提交一个作业,Slurm 按分区和节点空闲情况自动分配。三个节点、每个节点 1 核的情况下,squeue里会看到一两个R(运行中)、其余PD(排队中),这是正常的。

5.4 并行之后的结果归集

所有作业跑完之后,把散落的*_sdf合并成一个文件:

cd /vina/mols cat *_out.sdf > /vina/output_all.sdf grep -c '\$\$\$\$' /vina/output_all.sdf

sdf 里每个分子以$$$$结尾,所以grep -c出来的数字就是分子总数。这个数字应该等于输入配体的数量,少一个都说明有作业失败了,去/vina/logs/里按作业号翻。

这种「先分散写、最后合并」的写法比串行累加多一步,但它是可重复的——重跑某个失败作业不会污染整体结果,把对应的*_out.sdf删掉重跑就行。串行累加的写法一旦中途失败,output.sdf就是个半成品,你还得手动判断哪些分子已经跑过。

6. 避坑与排查:五条血泪记录

这一章的五条都是我真金白银撞过的,按「现象、原因、解决」记,照着对号入座。

6.1 prepare_ligand4.py 报 bad interpreter

现象:执行prepare_ligand4.py时终端提示/usr/bin/env: 'python': No such file or directory,或者一执行就抛SyntaxError: invalid syntax,报错指向脚本里某个print语句。

原因:系统里python这个名字被指向了 Python 3,而 MGLTools 1.5.6 是 Python 2 代码。Ubuntu 18.04 默认还有/usr/bin/python2.7,但python这个软链可能被后装的其他工具改掉了。

解决:先确认python -V的输出,如果是 3.x,用update-alternatives --config python切回 2.7,或者把脚本里的调用统一改成python2。我习惯的做法是装完 MGLTools 立刻执行一次python -V,输出不是 2.x 就不往下走。

6.2 slurmctld 起不来,日志说分区配置非法

现象:systemctl start slurmctld返回失败,journalctl -u slurmctld里滚出几行提到 partition 或 default 的信息,服务反复重启。

原因:slurm.conf里多个PartitionName行同时写了Default=YES。Slurm 只允许一个默认分区,但配置语法不检查这一点,只在启动时才报。

解决:全文件搜一遍Default=YES,只保留一个分区上有。改完systemctl restart slurmctld。另外注意三个分区如果都指向同一个节点,本身也没意义,不如就留一个分区把三个节点都列进去。

6.3 sbatch 提交报 Invalid qos specification

现象:sbatch job.sh立刻返回sbatch: error: Invalid qos specification,作业根本没进队列。

原因:脚本头里写了#SBATCH --qos=low,但集群从来没配置过 QOS。原始笔记里的作业脚本就带着这一行,直接抄过来必踩。

解决:两条路。要么把--qos那行删掉,小集群根本用不上;要么用sacctmgr add qos low建一个再用sacctmgr show qos确认。我一般选前者,除非真的需要按 QOS 限制作业资源。

6.4 节点全是 drain,scontrol ping 不通

现象:sinfo里节点状态是drain,scontrol show node node02显示Not responding,scontrol ping显示节点不可达。

原因:三个可能,按概率排序——munge.key三台不一致、主机名解析不了、系统时间偏差过大。这三个原因在日志里的表现几乎一样,都是「通信失败」。

解决:按顺序排。先ping node02确认解析;再比对三台/etc/munge/munge.key的 md5 是否一致;最后date看三台时间差。全部对上之后scontrol update NodeName=node02 State=RESUME手动拉回。三台机器的时间同步我一般用timedatectl set-ntp true一次性配好,省得后面反复查。

6.5 并行跑完,结果文件里的分子少了

现象:三节点并行跑完,output.sdf里分子数是输入的一半甚至三分之一,grep -c '\$\$\$\$'出来的数字对不上,但squeue显示所有作业都COMPLETED。

原因:所有作业共用同一个 `output

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询