Nachtrag: Post kann man wohl leider ignorieren. Ist wohl doch schlecht umsetzbar ohne eine Anpassung des qemu-guest-agent.
Moin,
Hat sich mal wer daran versucht ein dynamisches Ballooning umzusetzen?
Das Hauptproblem beim Ballooning finde ich ist, dass da PVE halt stupide den RAM der VMs senkt ohne Rücksicht darauf zu nehmen, wieviel von ihrem RAM die Gäste denn überhaupt nutzen.
Sagen wir ich habe 32GB RAM auf dem Host und 4 identische VMs mit aktiviertem Ballooning mit je "Min RAM = 3GB" und "Max RAM = 6GB". Alle VMs haben das selbe Share Ratio von 1000.
Bis 80% RAM-Auslastung des Hosts macht Ballooning ja überhaupt nichts und alle VMs können bis 6 GB RAM nutzen. Sobald dann der RAM des Hosts die 80% überschreitet setzt Ballooning ein und drosselt langsam den RAM der VMs in z.B. 100 MB Schritten von 6 GB bis runter zu 3 GB. Das macht das Ballooning so lange bis entweder das gesetze Minimum von 3 GB erreicht ist oder bis die RAM-Auslastung des Hostes wieder unter 80% fällt.
Dem Host ist es aber egal ob eine VM den RAM braucht oder nicht, er drosselt einfach immer weiter und die VM muss halt irgendwie dafür sorgen, dass sie mit dem RAM auskommt, welcher der Host ihr noch lässt. Im Idealfall hat die VM da freien RAM, dann muss die VM nichts machen. Hat die VM nicht genug freien RAM oder noch viel "available" RAM, dann ist das auch nicht kritisch, weil die VM einfach schnell mal den Page File Cache wegwirft der ja nicht zwingend benötigt wird. Ist dann höchstens etwas nervig, weil das dann stoßweise zu zu mehr Auslastung der VM führt, weil die VM ja unter druck gesetzt wird und so schnell wie möglich RAM freischaufeln muss. Kritisch wird es aber wenn der Host der VM RAM abzieht aber die VM keinen freien RAM oder "available" RAM mehr besitzt. Dann muss die VM den OOM Killer starten und der killt dann in der VM Prozesse, die man eigentlich nicht beendet haben möchte.
Also mal als Beispiel:
RAM bevor das Ballooning einsetzt:
Host: 25,6 GB von 32 GB benutzt = 80% Auslastung
Host ist nicht über 80% RAM-Auslastung also ist Ballooning inaktiv und alle VMs dürfen volle 6 GB RAM nutzen.
Nun braucht der Host plötzlich 3,2 GB mehr RAM und die RAM-Auslastung springt auf 90% weil der Host 28,8 GB von 32 GB benutzt. Ballooning setzt ein und versucht wieder den Host RAM auf unter 80% Auslastung zu drücken, weshalb also 3,2 GB RAM von den VMs abgezogen werden müssen. Dies geschieß gleichmäßig, weil alle VMs das selbe Share Ratio haben. Es wird also jeder VM 0,8 GB RAM abgezogen:
Soweit alles noch unkritisch. VM A, B und D hatte alle genug "free" RAM und mussten nicht einmal den Cache leeren. VM C ist aber schon echt am Limit und musste den kompletten Cache leeren.
Nun braucht der Host weitere 3,2 GB und die RAM-Auslastung steigt auf 100%. Ballooning muss sich ebenfalls weitere 0,8 GB von jeder VMs zurückholen:
VM A musste nur etwas Cache leeren. VM C und D hatten genug freien RAM. VM C hat jetzt aber ein Problem, da nur noch 0,2 GB RAM "available" waren also nirgends mehr freier RAM hergezaubert werden konnte. Es mussten also durch den OOM Killer genug Prozesse gekillt werden, dass da zusätzlich 0,6 GB RAM frei wurden. Was genau an Prozessen gekillt wird entscheidet der Gast. Mit Pech ist es eine wichtige Anwendung auf die man angewiesen ist oder ein wichtiger Systemprozess und die ganze VM stürzt ab. Das ist super ärgerlich, denn gleichzeitig verschwenden die anderen VMs weiterhin RAM. VM A, B und D haben alle weiterhin noch 2,4 oder 3,4 GB RAM zur Verfügung. Anstatt VM C zu zwingen Prozesse zu killen hätte man lieber etwas weniger RAM von VM C weggenommen und dafür etwas mehr von anderen VMs.
Der Host müsste also bei den Gästen nachfragen, wieviel "available" RAM diese haben und dann entscheiden welche VM den RAM am meisten/wenigstens braucht und die RAM-Vergabe dann dynamisch regeln. Ohne beim Gast nachzufragen kann er dies nicht sehen, da er ja nur den phyischen RAM-Verbrauch sieht der ja aber keinen Rückschluss darauf gibt, ob der VM wirklich der RAM ausgeht, da ja für Caching benutzter RAM nicht wirklich von der VM benötigt wird und jederzeit freigemacht werden kann, aber eben doch phyisch RAM belegt. Es können also z.B. 2 VMs beide 90% ihres RAMs benutzen. DAs heißt aber nicht das auch beiden der RAM ausgeht. Vielleicht nutzt die eine nur 10% für Prozesse und 80% für Caching und die andere 80% für Prozesse und nur 10% für Caching. Für den Host sieht das beides gleich aus, aber der einen VM könnt man problemlos ohne NAchteil 50% ihres RAMs wegnehmen während die andere VM dann viele Prozesse killen müsste oder gar crashen würde.
Nach meinen Nachforschungen wurde schon einmal an so etwas direkt von KVM aus gearbeitet, das wurde dann aber verworfen, weil das alles viel zu anfällig und kompliziert umzusetzen war mit einer dynamischen RAM-Verteilung.
Dann ist mir aber eingefallen, dass man das doch mal selbst versuchen könnte.
1.) Im Gegensatz zum "max RAM" kann man den "min RAM" einer VM während ihrer Laufzeit ändern und muss die VM nicht runterfahren, damit der neue Wert übernommen wird. Hier sollte man also dynamisch den "min RAM" je nach Bedarf nach oben oder unten regeln können. Befehl für die CLI wäre
2.) Über den qemu-guest-agent kann man vom Host aus abfragen, wieviel RAM eine VM benutzt und wie sie ihn benutzt. Über die CLI läuft das so. Erst muss man über
Hier bedeuten die Werte wohl:
actual=16324 -> auf wieviel MB RAM ballooning die VM gerade gedrosselt hat.
max_mem=16384 -> wieviel MB RAM die VM theoretisch maximal nutzen könnte, wenn da Ballooning nicht gedrosselt hätte.
total_mem=15982 -> wieviel MB RAM das OS effektiv nutzen kann?
free_mem=10239 -> wieviel MB RAM das OS "available" hat. Also die Summe aus free+cached.
last_update=1632407624 -> timestamp des letzten Updates der Daten (Daten werden wohl im Sekundentakt aktualisiert)
Wenn man dann ein
Ich habe leider keine Ahnung wie man das als ein One-Liner hinbekommt. Oder gar besser asynchron das man in der Sitzung bleiben kann und diese nicht ständig neu starten und verlassen muss. Weiß jemand ob man da irgendwas pipen kann oder so, dass man nur einen Befehl eingeben muss und dann die Rückmeldung angezeigt bekommt? So etwas wie
Moin,
Hat sich mal wer daran versucht ein dynamisches Ballooning umzusetzen?
Das Hauptproblem beim Ballooning finde ich ist, dass da PVE halt stupide den RAM der VMs senkt ohne Rücksicht darauf zu nehmen, wieviel von ihrem RAM die Gäste denn überhaupt nutzen.
Sagen wir ich habe 32GB RAM auf dem Host und 4 identische VMs mit aktiviertem Ballooning mit je "Min RAM = 3GB" und "Max RAM = 6GB". Alle VMs haben das selbe Share Ratio von 1000.
Bis 80% RAM-Auslastung des Hosts macht Ballooning ja überhaupt nichts und alle VMs können bis 6 GB RAM nutzen. Sobald dann der RAM des Hosts die 80% überschreitet setzt Ballooning ein und drosselt langsam den RAM der VMs in z.B. 100 MB Schritten von 6 GB bis runter zu 3 GB. Das macht das Ballooning so lange bis entweder das gesetze Minimum von 3 GB erreicht ist oder bis die RAM-Auslastung des Hostes wieder unter 80% fällt.
Dem Host ist es aber egal ob eine VM den RAM braucht oder nicht, er drosselt einfach immer weiter und die VM muss halt irgendwie dafür sorgen, dass sie mit dem RAM auskommt, welcher der Host ihr noch lässt. Im Idealfall hat die VM da freien RAM, dann muss die VM nichts machen. Hat die VM nicht genug freien RAM oder noch viel "available" RAM, dann ist das auch nicht kritisch, weil die VM einfach schnell mal den Page File Cache wegwirft der ja nicht zwingend benötigt wird. Ist dann höchstens etwas nervig, weil das dann stoßweise zu zu mehr Auslastung der VM führt, weil die VM ja unter druck gesetzt wird und so schnell wie möglich RAM freischaufeln muss. Kritisch wird es aber wenn der Host der VM RAM abzieht aber die VM keinen freien RAM oder "available" RAM mehr besitzt. Dann muss die VM den OOM Killer starten und der killt dann in der VM Prozesse, die man eigentlich nicht beendet haben möchte.
Also mal als Beispiel:
RAM bevor das Ballooning einsetzt:
Host: 25,6 GB von 32 GB benutzt = 80% Auslastung
used RAM | free RAM | cache RAM | available RAM (free+cache) | RAM gedrosselt auf | ballooning (Min RAM Wert) | Share Ratio | |
VM A | 2 GB | 2 GB | 2 GB | 4 GB | 6 GB | 3 GB | 1000 |
VM B | 2 GB | 3,5 GB | 0,5 GB | 4 GB | 6 GB | 3 GB | 1000 |
VM C | 5 GB | 0,5 GB | 0,5 GB | 1 GB | 6 GB | 3 GB | 1000 |
VM D | 1 GB | 5 GB | 0 GB | 5 GB | 6 GB | 3 GB | 1000 |
Nun braucht der Host plötzlich 3,2 GB mehr RAM und die RAM-Auslastung springt auf 90% weil der Host 28,8 GB von 32 GB benutzt. Ballooning setzt ein und versucht wieder den Host RAM auf unter 80% Auslastung zu drücken, weshalb also 3,2 GB RAM von den VMs abgezogen werden müssen. Dies geschieß gleichmäßig, weil alle VMs das selbe Share Ratio haben. Es wird also jeder VM 0,8 GB RAM abgezogen:
used RAM | free RAM | cache RAM | available RAM (free+cache) | RAM gedrosselt auf | ballooning (Min RAM Wert) | Share Ratio | |
VM A | 2 GB | 2 - 0,8 = 1,2 GB | 2 GB | 3,2 GB | 5,2 GB | 3 GB | 1000 |
VM B | 2 GB | 3,5 - 0,8 = 2,7 GB | 0,5 GB | 3,2 GB | 5,2 GB | 3 GB | 1000 |
VM C | 5 GB | 0,5 - 0,3 = 0,2 GB | 0,5 - 0,5 = 0 GB | 0,2 GB | 5,2 GB | 3 GB | 1000 |
VM D | 1 GB | 5 - 0,8 = 4,2 GB | 0 GB | 4,2 GB | 5,2 GB | 3 GB | 1000 |
Nun braucht der Host weitere 3,2 GB und die RAM-Auslastung steigt auf 100%. Ballooning muss sich ebenfalls weitere 0,8 GB von jeder VMs zurückholen:
used RAM | free RAM | cache RAM | available RAM (free+cache) | RAM gedrosselt auf | ballooning (Min RAM Wert) | Share Ratio | |
VM A | 2 GB | 1,2 - 0,7 = 0,5 GB | 2 - 0,1 = 1,9 GB | 2,4 GB | 4,4 GB | 3 GB | 1000 |
VM B | 2 GB | 2,7 - 0,8 = 1,9 GB | 0,5 GB | 2,4 GB | 4,4 GB | 3 GB | 1000 |
VM C | 5 - 0,6 = 4,4 GB | 0,2 - 0,2 = 0GB | 0 GB | 0,0 GB | 4,4 GB | 3 GB | 1000 |
VM D | 1 GB | 4,2 - 0,8 = 3,4 GB | 0 GB | 3,4 GB | 4,4 GB | 3 GB | 1000 |
Der Host müsste also bei den Gästen nachfragen, wieviel "available" RAM diese haben und dann entscheiden welche VM den RAM am meisten/wenigstens braucht und die RAM-Vergabe dann dynamisch regeln. Ohne beim Gast nachzufragen kann er dies nicht sehen, da er ja nur den phyischen RAM-Verbrauch sieht der ja aber keinen Rückschluss darauf gibt, ob der VM wirklich der RAM ausgeht, da ja für Caching benutzter RAM nicht wirklich von der VM benötigt wird und jederzeit freigemacht werden kann, aber eben doch phyisch RAM belegt. Es können also z.B. 2 VMs beide 90% ihres RAMs benutzen. DAs heißt aber nicht das auch beiden der RAM ausgeht. Vielleicht nutzt die eine nur 10% für Prozesse und 80% für Caching und die andere 80% für Prozesse und nur 10% für Caching. Für den Host sieht das beides gleich aus, aber der einen VM könnt man problemlos ohne NAchteil 50% ihres RAMs wegnehmen während die andere VM dann viele Prozesse killen müsste oder gar crashen würde.
Nach meinen Nachforschungen wurde schon einmal an so etwas direkt von KVM aus gearbeitet, das wurde dann aber verworfen, weil das alles viel zu anfällig und kompliziert umzusetzen war mit einer dynamischen RAM-Verteilung.
Dann ist mir aber eingefallen, dass man das doch mal selbst versuchen könnte.
1.) Im Gegensatz zum "max RAM" kann man den "min RAM" einer VM während ihrer Laufzeit ändern und muss die VM nicht runterfahren, damit der neue Wert übernommen wird. Hier sollte man also dynamisch den "min RAM" je nach Bedarf nach oben oder unten regeln können. Befehl für die CLI wäre
qm set <vmid>--balloon <TargetRAMSizeInMB>
also z.B. qm set 100 --balloon 7000
wenn man KVM sagen möchte, dass das Ballooning den RAM für die VM 100 bis runter auf 7GB drosseln darf.2.) Über den qemu-guest-agent kann man vom Host aus abfragen, wieviel RAM eine VM benutzt und wie sie ihn benutzt. Über die CLI läuft das so. Erst muss man über
qm monitor <VMID>
eine qm Sitzung starten. Dort kann man dann info balloon
eingeben und erhält Infos zur RAM-Nutzung. Bei meinem Debian sieht die Rückmeldung z.B. so aus:
Code:
balloon: actual=16324 max_mem=16384 total_mem=15982 free_mem=10239 mem_swapped_in=0 mem_swapped_out=0 major_page_faults=1694 minor_page_faults=5590676 last_update=1632407624
actual=16324 -> auf wieviel MB RAM ballooning die VM gerade gedrosselt hat.
max_mem=16384 -> wieviel MB RAM die VM theoretisch maximal nutzen könnte, wenn da Ballooning nicht gedrosselt hätte.
total_mem=15982 -> wieviel MB RAM das OS effektiv nutzen kann?
free_mem=10239 -> wieviel MB RAM das OS "available" hat. Also die Summe aus free+cached.
last_update=1632407624 -> timestamp des letzten Updates der Daten (Daten werden wohl im Sekundentakt aktualisiert)
Wenn man dann ein
q
sendet verlässt man die Sitzung wieder und kommt in die Konsole.Ich habe leider keine Ahnung wie man das als ein One-Liner hinbekommt. Oder gar besser asynchron das man in der Sitzung bleiben kann und diese nicht ständig neu starten und verlassen muss. Weiß jemand ob man da irgendwas pipen kann oder so, dass man nur einen Befehl eingeben muss und dann die Rückmeldung angezeigt bekommt? So etwas wie
qm monitor 111; echo "info ballon"; echo "q"
geht leider nicht.
Last edited: