2016-01-08 18 views
5

Pamięć na serwerze mojego laboratorium (Ubuntu) stale się wypełnia, ponieważ użytkownicy nigdy nie wyłączają starych notebooków. Chciałbym lepiej zrozumieć, ile pamięci zajmuje każdy notebook. Mogę podsumować (zgrubne) użycie pamięci dla wszystkich notebooków jupyter uruchamianych przez każdego użytkownika, ale chciałbym uzyskać całkowite wykorzystanie pamięci każdego pojedynczego notebooka, aby móc zamknąć te szczególne świnki pamięci (lub powiedzieć innym użytkownikom, aby zamknęli jego/ona jest na dole). Szybko ułożyłem poniższy kod, aby uzyskać około. mem. użycie na jądro Jupytera, ale nie wiem jak powiązać identyfikatory jądra z konkretnym notatnikiem.Notebook Jupyter: zużycie pamięci dla każdego notebooka

import os 
import pwd 
import pandas as pd 

UID = 1 
EUID = 2 

pids = [pid for pid in os.listdir('/proc') if pid.isdigit()] 

df = [] 
for pid in pids: 
    try: 
     ret = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read() 
    except IOError: # proc has already terminated 
     continue 

    # jupyter notebook processes 
    if len(ret) > 0 and 'share/jupyter/runtime' in ret: 
     process = psutil.Process(int(pid)) 
     mem = process.memory_info()[0] 

     # user name for pid 
     for ln in open('/proc/%d/status' % int(pid)): 
      if ln.startswith('Uid:'): 
       uid = int(ln.split()[UID]) 
       uname = pwd.getpwuid(uid).pw_name 

     # user, pid, memory, proc_desc 
     df.append([uname, pid, mem, ret]) 

df = pd.DataFrame(df) 
df.columns = ['user', 'pid', 'memory', 'proc_desc'] 
df 
+0

nie mogę uruchomić tego powodu .. znalezionego przy błędach 'PackageNotFoundError bez modułu: Pakiety brakuje w obecnych kanałów: - pwd' . każde inne rozwiązanie, które nie wymaga 'pwd'. Jestem na serwerze Windows z pytaniem anakonda 2.7. – ihightower

Odpowiedz

3

I wydawało się, że zorientowali się roztwór roboczy dla własnego problemu:

import os 
import pwd 
import psutil 
import re 
import string 
import json 
import urllib2 
import pandas as pd 

UID = 1 
EUID = 2 
regex = re.compile(r'.+kernel-(.+)\.json') 

pids = [pid for pid in os.listdir('/proc') if pid.isdigit()] 

# memory info from psutil.Process 
df_mem = [] 
for pid in pids: 
    try: 
     ret = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read() 
    except IOError: # proc has already terminated 
     continue 

    # jupyter notebook processes 
    if len(ret) > 0 and 'share/jupyter/runtime' in ret: 
     # kernel 
     kernel_ID = re.sub(regex, r'\1', ret) 
     kernel_ID = filter(lambda x: x in string.printable, kernel_ID) 

     # memory 
     process = psutil.Process(int(pid)) 
     mem = process.memory_info()[0]/float(1e9) 


     # user name for pid 
     for ln in open('/proc/{}/status'.format(int(pid))): 
      if ln.startswith('Uid:'): 
       uid = int(ln.split()[UID]) 
       uname = pwd.getpwuid(uid).pw_name 

     # user, pid, memory, kernel_ID 
     df_mem.append([uname, pid, mem, kernel_ID]) 

df_mem = pd.DataFrame(df_mem) 
df_mem.columns = ['user', 'pid', 'memory_GB', 'kernel_ID'] 


# notebook info from assessing ports 
df_nb = [] 
for port in xrange(5000,30000): 
    sessions = None 
    try: 
     url = 'http://127.0.0.1:{}/api/sessions'.format(port) 
     sessions = json.load(urllib2.urlopen(url)) 
    except urllib2.URLError: 
     sessions = None 

    if sessions: 
     for sess in sessions: 
      kernel_ID = str(sess['kernel']['id']) 
      notebook_path = sess['notebook']['path'] 
      df_nb.append([port, kernel_ID, notebook_path]) 

