简介:Torque 6.1.1.1 源码包面向高性能计算集群运维人员与作业调度系统开发者,用于搭建由管理节点与计算节点组成的 PBS 集群环境。管理节点运行 pbs_server,计算节点运行 pbs_mom,客户端命令可独立部署于任意主机,适合需要理解作业提交、调度与资源管理机制的中高级读者研读。压缩包共约 2000 个文件、13.45MB,以 C 源码为主体,辅以大量 Perl 脚本、头文件、模板与构建配置,涵盖 mom 通信、节点管理、作业函数与请求处理等核心模块,并附有安装脚本、调度配置样例及说明文档,便于按模块梳理架构。已有 841 人学习下载,可据此掌握 Torque 的进程协作方式、编译安装流程与常见配置要点,为集群部署和二次开发提供参考。
1. 拿到 torque-6.1.1.1.tar.gz 先别急着解压:它到底能解决什么
集群里跑批处理任务,最怕的不是算得慢,而是任务排不进去、节点空转、作业莫名被踢。torque-6.1.1.1.tar.gz 就是一套老牌的资源管理与作业调度系统源码包,解压后是一棵完整的 C 源码树,带 configure 脚本、调度器、pbs_server、pbs_mom、pbs_sched 这些核心组件。它解决的是“多台机器、多个队列、多用户提交作业”这件事:谁先跑、跑在哪、跑多久、超了怎么办。适合两类人:一是在内网小集群上要自己搭一套调度环境、又不想被商业调度绑死的运维;二是需要读调度器源码、改排队策略或做课程设计的研究者。这个包不是二进制发行版,装它得有编译环境和一点耐心,下面按“先看懂结构、再编译、再配队列、最后排错”的顺序拆。
2. 解压后先看源码树:configure 与三大守护进程怎么分工
torque 的源码包解压出来不是一堆散文件,而是有明确分层的。动手编译之前花十分钟把目录和进程模型搞清楚,后面配队列、看日志会省很多事。这一章先把“它由什么组成、为什么这么分”讲透,再落到具体的解压和依赖检查命令。
2.1 目录结构与组件职责
解压后典型会看到这些顶层目录:src/放全部 C 源码,configure是 autoconf 生成的构建脚本,buildutils/是打包辅助,contrib/里有些社区补丁和工具。真正要关注的是src/下的几个子目录:
| 目录/文件 | 作用 | 对应进程 |
|---|---|---|
| src/server | 作业与队列的中央管理 | pbs_server |
| src/mom | 节点侧执行与资源监控 | pbs_mom |
| src/scheduler.cc | 调度策略实现 | pbs_sched |
| src/cmds | 用户命令 qsub/qstat/qdel 等 | 客户端工具 |
| src/include | 公共头文件与协议定义 | 编译依赖 |
这个分工是 torque 的核心设计:pbs_server 是唯一掌握全局作业状态的地方,所有 qsub 提交的作业先落到它这里排队;pbs_mom 跑在每个计算节点上,负责真正 fork 出用户进程、盯 CPU 和内存、把作业输出回传;pbs_sched 是独立进程,周期性向 server 要“可运行作业列表”和“可用节点列表”,算出一个匹配结果再告诉 server 把哪个作业派到哪个节点。把调度器拆成独立进程的好处是:换调度策略不用动 server,甚至可以自己写一个调度器替换掉默认的。常见做法是先跑默认的 pbs_sched 把环境跑通,再考虑替换。
理解这个模型对排错极其关键。作业卡在 Q 状态不动,可能是 server 没收到,也可能是 sched 没算出来,还可能是 mom 没上报资源,三者日志位置完全不同。所以别一上来就改配置,先确认是哪个环节断的。
2.2 解压与编译依赖检查
拿到 tar.gz 第一步是校验和解压,别直接tar xzf完事,先看一眼包完整性。下面这套命令我一般会走一遍:
# 校验压缩包完整性,确认没有传输损坏 gzip -t torque-6.1.1.1.tar.gz && echo "archive ok" # 解压到独立目录,避免污染当前工作区 mkdir -p ~/build && tar xzf torque-6.1.1.1.tar.gz -C ~/build cd ~/build/torque-6.1.1.1 # 检查编译工具链是否齐全 which gcc make autoconf gcc --version | head -1gzip -t只做完整性测试不解压,几秒钟的事,能避免后面 configure 报一堆莫名其妙的错。解压到~/build是习惯,源码树和安装目录分开,重编时直接删掉重建,不会把已安装的文件搅乱。
依赖方面,torque 6.x 这套源码需要 C 编译器、make、以及可选的 openssl 头文件(如果启用加密通信)。缺 openssl 开发包时 configure 会在检测阶段给出 warning,不致命但会影响某些安全特性。检查命令:
# 确认 openssl 开发头文件是否存在(可选依赖) ls /usr/include/openssl/ssl.h 2>/dev/null || echo "openssl-devel missing"如果这行输出 missing,要么装上开发包,要么在 configure 时显式关掉相关选项。别忽略这个 warning 直接往下走,后面编译到通信模块时可能突然报找不到头文件,那时候再回头查就费劲了。
2.3 configure 的关键参数怎么选
configure 的参数决定了安装路径、守护进程运行用户、以及是否启用某些特性。最常改的是--prefix和--with-server-home,前者是二进制和库的安装位置,后者是运行时配置和队列数据的存放位置。这两个别混在一起,升级时只换 prefix、保留 server-home,队列配置就不会丢。
./configure \ --prefix=/opt/torque \ --with-server-home=/var/spool/torque \ --disable-gcc-warnings \ --enable-docs逐项说明:--prefix=/opt/torque把 qsub、qstat 这些命令装到/opt/torque/bin,方便统一管理;--with-server-home=/var/spool/torque指定运行时目录,server 的队列定义、mom 的节点配置都落在这里;--disable-gcc-warnings是因为老源码在新版 gcc 下会刷大量 warning,关掉让输出干净些,不影响功能;--enable-docs生成 man 手册,排查命令参数时有用。如果内网对通信加密没要求,可以再加--disable-server-encryption简化依赖,但要注意这会影响节点间认证方式,改之前想清楚。
configure 跑完会打印一份摘要,重点看 server home、install prefix、以及有没有 “checking for openssl... no” 这类关键项。摘要不对就别急着 make,先回去调参数。
3. 编译安装与队列初始化:从 make 到第一个 qsub 跑通
源码编译只是前半程,真正让集群“活”起来的是安装后的初始化:设置 server 名称、启动三大守护进程、定义队列、把计算节点加进来。这一章按顺序走一遍,每一步都给出可抄的命令和该盯的输出。
3.1 make 与安装的实操顺序
configure 通过后,编译分两步:先make编全部组件,再make install装到 prefix。老源码并行编译偶尔会因依赖顺序出问题,第一次建议单线程跑,确认没问题后再用-j加速重编。
# 首次编译用单线程,避免老 Makefile 的依赖顺序问题 make 2>&1 | tee build.log # 编译成功后安装 make installtee build.log是为了留证据,编译报错时直接grep -i error build.log定位,比翻终端回滚快得多。如果 make 中途失败,先看最后 20 行,常见的是缺头文件或某个子目录的 Makefile 没生成,前者补依赖,后者重新跑 configure。
安装完成后确认关键文件到位:
ls /opt/torque/bin/qsub /opt/torque/sbin/pbs_server ls /var/spool/torque/server_priv/server_priv目录存在说明 server-home 初始化正常,后面队列定义就写在这里。
3.2 设置 server 名称与启动守护进程
torque 靠主机名识别 server,装完第一件事是把 server 名称写进配置,否则 pbs_server 启动时会报找不到自身。用pbs_server -t create首次创建运行时数据库,再用 qmgr 设名称。
# 首次启动,创建 server 数据库 /opt/torque/sbin/pbs_server -t create # 设置 server 名称,必须与主机名解析一致 /opt/torque/bin/qmgr -c "set server server_name = $(hostname)" # 启动 mom(计算节点侧)和调度器 /opt/torque/sbin/pbs_mom /opt/torque/sbin/pbs_sched-t create只在第一次用,它会初始化 server_priv 下的数据库文件;重复执行会覆盖,别手滑。server_name必须能被集群内所有节点解析到,用 IP 或 hosts 里配好的名字都行,但一定要一致,否则 mom 连不上 server。三个进程的启动顺序建议 server → mom → sched,sched 依赖 server 的作业列表,起早了会空转重试。
启动后用qstat -B看 server 状态,pbsnodes -a看节点是否注册上来。节点列表为空是正常的,还没加节点。
3.3 定义队列与加入计算节点
队列是 torque 里作业的“入口分类”,每个队列有自己的资源上限和优先级。最小可用配置是一个批处理队列加一个计算节点。
# 创建名为 batch 的队列,指定可用的节点 /opt/torque/bin/qmgr -c "create queue batch queue_type = Execution" /opt/torque/bin/qmgr -c "set queue batch enabled = True" /opt/torque/bin/qmgr -c "set queue batch started = True" /opt/torque/bin/qmgr -c "set queue batch resources_max.walltime = 24:00:00" # 把本机作为计算节点加入 /opt/torque/bin/qmgr -c "create node $(hostname)"enabled=True表示队列接受提交,started=True表示允许调度,两个都开作业才会跑,只开一个会出现作业排队但永远不执行的情况,这是新手最常踩的坑之一。resources_max.walltime限制单作业最长运行时间,超时会被 mom 杀掉,按实际业务设,别设太大也别太小。
加完节点用pbsnodes -a确认状态是free,然后提交一个测试作业:
echo "sleep 5; echo hello from torque" | qsub -q batch qstat -aqstat 里看到作业从 Q 变 R 再变 C,说明整条链路通了。如果一直 Q,回去看 3.2 的进程和 3.3 的 started 标志。
4. 调度与资源限制:walltime、节点属性与排队策略
环境跑通只是及格线,真正决定集群好不好用的是调度配置。torque 默认调度器逻辑简单,靠队列资源和节点属性做匹配,理解这几个参数才能让作业排得合理、不互相挤占。
4.1 walltime 与资源上限的配合
walltime 是作业最长运行时间,设在哪一层有讲究。队列级的resources_max.walltime是硬上限,超过直接拒绝提交;节点级可以再设更细的限制。实际配置里我一般队列给宽、节点给严,让调度器有腾挪空间。
# 队列级:单作业最长 24 小时 qmgr -c "set queue batch resources_max.walltime = 24:00:00" # 节点级:单节点同时最多跑 4 个作业,避免内存打爆 qmgr -c "set node $(hostname) max_running = 4"max_running控制单节点并发作业数,比单纯靠内存监控更直接。设太小节点利用率低,设太大容易 OOM,按节点核数和单作业平均内存估。walltime 超时的作业会被 mom 发 SIGTERM,再不行 SIGKILL,日志在 mom 的 log 里能看到具体时间点。
4.2 节点属性与作业路由
节点属性(properties)是让作业“指定去哪类机器”的机制。比如一批节点有 GPU、一批没有,给节点打属性,提交时用-l nodes=1:gpu就能路由过去。
# 给节点打属性标记 qmgr -c "set node node01 properties = gpu" qmgr -c "set node node02 properties = cpu" # 提交时指定节点属性 qsub -l nodes=1:gpu -q batch job.sh属性名自己定,但要和提交时的写法严格一致,大小写敏感。常见翻车是节点属性设了GPU大写,提交写gpu,结果作业一直排队等不到匹配节点,qstat 里看不出原因,得去 sched 日志里找 “no suitable node” 之类的记录。所以属性命名统一小写,团队里约定好。
4.3 排队策略与优先级
torque 默认按提交顺序排队(FIFO),队列可以设优先级让重要作业先跑。queue_priority数值越大越优先,但只在同队列内比较,跨队列要靠 server 级的调度权重。
# 高优队列,数值大于默认队列 qmgr -c "create queue urgent queue_type = Execution" qmgr -c "set queue urgent priority = 100" qmgr -c "set queue urgent enabled = True" qmgr -c "set queue urgent started = True"优先级不是抢占,已经在跑的作业不会被踢,只是新作业排队时高优队列先被调度器看到。如果业务需要“紧急作业插队”,得靠预留资源或手动 qmove 到空闲队列,别指望优先级能打断运行中的作业。这一点在规划队列结构时就要想清楚,事后改代价大。
5. 避坑与排查:作业卡 Q、节点掉线、编译报错的真实处理
这套东西跑起来之后,问题基本集中在三类:作业不跑、节点失联、编译或启动失败。下面几条都是实际环境里反复出现的,按“现象 → 原因 → 解决”记,遇到时直接对号入座。
5.1 作业一直 Q 状态不动
现象:qsub 提交后 qstat 显示 Q,几分钟甚至几小时都不变 R。原因通常有三个:队列started没开、调度器进程没起、或者作业请求的资源没有节点能满足。解决顺序是先qstat -B确认 server 活着,再ps aux | grep pbs_sched确认调度器在跑,最后qmgr -c "print queue batch"看 started 是否为 True。如果都正常,去 sched 日志里搜作业 ID,通常会写 “insufficient resource” 或 “no node available”,按提示调资源请求或加节点属性。
5.2 节点显示 down 或 state-unknown
现象:pbsnodes -a里节点状态是 down 或 state-unknown,作业派不过去。原因多是 mom 进程没起、或者 mom 和 server 之间主机名解析不一致。先在节点上ps aux | grep pbs_mom确认进程,没有就手动起;进程在但状态异常,检查/var/spool/torque/mom_logs/下最新日志,常见是 “cannot connect to server”,说明 mom 配置里的 server 名解析不到。解决是把 server 名写进节点 hosts 或 DNS,重启 mom。
5.3 编译时报找不到头文件
现象:make 到某个模块突然报fatal error: xxx.h: No such file or directory。原因是 configure 阶段没检测到对应开发包,或者检测到了但路径没进 Makefile。先看 build.log 里 configure 摘要那段的 “checking for” 结果,缺什么补什么开发包,然后重新跑 configure再 make,别只 make clean 就重编,configure 的缓存会保留错误判断。补完依赖后删掉源码树重解压最干净,老源码的 config.cache 有时会误导。
5.4 qsub 提交被拒:Unauthorized Request
现象:qsub 报 “Unauthorized Request” 或 “bad UID”。原因是提交作业的用户在 server 侧没有映射,或者 server 运行用户和提交用户权限不匹配。torque 靠 server_priv 下的用户映射做认证,检查/var/spool/torque/server_priv/权限是否对 server 运行用户可写,以及提交用户是否在允许列表里。内网小集群常见做法是统一用同一个系统用户跑 server 和提交,省掉映射麻烦,但多用户场景必须配好映射,别图省事全用 root。
5.5 作业跑完但输出文件为空
现象:作业状态 C,但 stdout/stderr 文件是空的或不存在。原因是 mom 回传输出的路径在提交节点上不可写,或者作业的工作目录在计算节点上不存在。qsub 默认把输出写到提交时的当前目录,跨节点时这个路径必须共享存储可达。解决是提交时用-o和-e显式指定共享存储上的路径,或者确保所有节点挂载了同一份 home。这个坑在没配共享存储的小集群上几乎必踩,提前规划存储比事后补快。
6. 进阶:用 qmgr 批量配置与调度日志定位慢作业
环境稳定后,真正花时间的是“为什么这个作业排了这么久”。torque 的调度决策不直观,得靠日志反推。我一般会打开 sched 的详细日志,再用 qmgr 把常用配置脚本化,避免每次手敲。
先看调度日志的位置和关键字段。sched 日志默认在 server-home 下的sched_logs/,里面每次调度周期会记录可用节点、候选作业、匹配结果。定位一个慢作业,先拿到它的 ID,然后:
# 在调度日志里追踪某个作业的匹配过程 grep "job_id_here" /var/spool/torque/sched_logs/* | tail -20输出里重点看两类行:一类是 “considering job”,说明调度器看到了它;另一类是 “no suitable node” 或 “insufficient”,说明卡在资源匹配。如果连 “considering” 都没有,问题在 server 侧没把作业放进候选列表,回去查队列 started 和作业状态。
批量配置用 qmgr 的批处理模式,把常用设置写成一个文件一次导入,比逐条敲可靠:
# 把队列和节点配置写成脚本,便于重建环境 cat > torque_setup.cfg <<'EOF' create queue batch queue_type = Execution set queue batch enabled = True set queue batch started = True set queue batch resources_max.walltime = 24:00:00 set node node01 properties = cpu set node node01 max_running = 4 EOF qmgr < torque_setup.cfg这个脚本在重建环境或迁移到新 server 时直接复用,配置版本也能进仓库管理。注意 qmgr 批处理遇到已存在的对象会报错中断,重建前先清空或加判断,别在已有环境上盲跑。
还有一个实用技巧:用qstat -f看单个作业的完整属性,里面exec_host字段告诉你它最终跑在哪个节点,resources_used是实际消耗,和提交时请求的Resource_List对比,能看出是请求过大还是节点被占满。慢作业十有八九是请求的资源比实际需要多,调度器找不到足够大的空档,把请求调小往往立刻见效。
从那以后我每次配新队列,都先把qstat -f和一个测试作业的完整生命周期走一遍,确认 Q→R→C 每一步的日志都对得上,再放真实业务进去。这套源码包不新,但把进程模型和日志看透,排错就是查表的事。希望帮到你。
本文还有配套的精品资源,点击获取