基于Python的HPC共享集群作业专属资源监控问题求解
HPC作业专属资源占用监控解决方案
背景
当前开发的psutil基础监控脚本默认采集的是集群节点的整机资源指标,在多用户共享的HPC集群中无法匹配申请的专属作业资源,无法支撑作业拆分、配额评估的决策需求。
当前已完成的基础监控代码如下:
#!/usr/bin/env python from __future__ import division, print_function import psutil from argparse import ArgumentParser import time def getUsage(): cpu = psutil.cpu_percent() memory = psutil.virtual_memory().percent return cpu, memory, psutil.disk_io_counters().read_bytes, psutil.disk_io_counters().write_bytes def main(args): the_file = open(args.name + ".txt", 'a') the_file.write("cpu,memory,read,write\n") while True: cpu, memory, read, write = getUsage() the_file.write("{},{},{},{}\n".format(cpu, memory,read,write)) time.sleep(args.sleepTime*60) if __name__ == "__main__": parser = ArgumentParser("monitor", description="monitors cpu and memory usage") parser.add_argument("--name", required=True, help="name of the file that contains the usage info") parser.add_argument("--sleepTime", default=1, type=float, help="the sleep time between every entry in minutes") args = parser.parse_args() main(args)
原有脚本输出的整机监控可视化示例:
可行解决方案
以下3种方案适配不同的集群环境,可按需选择:
方案1:基于作业进程树统计(改造成本最低,无需集群权限)
原理:HPC作业启动后,所有任务子进程都会挂载在作业的主进程下,只需在启动监控脚本时传入作业主进程PID,遍历进程树累加资源即可得到作业专属的资源使用量。
核心修改代码片段:# 新增参数,传入作业主进程PID parser.add_argument("--pid", required=True, type=int, help="PID of the target HPC job main process") def get_job_usage(job_pid): total_cpu = 0 total_mem = 0 total_read = 0 total_write = 0 # 遍历主进程+所有子进程 try: parent = psutil.Process(job_pid) processes = [parent] + parent.children(recursive=True) for p in processes: with p.oneshot(): total_cpu += p.cpu_percent() total_mem += p.memory_percent() io = p.io_counters() total_read += io.read_bytes total_write += io.write_bytes except psutil.NoSuchProcess: # 作业结束自动退出监控 return None return total_cpu, total_mem, total_read, total_write注意:如果集群用SLURM调度,作业主进程PID可以通过环境变量
SLURM_TASK_PID直接获取,无需手动传入。方案2:对接集群调度器自带统计接口(数据最贴合配额规则)
主流HPC调度器本身就会记录每个作业的资源分配量和实际使用量,直接调用调度器命令即可拿到精准数据,不用自己统计进程:- SLURM集群:调用
sstat -j <JOBID> --format=JobID,CPUTime,MaxRSS,MaxDiskRead,MaxDiskWrite命令,解析输出即可 - PBS集群:调用
qstat -f <JOBID>命令,解析对应资源字段即可
这种方式统计的数据会直接和申请的配额做对应,不需要额外换算占比。
- SLURM集群:调用
方案3:读取cgroup统计文件(精度最高,适配cgroup隔离的集群)
现在绝大多数HPC都用cgroup做资源隔离,每个作业对应独立的cgroup目录,直接读取目录下的统计文件即可拿到作业级的精准资源使用:- CPU使用:读取
/sys/fs/cgroup/cpuacct/<作业cgroup路径>/cpuacct.usage - 内存使用:读取
/sys/fs/cgroup/memory/<作业cgroup路径>/memory.usage_in_bytes - 磁盘IO:读取
/sys/fs/cgroup/blkio/<作业cgroup路径>/blkio.throttle.io_service_bytes
作业的cgroup路径可以通过调度器环境变量或者/proc/<pid>/cgroup查询得到。
- CPU使用:读取
内容的提问来源于stack exchange,提问作者Mc Missile
相关产品推荐
相关产品推荐

