[gelöst] CPU-Auslastung mit Bordmitteln der Bash begrenzen
[gelöst] CPU-Auslastung mit Bordmitteln der Bash begrenzen
Hallo zusammen,
ich habe einen vServer, dessen Ressourcen ich mir mit anderen teile. Die Anzahl der zur Verfügung stehenden CPU-Cores hat mich dazu verleitet rechenintensive Operationen auf den Server auszulagern, was naturgemäß bei den anderen Usern nicht gut ankommt. Ich habe also meine rechenintensiven Prozesse mit einem nice -n19 <Prozess> gestartet, was aber seitens der Administratoren auch unerwünscht war.
Tools wie cpulimit oder cgroup fallen raus, weil mangels su-Rechte nicht installierbar.
Die Funktionsweise von cpulimit ist, sofern ich das richtig verstehe, einen Prozess zu starten und wieder schlafen zu legen. Je länger der Prozess schläft, desto geringer ist die Arbeitslast, die der Prozess erzeugt. Umgesetzt in der Bash könnte das so aussehen:
#!/bin/bash
#
cat /dev/zero > /tmp/outfile.dat &
#
PROC=$!
SLEEP=0
#
while :; do
case "$SLEEP" in
0) kill -19 $PROC && SLEEP=1 && sleep 0.0005 ;;
1) kill -18 $PROC && SLEEP=0 ;;
esac
done
Problem: Das Skript erzeugt bei mir eine Last von etwa 16%, der eigentliche Befehl cat jedoch nur 3%. Gibt es eine Möglichkeit den Overhead durch das Skript zu reduzieren, damit der Prozess, der limitiert werden soll, ein größeres Stück vom Kuchen abkriegt?
//edit:
Wenn ich den o.g. cat-Befehl abändere zu cat /dev/urandom > /dev/null bekomme ich anstelle 3%-Auslastung plötzlich ~40% Auslastung auf der CPU, neben den 16%, die für das eigentliche Skript anfallen. Wie kann das sein?
ich habe einen vServer, dessen Ressourcen ich mir mit anderen teile. Die Anzahl der zur Verfügung stehenden CPU-Cores hat mich dazu verleitet rechenintensive Operationen auf den Server auszulagern, was naturgemäß bei den anderen Usern nicht gut ankommt. Ich habe also meine rechenintensiven Prozesse mit einem nice -n19 <Prozess> gestartet, was aber seitens der Administratoren auch unerwünscht war.
Tools wie cpulimit oder cgroup fallen raus, weil mangels su-Rechte nicht installierbar.
Die Funktionsweise von cpulimit ist, sofern ich das richtig verstehe, einen Prozess zu starten und wieder schlafen zu legen. Je länger der Prozess schläft, desto geringer ist die Arbeitslast, die der Prozess erzeugt. Umgesetzt in der Bash könnte das so aussehen:
#!/bin/bash
#
cat /dev/zero > /tmp/outfile.dat &
#
PROC=$!
SLEEP=0
#
while :; do
case "$SLEEP" in
0) kill -19 $PROC && SLEEP=1 && sleep 0.0005 ;;
1) kill -18 $PROC && SLEEP=0 ;;
esac
done
Problem: Das Skript erzeugt bei mir eine Last von etwa 16%, der eigentliche Befehl cat jedoch nur 3%. Gibt es eine Möglichkeit den Overhead durch das Skript zu reduzieren, damit der Prozess, der limitiert werden soll, ein größeres Stück vom Kuchen abkriegt?
//edit:
Wenn ich den o.g. cat-Befehl abändere zu cat /dev/urandom > /dev/null bekomme ich anstelle 3%-Auslastung plötzlich ~40% Auslastung auf der CPU, neben den 16%, die für das eigentliche Skript anfallen. Wie kann das sein?
Zuletzt geändert von Tintom am 23.12.2018 08:11:52, insgesamt 1-mal geändert.
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
Wenn Du kein sleep hinter dem Sigcont hast, wird der Prozess doch fast sofort wieder gestoppt. Vielleicht testest Du mal mit (unterschiedlich großen) Sleepzeiten für Sigstop und Sigcont, dann sollte die Schleife selbst auch nicht mehr so viel CPU-Last erzeugen.
Dann brauchst Du übrigens auch kein case mehr, einfach Sigstop, Sleep, Sigcont, sleep und wieder von vorn, das sollte die Schleife auch nochmal entlasten.
Dann brauchst Du übrigens auch kein case mehr, einfach Sigstop, Sleep, Sigcont, sleep und wieder von vorn, das sollte die Schleife auch nochmal entlasten.
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
sleep erwartet ein Zeitinterval in Sekunden. 0.0005 wird zu Null gerunden, was dann dazu führt, daß du das System mit einer extremen Folge von teurern kill-Aufrufen auslastest.
Eigentlich wäre nice -19 schon der richtige Weg. Ein derart runterpriorisierter Prozeß bekommt zwar 100% der CPU, wenn nichts anderes läuft, muß aber sofort zurückstecken, wenn irgenjemand anderes die CPU braucht. Warum das deine Mitstreiter irgendwie falsch verstanden haben, kann ich dir natürlich nicht sagen.
Problematisch wird es erst, wenn ein Prozeß den Hauptspeicher belagert und das System ins Swappen gerät, wenn andere Prozesse laufen sollen. Da hilft dann auch kein nice oder Basteleien mit sleep.
Eigentlich wäre nice -19 schon der richtige Weg. Ein derart runterpriorisierter Prozeß bekommt zwar 100% der CPU, wenn nichts anderes läuft, muß aber sofort zurückstecken, wenn irgenjemand anderes die CPU braucht. Warum das deine Mitstreiter irgendwie falsch verstanden haben, kann ich dir natürlich nicht sagen.
Problematisch wird es erst, wenn ein Prozeß den Hauptspeicher belagert und das System ins Swappen gerät, wenn andere Prozesse laufen sollen. Da hilft dann auch kein nice oder Basteleien mit sleep.
-
- Beiträge: 385
- Registriert: 16.06.2017 09:52:36
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
Es gibt auch noch ein bash-builtin namens "ulimit". Tipp mal (natürlich nur in einer bash-session).
Code: Alles auswählen
help ulimit
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
Bei mir nimmt sleep auch Sekundenbruchteile.
Code: Alles auswählen
time for ((i=1;i<=30;i++)) do sleep .1 ; printf \\r$i ; done
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
Interessant, again what learned.
Trotzdem ist der oben genannte Wert von 0.0005s viel zu klein um irgendetwas, ausser Last durch kill- und sleep-Aufrufe zu bewirken.
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
Das sehe ich auch so, 2000 Schleifendurchläufe pro Sekunde ist hier viel zu viel.MSfree hat geschrieben:22.12.2018 18:57:58Trotzdem ist der oben genannte Wert von 0.0005s viel zu klein um irgendetwas, ausser Last durch kill- und sleep-Aufrufe zu bewirken.
Als leidenschaftlich faule Sau, sehe ich mir nicht "help ulimit" an, unterstütze aber die entsprechende Empfehlung von RobertDebiannutzer.
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
Danke für eure Antworten!
ulimit kannte ich noch gar nicht, danke!
Allerdings weiß ich nicht so recht, wie ich damit umgehen soll.
$help ulimit
ulimit: ulimit [-SHabcdefiklmnpqrstuvxPT] [Grenze]
Modify shell resource limits.
Provides control over the resources available to the shell and processes
it creates, on systems that allow such control.
Options:
-S use the `soft' resource limit
-H use the `hard' resource limit
-a all current limits are reported
-b the socket buffer size
-c the maximum size of core files created
-d the maximum size of a process's data segment
-e the maximum scheduling priority (`nice')
-f the maximum size of files written by the shell and its children
-i the maximum number of pending signals
-k the maximum number of kqueues allocated for this process
-l the maximum size a process may lock into memory
-m the maximum resident set size
-n the maximum number of open file descriptors
-p the pipe buffer size
-q the maximum number of bytes in POSIX message queues
-r the maximum real-time scheduling priority
-s the maximum stack size
-t the maximum amount of cpu time in seconds
-u the maximum number of user processes
-v the size of virtual memory
-x the maximum number of file locks
-P the maximum number of pseudoterminals
-T the maximum number of threads
Ich habe im ersten Anlauf den Parameter -t genommen, aber zum einen läuft der Prozess mit 100% Leistung und zum anderen wird er nach Erreichen des Limits gekillt. Oder nehme ich einfach nur den falschen Parameter?
ulimit kannte ich noch gar nicht, danke!
Allerdings weiß ich nicht so recht, wie ich damit umgehen soll.
$help ulimit
ulimit: ulimit [-SHabcdefiklmnpqrstuvxPT] [Grenze]
Modify shell resource limits.
Provides control over the resources available to the shell and processes
it creates, on systems that allow such control.
Options:
-S use the `soft' resource limit
-H use the `hard' resource limit
-a all current limits are reported
-b the socket buffer size
-c the maximum size of core files created
-d the maximum size of a process's data segment
-e the maximum scheduling priority (`nice')
-f the maximum size of files written by the shell and its children
-i the maximum number of pending signals
-k the maximum number of kqueues allocated for this process
-l the maximum size a process may lock into memory
-m the maximum resident set size
-n the maximum number of open file descriptors
-p the pipe buffer size
-q the maximum number of bytes in POSIX message queues
-r the maximum real-time scheduling priority
-s the maximum stack size
-t the maximum amount of cpu time in seconds
-u the maximum number of user processes
-v the size of virtual memory
-x the maximum number of file locks
-P the maximum number of pseudoterminals
-T the maximum number of threads
Ich habe im ersten Anlauf den Parameter -t genommen, aber zum einen läuft der Prozess mit 100% Leistung und zum anderen wird er nach Erreichen des Limits gekillt. Oder nehme ich einfach nur den falschen Parameter?
Stimmt, daran hatte ich noch gar nicht gedacht. Wenn ich mit dem Sleep-Paramter ein bisschen rumspiele und höhere Werte benutze, kommen auch realistische Werte bei der Auslastung heraus. Danke!MSfree hat geschrieben:22.12.2018 18:57:58Trotzdem ist der oben genannte Wert von 0.0005s viel zu klein um irgendetwas, ausser Last durch kill- und sleep-Aufrufe zu bewirken.
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
ulimit wird dich nicht weiterbringen. Das ist nicht zum Einschränken des Anteils an der CPU geeignet. Man kann damit nur maximale grenzen setzen und wenn diese überschritten werden, wird der Prozeß gekillt.
Es gibt auch keine Möglichkeit unter Linux, den CPU-Anteil z.B. auf 50% zu beschränken. Das ganze wäre auch kompletter Unsinn. Deinen Mitstreitern solltest du mal folgdendes Zeigen. Starte folgende Prozesse:
und
Du wirst sehen, daß gzip praktisch 100% der CPU belegt. Starte nun einen zweiten Prozeß:
Und du siehst, wie der genicete Prozeß vom normal laufenden verdrängt wird.
100% CPU-Last ist nicht schädlich und führt auch nicht zu einem schlecht reagierenden System, wenn man "CPU-Fresser" runterpriorisiert. Warum sich deine Mitstreiter da so aufregen, zeugt nur von deren Unwissenheit.
Es gibt auch keine Möglichkeit unter Linux, den CPU-Anteil z.B. auf 50% zu beschränken. Das ganze wäre auch kompletter Unsinn. Deinen Mitstreitern solltest du mal folgdendes Zeigen. Starte folgende Prozesse:
Code: Alles auswählen
nice -19 gzip -9 -c /dev/zero > /dev/null &
Code: Alles auswählen
top
Code: Alles auswählen
gzip -9 -c /dev/zero > /dev/null &
100% CPU-Last ist nicht schädlich und führt auch nicht zu einem schlecht reagierenden System, wenn man "CPU-Fresser" runterpriorisiert. Warum sich deine Mitstreiter da so aufregen, zeugt nur von deren Unwissenheit.
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
Der Hinweis von Phineas hat es schlussendlich gebracht. Nach ein wenig umschreiben sieht die Lösung nun so aus:
#!/bin/bash
cat /dev/urandom > /dev/null &
PROC=$!
SLEEP=0.7
AWAKE=`bc <<<1-$SLEEP`
echo Limit ist `bc <<<$AWAKE*100` Prozent
while :; do
kill -19 $PROC
sleep $SLEEP
kill -18 $PROC
sleep $AWAKE
done
Wenn ich nun top aufrufe, genehmigt sich cat im Schnitt 30% der CPU, das Skript an sich braucht etwa 0,3%. Das passt für mich als Lösung. Vielen Dank an alle Beteiligten!
@MSfree: Ich sehe das genauso wie du, aber der (kommerzielle) Anbieter des vServers hat da leider eine andere Ansicht zu.
#!/bin/bash
cat /dev/urandom > /dev/null &
PROC=$!
SLEEP=0.7
AWAKE=`bc <<<1-$SLEEP`
echo Limit ist `bc <<<$AWAKE*100` Prozent
while :; do
kill -19 $PROC
sleep $SLEEP
kill -18 $PROC
sleep $AWAKE
done
Wenn ich nun top aufrufe, genehmigt sich cat im Schnitt 30% der CPU, das Skript an sich braucht etwa 0,3%. Das passt für mich als Lösung. Vielen Dank an alle Beteiligten!
@MSfree: Ich sehe das genauso wie du, aber der (kommerzielle) Anbieter des vServers hat da leider eine andere Ansicht zu.
Re: CPU-Auslastung mit Bordmitteln der Bash begrenzen
Und eine andere Meßmethode und ich fürchte, das ist ausschlaggebend.Tintom hat geschrieben:22.12.2018 22:57:28... aber der (kommerzielle) Anbieter des vServers hat da leider eine andere Ansicht zu.
(Will sagen dass MSfree Recht hat, aber das nützt so viel, wie eine Abgasmessung bei Volkswagen)