- Was ist der schnellste Weg, um die Kontrolle über ein Linux-System zurückzugewinnen, das aufgrund übermäßigen Austauschs nicht mehr reagiert oder extrem träge ist?
Wurde oben bereits mit Alt-SysRq-F beantwortet
- Gibt es einen wirksamen Weg, um ein solches Auslagern zu verhindern, indem beispielsweise die Speichermenge begrenzt wird, die ein Prozess zuzuteilen versucht?
Ich beantworte diesen 2. Teil. Ja, ulimit
funktioniert immer noch gut genug, um einen einzelnen Prozess einzuschränken. Sie können:
- Setzen Sie ein weiches Limit für einen Prozess, von dem Sie wissen, dass er wahrscheinlich außer Kontrolle geraten wird
- Setzen Sie ein hartes Limit für alle Prozesse, wenn Sie eine zusätzliche Versicherung wünschen
Auch, wie kurz erwähnt:
Sie können CGroups verwenden, um die Ressourcennutzung einzuschränken und solche Probleme zu vermeiden
Cgroups bieten zwar eine erweiterte Steuerung, sind aber meiner Meinung nach derzeit schwieriger zu konfigurieren.
Alte Schule ulimit
Einmalig
Hier ist ein einfaches Beispiel:
$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)
Es:
- Legt ein Soft-Limit von 1 GB Gesamtspeicher fest (ulimit geht von einem Limit in KB-Einheiten aus)
- Führt einen rekursiven Bash-Funktionsaufruf aus
r2(){ r2 $@$@;};r2 r2
, der die CPU und den RAM exponentiell auslastet, indem er sich beim Anfordern des Stapelspeichers unendlich verdoppelt.
Wie Sie sehen, wurde es angehalten, als versucht wurde, mehr als 1 GB anzufordern.
Beachten Sie, dass -v
die Zuweisung von virtuellem Speicher (insgesamt, dh physisch + Swap) ausgeführt wird.
Permanenter Schutz
Um die Zuweisung as
des virtuellen Speichers zu begrenzen, ist dies das Äquivalent von -v
for limits.conf
.
Ich tue Folgendes, um mich vor einem einzelnen Fehlverhalten zu schützen:
- Legen Sie für alle Prozesse ein festes Adressraumlimit fest.
address space limit = <physical memory> - 256MB
.
- Daher kann kein einzelner Prozess mit übermäßiger Speichernutzung oder einer aktiven Schleife und einem Speicherverlust den gesamten physischen Speicher belegen.
- 256 MB Headroom stehen für die Verarbeitung mit ssh oder einer Konsole zur Verfügung.
Einzeiler:
$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"
Für die Validierung ergibt sich Folgendes (z. B. auf einem 16-GB-System):
$ cat /etc/security/limits.d/mem.conf
* hard as 16135196
$ ulimit -H -v
161351960
Anmerkungen:
- Es wird nur verhindert, dass ein einzelner Prozess mit der Speichernutzung überlastet wird.
- Verhindert nicht, dass ein Multi-Prozess-Workload mit hohem Speicherdruck zu Thrashing führt (cgroups ist dann die Antwort).
- Verwenden Sie nicht die
rss
Option in der limits.conf. Es wird von neueren Kerneln nicht respektiert.
- Es ist konservativ.
- Theoretisch kann ein Prozess viel Speicher spekulativ anfordern, jedoch nur eine Teilmenge aktiv verwenden (kleinere Arbeitsmenge / residente Speichernutzung).
- Durch die oben angegebene Beschränkung werden solche Prozesse abgebrochen (auch wenn sie unter Linux möglicherweise fehlerfrei ausgeführt werden, kann der Adressraum des virtuellen Speichers überlastet werden).
Neuere CGruppen
Bietet mehr Kontrolle, ist aber derzeit komplexer zu bedienen:
- Verbessert das ulimit-Angebot.
memory.max_usage_in_bytes
kann den physischen Speicher separat erfassen und begrenzen.
- Zwar sollte
ulimit -m
und / oder rss
in limits.conf
eine ähnliche Funktionalität bieten, aber das funktioniert seit Kernel Linux 2.4.30 nicht mehr!
- Need einige Kernel cgroup Fahnen in Bootloader aktivieren:
cgroup_enable=memory swapaccount=1
.
- Dies war bei Ubuntu 16.04 standardmäßig nicht der Fall.
- Wahrscheinlich aufgrund einiger Auswirkungen auf die Leistung durch zusätzlichen Aufwand für die Buchhaltung.
- cgroup / systemd-Zeug ist relativ neu und ändert sich ein wenig, daher impliziert der Upstream-Fluss, dass Linux-Distributoren es noch nicht einfach gemacht haben, es zu verwenden. Zwischen 14.04LTS und 16.04LTS wurde das User-Space-Tool zur Verwendung von cgroups geändert.
cgm
Jetzt scheint es sich um das offiziell unterstützte Userspace-Tool zu handeln.
- System-Unit-Dateien scheinen noch keine vordefinierten "Vendor / Distro" -Standards zu haben, um wichtige Dienste wie ssh zu priorisieren.
ZB um die aktuellen Einstellungen zu überprüfen:
$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...
ZB um den Speicher eines einzelnen Prozesses einzuschränken:
$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed
Um zu sehen, wie RAM als Hintergrundprozess gekaut und dann getötet wird, gehen Sie wie folgt vor:
$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
0.0 0.0 2876
102 0.2 44056
103 0.5 85024
103 1.0 166944
...
98.9 5.6 920552
99.1 4.3 718196
[1]+ Killed bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'
Beachten Sie das exponentielle Wachstum (Potenz 2) der Speicheranforderungen.
Hoffen wir, dass in Zukunft "Distributoren / Lieferanten" Prioritäten und Limits für C-Gruppen (über System-Einheiten) für wichtige Dinge wie SSH und den Grafikstapel vorkonfigurieren, sodass ihnen nie der Speicher ausgeht.