df_nb = pd.DataFrame(df_nb) 
df_nb.columns = ['port', 'kernel_ID', 'notebook_path'] 


# joining tables 
df = pd.merge(df_nb, df_mem, on=['kernel_ID'], how='inner') 
df.sort(['memory_GB'], ascending=False) 
2

Zrobiłem kilka ulepszeń sharchaea's script do przenoszenia i szybkość.

Przede wszystkim sprawdzaj tylko porty, na których działają notebooki, sprawdź różne opcje nazwy hosta, popraw kontrolę procesu jądra i sprawdź, czy jest to ipython lub jupater.

import os 
import pwd 
import psutil 
import re 
import string 
import json 
import urllib2 
import socket 
import pandas as pd 

UID = 1 

regex = re.compile(r'.+kernel-(.+)\.json') 
port_regex = re.compile(r'port=(\d+)') 

pids = [pid for pid in os.listdir('/proc') if pid.isdigit()] 

# memory info from psutil.Process 
df_mem = [] 
ports = [] 
default_port = 8888 

for pid in pids: 
    try: 
     ret = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read() 
    except IOError: # proc has already terminated 
     continue 

    # jupyter notebook processes 
    if len(ret) > 0 and ('jupyter-notebook' in ret or 'ipython notebook' in ret): 
     port_match = re.search(port_regex, ret) 
     if port_match: 
      port = port_match.group(1) 
      ports.append(int(port)) 
     else: 
      ports.append(default_port) 
      default_port += 1 
    if len(ret) > 0 and ('jupyter' in ret or 'ipython' in ret) and 'kernel' in ret: 
     # kernel 
     kernel_ID = re.sub(regex, r'\1', ret) 
     kernel_ID = filter(lambda x: x in string.printable, kernel_ID) 

     # memory 
     process = psutil.Process(int(pid)) 
     mem = process.memory_info()[0]/float(1e9) 

     # user name for pid 
     for ln in open('/proc/{0}/status'.format(int(pid))): 
      if ln.startswith('Uid:'): 
       uid = int(ln.split()[UID]) 
       uname = pwd.getpwuid(uid).pw_name 

     # user, pid, memory, kernel_ID 
     df_mem.append([uname, pid, mem, kernel_ID]) 

df_mem = pd.DataFrame(df_mem) 
df_mem.columns = ['user', 'pid', 'memory_GB', 'kernel_ID'] 

# notebook info from assessing ports 
hostnames = [socket.gethostname(), '127.0.0.1', 'localhost', '0.0.0.0'] 
df_nb = [] 
kernels = [] 

for port in set(ports): 
    for hostname in set(hostnames): 
     sessions = None 
     try: 
      url = 'http://{0}:{1}/api/sessions'.format(hostname, port) 
      print url 
      sessions = json.load(urllib2.urlopen(url)) 
     except urllib2.URLError: 
      sessions = None 

     if sessions: 
      for sess in sessions: 
       kernel_ID = str(sess['kernel']['id']) 
       if kernel_ID not in kernels: 
        notebook_path = sess['notebook']['path'] 
        df_nb.append([port, kernel_ID, notebook_path]) 
        kernels.append(kernel_ID) 

df_nb = pd.DataFrame(df_nb) 
df_nb.columns = ['port', 'kernel_ID', 'notebook_path'] 

# joining tables 
df = pd.merge(df_nb, df_mem, on=['kernel_ID'], how='inner') 
df = df.sort_values('memory_GB', ascending=False) 

df.to_csv('notebook_mem_usage.csv', index=False) 

Pewnie nadal w aktualizacjach tego w tym gist

+0

Nie mogę tego uruchomić .. ze względu na brak modułu z błędem 'PackageNotFoundError: Brak pakietów w bieżących kanałach: - pwd'. każde inne rozwiązanie, które nie wymaga 'pwd'. Jestem na serwerze Windows z pytaniem anakonda 2.7. – ihightower

+0

@ihightower hmmm, wątpię, że to zadziała w systemie Windows. Otrzymuje większość informacji o procesach od proc, który jest uniksowym sposobem przechowywania danych o uruchomionych procesach, usługach itp. Https://stackoverflow.com/questions/5802143/is-there-anything-like-proc- for-windows może dać ci punkt wyjścia. – aiguofer

Powiązane problemy