Gibt es eine Möglichkeit, Speicherfragmentierung unter Linux zu erkennen? Dies liegt daran, dass ich auf einigen Servern mit langer Laufzeit einen Leistungsabfall festgestellt habe und erst nach einem Neustart eine bessere Leistung sehe. Ich bemerkte es mehr, wenn ich Linux-Unterstützung für große Seiten verwendete. Sind große Seiten in Linux anfälliger für Fragmentierung?
Ich habe mir insbesondere / proc / buddyinfo angesehen. Ich möchte wissen, ob es bessere Möglichkeiten gibt (nicht nur CLI-Befehle an sich, ein Programm oder ein theoretischer Hintergrund), um es zu betrachten.
linux
linux-kernel
Raghu
quelle
quelle
vmstat
auf dem Gebiet gebenso
?vmstat
ist eine übliche Benutzererfahrung. Wenn Sie ein Programm schreiben würden, um dasselbe zu tun, wäre es anders. Wenn Sie beabsichtigen, bash zu verwenden, um diese Informationen zu sammeln, bearbeiten Sie Ihre Frage, es wird nicht geschlossen :)Antworten:
Ich antworte auf den Linux- Tag. Meine Antwort bezieht sich nur auf Linux .
Ja, große Seiten sind anfälliger für Fragmentierung. Es gibt zwei Speicheransichten: die, die Ihr Prozess erhält (virtuell) und die, die der Kernel verwaltet (real). Je größer eine Seite ist, desto schwieriger wird es, ihre Nachbarn zu gruppieren (und bei ihnen zu bleiben), insbesondere wenn Ihr Dienst auf einem System ausgeführt wird, das auch andere unterstützen muss, die standardmäßig viel mehr Speicher zuweisen und schreiben als sie tatsächlich am Ende mit.
Die Zuordnung des Kernels zu (echten) zugewiesenen Adressen ist privat. Es gibt einen sehr guten Grund, warum Userspace sie so sieht, wie der Kernel sie präsentiert, weil der Kernel in der Lage sein muss, ein Overcommit durchzuführen, ohne Userspace zu verwirren. Ihr Prozess wird einen schönen, zusammenhängenden „Disneyfied“ Adressraum , in dem zu arbeiten, nicht bewusst, was der Kern tatsächlich tut hinter den Kulissen mit diesem Speicher.
Der Grund , warum Sie verminderte Leistung sehen auf lange laufenden Server ist sehr wahrscheinlich , weil zugeordnete Blöcke, die nicht explizit gesperrt (zB
mlock()
/mlockall()
oderposix_madvise()
) und eine Zeit lang nicht verändert wurden ausgelagert , was bedeutet , dass Sie da Kufen auf der Festplatte , wenn es zum Lesen Sie. Wenn Sie dieses Verhalten ändern, wird Ihr Prozess zu einem schlechten Nachbarn . Aus diesem Grund stellen viele Benutzer ihr RDBMS auf einen völlig anderen Server als web / php / python / ruby / whatever. Die einzige Möglichkeit, dies zu beheben, besteht darin, die Konkurrenz um zusammenhängende Blöcke zu verringern.Fragmentierung ist (in den meisten Fällen) nur dann wirklich bemerkbar, wenn sich Seite A im Speicher befindet und Seite B zum Auswechseln verschoben wurde. Ein Neustart Ihres Dienstes scheint dies natürlich zu "heilen", aber nur, weil der Kernel noch keine Gelegenheit hatte, den Prozess "(jetzt) neu zugewiesene Blöcke im Rahmen seiner Überlastungsquote" auszublenden.
Tatsächlich wird ein Neustart (sagen wir mal) von 'Apache' unter hoher Last wahrscheinlich Blöcke, die anderen Diensten gehören, direkt auf die Festplatte senden. Also ja, 'Apache' würde sich für kurze Zeit verbessern, aber 'MySQL' könnte darunter leiden. Zumindest bis der Kernel sie gleichermaßen leiden lässt, wenn es einfach an genügend physischem Speicher mangelt.
Fügen Sie mehr Speicher hinzu oder teilen Sie anspruchsvolle
malloc()
Verbraucher auf :) Es ist nicht nur eine Fragmentierung, die Sie sich ansehen müssen.Versuchen Sie
vmstat
sich einen Überblick darüber zu verschaffen, was wo tatsächlich gespeichert wird.quelle
Kernel
Um den aktuellen Fragmentierungsindex zu erhalten, verwenden Sie:
Führen Sie zum Defragmentieren des Kernelspeichers Folgendes aus:
Außerdem versuchen Sie, Transparent Huge Pages (auch bekannt als THP) zu deaktivieren und / oder Swap zu deaktivieren (oder zu verringern
swappiness
).Benutzerraum
Um die Fragmentierung des Benutzerbereichs zu verringern, sollten Sie beispielsweise einen anderen Allokator ausprobieren
jemalloc
(er verfügt über hervorragende Funktionen zur Selbstüberwachung , die Ihnen einen Einblick in die interne Fragmentierung des Allokators geben).Sie können zu benutzerdefiniertem malloc wechseln, indem Sie Ihr Programm damit neu kompilieren oder indem Sie Ihr Programm mit den
LD_PRELOAD
folgendenLD_PRELOAD=${JEMALLOC_PATH}/lib/libjemalloc.so.1 app
Befehlen ausführen : (Achten Sie auf die Interaktionen zwischen THP und Speicherzuordnern. )Sie möchten wahrscheinlich mehrere Instanzen Ihres Dienstes ausführen, eine für jeden NUMA-Knoten, und diese mithilfe von binden
numactl
.quelle
mmap
) sind auf verschiedenen Kerneln (z. B. Linux vs FreeBSD) oder sogar verschiedenen Versionen desselben Betriebssystems (2.6.32 vs 3.2 vs 3.10) unterschiedlich implementiert. "Es erlaubt modifizierte Seiten [. ..] aus dem physischen [...] Speicher entfernt werden "- das wird Speicherlecks verbergen. "Behandeln Sie Fälle, in denen viel mehr Speicher reserviert ist als verwendet wird" - langsames System ist viel schlimmer als ausgefallenes System, daher ist "vernünftig" fraglich.Die Verwendung großer Seiten sollte unter Linux keine zusätzliche Speicherfragmentierung verursachen. Die Linux-Unterstützung für große Seiten gilt nur für gemeinsam genutzten Speicher (über shmget oder mmap), und alle verwendeten großen Seiten müssen von einem Systemadministrator speziell angefordert und vorab zugewiesen werden. Sobald sie sich im Speicher befinden, werden sie dort festgehalten und nicht mehr ausgetauscht. Die Herausforderung beim Auslagern großer Seiten angesichts der Speicherfragmentierung besteht genau darin, warum sie im Speicher festgehalten werden (bei der Zuweisung einer 2-MB-großen Seite muss der Kernel 512 zusammenhängende freie 4-KB-Seiten finden, die möglicherweise gar nicht vorhanden sind).
Linux-Dokumentation auf riesigen Seiten: http://lwn.net/Articles/375098/
Es gibt einen Umstand, in dem die Speicherfragmentierung zu einer langsamen Zuweisung großer Seiten führen kann (nicht jedoch, wenn große Seiten eine Speicherfragmentierung verursachen ). Dies ist der Fall , wenn Ihr System so konfiguriert ist, dass der Pool großer Seiten vergrößert wird, wenn eine Anwendung dies anfordert. Wenn / proc / sys / vm / nr_overcommit_hugepages größer als / proc / sys / vm / nr_hugepages ist, kann dies passieren.
quelle
Es gibt
/proc/buddyinfo
was sehr nützlich ist. Es ist nützlicher mit einem schönen Ausgabeformat, wie dieses Python-Skript tun kann:https://gist.github.com/labeneator/9574294
Für große Seiten möchten Sie einige freie Fragmente in der Größe 2097152 (2 MB) oder größer. Bei transparenten großen Seiten wird sie automatisch komprimiert, wenn der Kernel nach einer bestimmten Anzahl von Seiten gefragt wird. Wenn Sie jedoch sehen möchten, wie viele Sie erhalten können, führen Sie als Root Folgendes aus:
Ja, große Seiten verursachen große Probleme bei der Fragmentierung. Entweder können Sie keine großen Seiten abrufen, oder der Kernel verbringt viel zusätzliche Zeit mit dem Abrufen von Seiten.
Ich habe eine Lösung, die für mich funktioniert. Ich benutze es auf ein paar Servern und meinem Laptop. Es funktioniert hervorragend für virtuelle Maschinen.
Fügen Sie die
kernelcore=4G
Option Ihrer Linux-Kernel-Befehlszeile hinzu. Auf meinem Server verwende ich 8G. Gehen Sie mit der Nummer vorsichtig um, da Ihr Kernel sonst nichts außerhalb dieses Speichers zuordnen kann. Server, die viele Socket-Puffer benötigen oder Festplattenschreibvorgänge auf Hunderte von Laufwerken streamen, werden diese Einschränkung nicht mögen. Jegliche Speicherzuordnung, die für eine Platte oder einen DMA "fixiert" werden muss, fällt in diese Kategorie.Der gesamte andere Speicher wird dann "verschiebbar", was bedeutet, dass er für eine enorme Seitenzuordnung zu netten Stücken komprimiert werden kann. Jetzt können transparente, große Seiten wirklich abheben und so arbeiten, wie sie sollen. Wann immer der Kernel mehr 2M Seiten benötigt, kann er 4K Seiten einfach woanders neu zuordnen.
Und ich bin mir nicht ganz sicher, wie dies mit Zero-Copy Direct IO zusammenwirkt. Der Speicher in der "beweglichen Zone" sollte nicht fixiert werden, aber eine direkte E / A-Anforderung würde genau das für DMA tun. Es könnte es kopieren. Es könnte sowieso in der beweglichen Zone stecken. In beiden Fällen ist es wahrscheinlich nicht genau das, was Sie wollten.
quelle