多服务器显卡使用状态监控工具实现
一、前言
实验室是做计算机视觉的,拥有几台服务器,每台服务器上有1到8张数量不等的显卡,用于同学们跑深度学习算法。每次到了会议/期刊截稿前,服务器都人满为患,大家各种抢显卡用(同时占用多张显卡能提高程序的并行性,训练模型花费时间变少),旱的旱死涝旳涝死,有的同学占了十几张卡,而有的同学天天蹲守服务器也等不到一张空闲的卡。于是,产品经理(其实是实验室大师兄)提了个需求,让我写个显卡监控工具,用于监控所有服务器的显卡使用情况,并汇总到一起做个排名(每人用了多少张卡,占了多少显存等等)。
二、实现
- 我的想法基于C/S模型
- 在每个需要监控的服务器上运行一个客户端,每隔一段时间就把当前服务器的显卡使用情况发送给服务器
- 服务器负责接收这些信息,并做汇总排序
- 有了想法后,再参考网上大佬的代码,具体实现如下
2.1 客户端
- 用Popen函数执行nvidia-smi命令,获取返回信息。然后使用正则匹配的方式获取nvidia-smi返回信息中的GPU信息和进程信息。GPU信息包含每张显卡的显存大小、已被占用显存;进程信息包含显卡ID、进程ID、执行命令、占用显存。然后通过进程ID找到对应的用户名
def get_owner(pid):try:for line in open('/proc/%d/status' % pid):if line.startswith('Uid:'):uid = int(line.split()[1])return pwd.getpwuid(uid).pw_nameexcept:return Nonedef get_info():info = { 'gpu': [], 'process': [] }msg = subprocess.Popen('nvidia-smi', stdout = subprocess.PIPE).stdout.read().decode()msg = msg.strip().split('\n')lino = 8while True:status = re.findall('.*\d+%.*\d+C.*\d+W / +\d+W.* +(\d+)MiB / +(\d+)MiB.* +\d+%.*', msg[lino])if status == []: breakmem_usage, mem_total = status[0]info['gpu'].append({'mem_usage': float(mem_usage),'mem_total': float(mem_total),})lino += 3lino = -1while True:lino -= 1status = re.findall('\| +(\d+) +(\d+) +\w+ +([^ ]*) +(\d+)MiB \|', msg[lino])if status == []: breakgpuid, pid, program, mem_usage = status[0]username = get_owner(int(pid))if username is None:print('进程已经不存在')continuetry:p = psutil.Process(int(pid))p.cpu_percent()time.sleep(0.5)cpu_percent = p.cpu_percent()except psutil.NoSuchProcess:print('进程已经不存在')continueinfo['process'].append({'gpuid': int(gpuid),'pid': int(pid),'program': program,'cpu_percent': cpu_percent,'mem_usage': float(mem_usage),'username': username,})info['process'].reverse()return info
- 获取显卡信息后通过HTTP库request,把显卡信息发送给服务器,并sleep一定时间(每隔一定时间获取一次显卡信息并发送)
while True:mean_info = get_info()data = json.dumps(mean_info)try:response = requests.get(url, data = data)print('HTTP状态码:', response.status_code)except Exception as e:print(e)time.sleep(opt.persecond)
2.2 服务器
- 使用http.server中的HTTPServer类,开启一个HTTP服务器,在do_GET函数中对客户端的GET请求进行处理,主要是更新客户端的显卡信息和时间戳
class CustomHandler(BaseHTTPRequestHandler):alert_record = { }def do_GET(self):length = int(self.headers['content-length'])info = json.loads(self.rfile.read(length).decode())slaver_address, _ = self.client_addresslock.acquire()if slaver_address not in info_record:info_record[slaver_address] = {}info_record[slaver_address]['info'] = infoinfo_record[slaver_address]['timestamp'] = time.time()lock.release()report_user()self.send_response(200)self.end_headers()
- 在report_user函数中对显卡信息进行排序输出。遍历info_record(info_record是一个dict,用于保存每个客户端的显卡信息和时间戳,直接用客户IP地址字符串作为dict的键),判断客户端的显卡信息是否过期(默认100s不更新就算过期),若过期,直接continue;若不过期,则分别统计用户显存占用和用户显卡占用。处理完info_record后,把排序结果print到终端
def report_user():usage_dict = { }usage_num = { }lock.acquire()for slaver_address in sorted(info_record.keys()):if isExpire(info_record[slaver_address]['timestamp']):continuepi_list = info_record[slaver_address]['info']['process']for pi in pi_list:username = pi['username']mem_usage = pi['mem_usage']gpu_id = pi['gpuid']usage_dict[username] = usage_dict.get(username, 0) + mem_usageif username in usage_num:usage_num[username].add(slaver_address + ':' + str(gpu_id))else:s = set()s.add(slaver_address + ':' + str(gpu_id))usage_num[username] = slock.release()print('=' * 60)print(time.strftime('%Y-%m-%d %H:%M:%S\n', time.localtime(time.time())))usage_list = sorted(usage_dict.items(), key = lambda x: x[1], reverse=True)print('用户显存占用排序:')print('<用户ID> : <占用显存(MB)>')for username, usagememory in usage_list:print('%s : %dM' % (username, usagememory))# report1 = ['%s : %dM' % (n, u) for n, u in usage_list]# report1 = '\n'.join(report1)print()usage_num_list = sorted(usage_num.items(), key = lambda x: len(x[1]), reverse=True)print('用户显卡占用排序:')print('<用户ID> : <占用显卡数量> : <显卡IP地址和ID>')for username, gpuset in usage_num_list:print('%s : %d : ' % (username, len(gpuset)), end='')for gpuaddr in gpuset:print('%s, ' % gpuaddr, end='')print()print('=' * 60)return
三、最终效果
完整代码
多服务器显卡使用状态监控工具实现相关推荐
- 服务器状态监控app,服务器/网站连接状态监控工具
本工具是监听服务器或者网站状态的工具,一次可以批量检测多个IP或者服务器,工具是由概念网络自主开发的,本工具为收费软件,没有免费版本下载,程序是用C#开发,需要.Net Framework 3.5及以 ...
- RTX30 系列游戏本与台式机、云服务器显卡 AI 计算力对比
目录 笔记本显卡: AI大咖性能对比: 云服务器显卡对比: MX450单挑GTX1650: 新一代移动版显卡性能对比: RTX30 系列台式机显卡性能对比: 小结: 最近考虑用什么显卡来做AI训练,既 ...
- 查看和指定GPU服务器显卡训练模型
查看和指定GPU服务器显卡 1.查看显卡 2.间隔查看GPU使用情况 3.查看当前显卡信息 4. 使用os指定使用的显卡 1.查看显卡 nvidia-smi GPU:GPU 编号:与实际编号不一定一致 ...
- mysql php状态函数_mysql_stat()查询MySQL服务器当前系统状态
mysql教程:mysql_stat()查询MySQL服务器当前系统状态 定义和用法 mysql_stat() 函数返回 MySQL 服务器的当前系统状态. 如果成功,则该函数返回状态.如果失败,则返 ...
- arduino服务器_如何使用Arduino检查Web服务器的响应状态
arduino服务器 by Harshita Arora 通过Harshita Arora 如何使用Arduino检查Web服务器的响应状态 (How to use Arduino to check ...
- Nagios监控HP服务器的硬件状态
Nagios监控HP服务器的硬件状态 安装环境:RHEL6 方法一: (1) 下载bootstrap.sh #wget http://downloads.linux.hp.com/SDR/ ...
- linux生产服务器有关网络状态的优化措施
本博文为老男孩linu培训机构早期的培训教案,特分享以供大家学习参考. 全部系列分为五篇文章,本博文为第五篇:5.1高并发linux生产服务器内核参数优化案例 高并发linux生产服务器内核参数优化案 ...
- 状态服务器与无状态服务器(要点)
对服务器程序来说,究竟是有状态服务,还是无状态服务,其判断依旧是指两个来自相同发起者的请求在服务器端是否具备上下文关系.如果是状态化请求,那么服务器端一般都要保存请求的相关信息,每个请求可以默认地使用 ...
- 服务器常用的状态码及其对应的含义
服务器常用的状态码及其对应的含义如下: 200:服务器响应正常. 304:该资源在上次请求之后没有任何修改(这通常用于浏览器的缓存机制,使用GET请求时尤其需要注意). 400:无法找到请求的资源. ...
最新文章
- VS2019配置opencv环境时找不到Microsoft.Cpp.x64.user.props
- Tensorflow中padding的两种类型SAME和VALID
- android ip rule 策略路由,ip rule 策略路由
- [ATF]-MTK:一篇文章了解ATF原理
- bilstm+crf中文分词_基于LSTM的中文分词模型
- 移动应用APP性能测试白皮书
- ECCV 2020 | 小米提出 Fair DARTS :公平的可微分神经网络搜索
- 作业帮:字符串反转(头部插入)
- 吃豆人动态模型创建---canvas
- c++ Primer plus 之c++学习
- make_heap(), pop_heap(), push_heap()用法
- jquery实现页面提示,数据正在加载中
- 服务器打微软补丁后无法启动,关于打了最新微软补丁后,针式打印机突然不好打印的处理方法。...
- 【软件工程】软件测试报告——软件测试说明书
- XMAPP启动apache和mysql失败的问题
- kubernetes(k8s)安装metrics-server实现资源使用情况监控
- C++Error2208:...尝试引用已删除的函数
- 痔疮最佳治疗方法 十人九痔 不必害羞
- parsel安装老是失败_adb安装应用失败,错误码
- 【生产调度】基于遗传算法求解柔性生产调度(FJSP)问题含Matlab源码