Was ist der fairste Weg, um die Gesamt-CPU-Zeit pro Benutzer zu überwachen?


25

Auf einem Mehrbenutzersystem möchte ich die CPU-Auslastung jedes Benutzers in Sekunden der CPU-Zeit messen. Für diese Messung gehe ich davon aus, dass dieser Benutzer die CPU-Zeit verursacht, wenn eine PID einem Benutzer gehört - das heißt, ich ignoriere Daemons und den Kernel.

Derzeit mache ich das alle fünf Sekunden:

  1. Rufen Sie jeden Benutzer und die PIDs ab, über die er ausgeführt wird ps aux
  2. Für jede PID erhalten Sie xdie Summe aus utime, cutime, stime und cstime von/proc/[pid]/stat
  3. berechnen t = x / interval(Intervall ist bei hoher Last nicht immer genau 5 Sekunden)

Wenn ich das starte, bekomme ich vernünftig aussehende Werte. Beispiel: Ein Benutzer auf diesem System drehte sich in python ( while True: pass) und das System zeigte ungefähr 750 Millisekunden CPU-Zeit pro Sekunde an. Wenn das System ein bisschen hängen blieb, wurden 1600 ms für einen 1-Sekunden-Intervall gemeldet. Was ungefähr richtig erscheint, aber ich verstehe, dass diese Werte trügerisch sein können, zumal ich sie nicht wirklich verstehe.

Meine Frage lautet also:

Was ist eine faire und korrekte Methode, um die CPU-Auslastung auf Benutzerbasis zu messen?

Die Methode muss ziemlich genau sein. Es gibt möglicherweise viele Hunderte von Benutzern auf diesem System, daher ist das Extrahieren von Prozentsätzen ps auxnicht genau genug, insbesondere für kurzlebige Threads, aus denen viele Softwareteile gerne erstellt werden.

Das mag kompliziert sein, aber ich weiß, dass es möglich ist. Dies war mein Ausgangspunkt:

Der Kernel verfolgt die Erstellungszeit eines Prozesses sowie die CPU-Zeit, die er während seiner Lebensdauer verbraucht. Bei jedem Takt aktualisiert der Kernel die Zeit in Sekundenschnelle, die der aktuelle Prozess im System- und im Benutzermodus verbracht hat. - (aus dem Linux-Dokumentationsprojekt )

Der Wert, nach dem ich mich befinde, ist die Anzahl der Sekunden (oder Zeitspannen), die ein Benutzer für die CPU aufgewendet hat, nicht ein Prozentsatz der Systemlast oder der CPU-Auslastung.

Es ist wichtig, dass wir die CPU-Zeit messen, während die Prozesse noch ausgeführt werden. Einige Prozesse dauern nur eine halbe Sekunde, andere mehrere Monate - und wir müssen beide Arten abfangen, damit wir die CPU-Zeit der Benutzer mit feiner Granularität abrechnen können.


1
500 Ruf: o gute Chance für Anfänger
Tachyons

Ein bisschen außerhalb meiner Liga, aber eine sehr interessante Frage, also habe ich ein bisschen gegraben und etwas gefunden, von dem ich hoffe, dass es zumindest hilfreich ist, um dieses Problem zu
kingmilo

1
Sie wissen, topkönnen Batch-Modus tun? top -b -n 1 -u {user} | awk 'NR>7 { sum += $9; } END { print sum; }'sollte die Last für {user} in diesem Moment anzeigen.
Rinzwind

Antworten:


11

Klingt so, als ob Sie eine Prozessabrechnung benötigen.

http://www.faqs.org/docs/Linux-mini/Process-Accounting.html

Unter Ubuntu sind die Tools für die Prozessabrechnung im acctPaket enthalten Installieren Sie acct

Führen Sie den folgenden Befehl aus, um einen Bericht für einzelne Benutzer zu erhalten

sa -m

Leider funktioniert dies bei mir nicht, da "sa" keine lang laufenden Prozesse berücksichtigt. Was ich brauche (glaube ich), ist eine Möglichkeit, Prozesse zu erkennen, die gestartet und beendet werden, und ihre CPU-Zeit aufzuzeichnen, wenn sie beendet werden sowie während sie ausgeführt werden.
Stefano Palazzo

@StefanoPalazzo Ich glaube, das ist das Beste, was Sie bekommen. Ergänzen Sie es mit Zeiten für das Ausführen von Prozessen von /proc/[pid]/stat.
ændrük

Wie sich herausstellt, werden fast alle Prozesse ordnungsgemäß von sa(.ps.gz) erfasst . Und ich habe auch eine gute Möglichkeit, diese lang andauernden Prozesse zu "schätzen", bevor ich schließlich auch einen genauen Wert für sie erhalte. Also werden wir es doch nutzen, und ich freue mich sehr, die Prämie für Ihre Antwort zu vergeben. Vielen Dank!
Stefano Palazzo

3

Dies gibt für jeden Benutzer eine Zeile mit dem Benutzernamen und seiner gesamten CPU-Zeit:

ps -w -e --no-header -o uid,user \
        | sort -u \
        | while read uid user; do
                echo -e "$user\t"$(
                        ps --no-headers -u $uid --cumulative -o time \
                                | sed -e s/:/*3600+/ -e s/:/*60+/ \
                                | paste -sd+ \
                                | bc
                );
        done

2

Eine der naheliegenderen Antworten ist, einfach zu erweitern, was Sie gerade tun.

Ich bin auf diesen Monitorprozess gestoßen, bei dem Bash-Skripte und MySQL verwendet wurden, um die CPU-Zeit von Benutzern zu verfolgen, aber er wurde über einen viel größeren Zeitraum als den von Ihnen genannten verteilt.

Hoffentlich können Sie dadurch weitere Ideen für die Richtung erhalten, in die Sie sich bewegen möchten.

http://www.dba-oracle.com/t_oracle_unix_linux_vmstat_capture.htm


0

Dies behandelt auch Prozesse, die seit Tagen ausgeführt werden. Sie wissen nicht, wie Sie diese für Wochen / Monate / Jahre erweitern sollen.

ps -w -e --no-header -o uid,user \
    | sort -u \
    | while read uid user; do
            echo -e "$user\t"$(
                    ps --no-headers -u $uid --cumulative -o time \
                          | sed -e s/-/*86400+/ -e s/:/*3600+/ -e s/:/*60+/ 
                          | paste -sd+ \
                          | bc
            );
    done
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.