Speicherverwaltung und Leistung

Juli 16

Bei Raima sind wir stets bemüht, die Leistung unserer Produkte zu steigern. Kürzlich habe ich mit einem unserer Kunden zusammengearbeitet, um ein Problem mit der Datenbankleistung zu lösen, und einige interessante Fakten entdeckt. Die Lösung eines Datenbankleistungsproblems erfordert möglicherweise mehr als nur das Hinzufügen von zusätzlichem Speicher, der mit höheren Geschwindigkeiten ausgeführt wird.

Methoden zur Optimierung

In der Datenverwaltung gibt es unzählige Möglichkeiten, die verschiedenen Vorgänge beim Speichern und Abrufen von Daten zu optimieren. Oft erfordern Optimierungen in einem Bereich Kompromisse in anderen. Ein häufiges Beispiel hierfür ist die Steigerung der Insert-Leistung durch Lockerung der ACID-Eigenschaften (Atomicity, Consistency, Isolation, Durability) bei der Transaktionsverarbeitung. Positiv zu vermerken ist, dass Sie die Anzahl der Einfügungen pro Sekunde drastisch erhöhen können. Der Nachteil ist, dass Sie jetzt ein höheres Risiko für Datenverlust haben.

While most attempts to increase performance need some sacrifices, I had always thought that there was one tried and true method to increase database performance across the board – throw hardware at the problem. However, this case has shown me that, in certain situations, adding resources can cut performance – perhaps even dramatically.

 

Details zur Speicherverwaltung

Der Kunde, auf den ich mich beziehe, hat eine Anwendung, die muss mit großen Bursts von Platteneinfügungen umgehen – perhaps 10 million new records inserted into the database at a time. The application requires persistent storage so Eine reine In-Memory-Datenbank reichte nicht aus Das Schreiben der Daten auf selbst die schnellsten Laufwerke erfüllte nicht immer die Leistungsanforderungen. Nach einigen Analysen mit unserem Engineering-Team wurde entschieden, dass die kurzfristige Lösung für das Problem darin bestand, die Anwendung auf einem Server auszuführen, der über genügend RAM verfügt, um selbst den größten erwarteten Insert-Burst in den Cache zu cachen, bevor die Transaktion festgeschrieben und auf die Festplatte geschrieben wird . Durch Erhöhen der Gesamtzahl der Cache-Seiten und der Größe jeder Seite könnten sie den größten erwarteten Transaktionsblock in etwa 40 GB RAM passen.

Mit diesem Wissen rüsteten sie einen Server mit 128 GB RAM und 16 Prozessorkernen aus. Als sie die Anwendung auf dem neuen Server ausführten, waren die Ergebnisse entschieden überwältigend. Anstatt eine Leistungssteigerung durch Nutzung der verfügbaren Ressourcen auf dem Computer zu erzielen, sank die Datenbankleistung tatsächlich. Tatsächlich dauerte der erste Testlauf so lange, dass sie den Prozess endgültig aufgaben und abbrachen.

Bei dem Versuch, dem Kunden zu helfen, zu verstehen, was vor sich geht, und um zu entscheiden, ob etwas in unserem oder ihrem Code enthalten ist, um die Situation zu verbessern, haben wir viele Tests durchgeführt.

 

Werden wir virtuell?

Das erste, was wir uns angesehen haben, war die Festplatten-E / A. Ein häufiger Fehler, den ich von unserem Kundenstamm sehe, besteht darin, mehr Datenbank-Cache-Seiten anzufordern, als durch die Menge des zur Verwendung verfügbaren physischen Speichers verarbeitet werden können. Dies kann zu extremen Leistungseinbußen führen, da das Betriebssystem den virtuellen Speicherprozess durch Ausschreiben auf die Festplatte startet. Während der Server in diesem Testfall speziell für die erwartete Auslastung der Anwendung entwickelt wurde, wollten wir sicherstellen, dass das Betriebssystem den Cache so handhabt, wie wir es erwartet hatten. Unsere Analyse ergab, dass nicht mehr E / A durchgeführt wurden, als von den von der Anwendung angeforderten Vorgängen erwartet wurde. Der verfügbare persistente Speicher wurde verwendet und der Prozess wurde nicht virtualisiert.

 

Können wir eine große Anzahl von Seiten bearbeiten?

Als nächstes haben wir uns angesehen, wie wir mit unserem internen Datenbank-Cache umgegangen sind. Im RDM-Server Der Datenbankcache wird verwendet, um geänderte Teile der Datenbank zu speichern, bis eine Transaktion festgeschrieben und die Änderung auf die Festplatte geschrieben wird. Eine Sorge war, dass unser Algorithmus zum Nachschlagen von Cache-Seiten nicht gut genug skaliert wurde, um die sehr vielen von dieser Anwendung angeforderten Cache-Seiten zu verarbeiten. Die Analyse hat gezeigt, dass der zum Nachschlagen von Seiten verwendete Hashing-Algorithmus bei einer großen Anzahl von Seiten genauso effizient ist wie bei einer moderateren Anzahl von Seiten, die in typischeren Szenarien verwendet werden.

 

Warum dauert das Herunterfahren so lange?

Die fortgesetzte Analyse ergab, dass die Verarbeitungseinsätze in den Testläufen in der erwarteten Zeitspanne voranschritten. Nach Abschluss der Einfügeverarbeitung dauerte das Herunterfahren der Anwendung jedoch Stunden (statt Sekunden). Profilerstellung und Debugging zeigten, dass die unerwartete Zeit nach Abschluss der Einfügungen damit verbracht wurde, den zugewiesenen Speicher für die Cache-Seiten freizugeben. Jede freie Operation betrug durchschnittlich etwa 13 Millisekunden. Mit über 2.621.440 zugewiesenen Cache-Seiten wurde berechnet, dass es über 5 Stunden dauern würde, bis der gesamte Speicher vollständig freigegeben ist. Zu Vergleichszwecken wurde auf einem Entwicklungscomputer mit nur 12 GB Cache (1.572.864 8K-Seiten) der gesamte Cache in 3,48 Sekunden (2 Mikrosekunden pro frei) freigegeben.

Um das Verhalten zu isolieren, wurde eine sehr einfache Anwendung erstellt, die Speicher zuweist und ihn dann in Blöcken unterschiedlicher Größe freigibt. Wir haben diesen Test durchgeführt, um verschiedene Speichergrößen für verschiedene Blockgrößen zuzuweisen, und die Ergebnisse aufgezeichnet.

 

Speicherzuordnung im Windows Server 2008 R2-Datencenter

Das Diagramm für die Speicherzuordnung sah wie erwartet aus. Die Speicherzuweisung nimmt bei Verwendung kleinerer Blockgrößen mehr Zeit in Anspruch, da mehr Zuweisungen erforderlich sind. Die Diagramme sind jedoch für die verschiedenen Blockgrößen alle linear. Beim Ausführen / Aufzeichnen der Ergebnisse der Speicherfreigabe haben wir eine ganz andere Geschichte gefunden.
 
Speicherzuordnung im Windows Server 2008 R2-Datencenter

 

Speicher frei im Windows Server 2008 R2-Datencenter

What isn’t very easy to see on the chart is that memory free operations are linear for 1K, 2K, 4K, and 8K block sizes. What is very easy to see is that when using a block size of 16K (actually any block larger than 16,343 bytes) freeing memory is not a linear operation, particularly if you are allocating more than 6GB. This behavior was causing the degradation in performance.
 
Speicherfrei im Windows Server 2008 R2-Datencenter

 

Gesundheitsüberprüfung

Wir haben beschlossen, den Test auf einem anderen Betriebssystem auszuführen, um unsere Ergebnisse zu bestätigen. Wir haben denselben Quellcode kompiliert und die Binärdateien auf derselben Hardware ausgeführt (Dual-Boot unter Linux anstelle von Windows) und sehr unterschiedliche Ergebnisse erzielt.

 

Speicherzuordnung unter Linux

Die Speicherzuweisung unter Linux hatte auch ein sehr schönes lineares Diagramm. Die Zuweisung von Speicher unter Linux dauerte etwas länger als unter Windows, aber die Ergebnisse waren ähnlich.
 
Speicherzuordnung unter Linux

 

Speicherfrei unter Linux

Free memory on Linux was vastly different from what we saw on Windows. The free operations on Linux were much faster and more predictable than what happened on the Windows platform. Linux’s implementation in this respect was more robust and provided better scalability.
 
Speicherfrei unter Linux

 

Was kann getan werden?

One of the most challenging things about “something that should be fast but isn’t” is figuring out how to make it fast as it should be. We were unable to find much information about this issue through web searches, but we did make one minor change to the test that proved to have good results. The original test allocated memory in the same order it was freed. By modifying the test to free memory in the reverse order, stack instead of a queue, performance was greatly improved on Windows.

 

Reverse Memory Free im Windows Server 2008 R2-Datencenter

Während das Diagramm nicht vollständig linear ist, kann der Speicher in Windows in umgekehrter Reihenfolge in Sekunden anstatt in Stunden fertiggestellt werden, wenn Seitengrößen von mehr als 16 KB verwendet werden.
 
Reverse Memory im Windows Server 2008 R2-Datencenter

 

Reverse Memory Free unter Linux

Linux verzeichnete auch eine Leistungssteigerung durch freien Speicher in umgekehrter Reihenfolge wie die Zuweisung. Die Ergebnisse waren immer noch linear.
 
Reverse Memory Free unter Linux

Wie Sie den Diagrammen entnehmen können, führte die Umstellung auf die Freigabe des Speichers in umgekehrter Reihenfolge zu einer dramatischen Leistungssteigerung. Obwohl es immer noch nicht annähernd die unter Linux beobachtete Datenbankleistung ist, ist es zumindest tolerierbar. Dies war eine perfekte kurzfristige Lösung für unsere Kunden, die unter Windows laufen, aber wir sind immer noch der Meinung, dass es schneller laufen sollte.

 

Können wir Malloc / Free durch etwas Besseres ersetzen?

Nachdem wir mit unserem Kunden bestätigt hatten, dass die Änderung der freien Daten in umgekehrter Reihenfolge die Ausführung seiner Anwendung ermöglichte, entschieden wir uns, einige der von Microsoft bereitgestellten alternativen Malloc-Implementierungen zu prüfen. Es gibt verschiedene Alternativen, aber viele davon sind Legacy-Implementierungen aus der 16-Bit-Ära. Die VirtualAlloc / VirtualFree-Funktionen scheinen die einzig praktikable Alternative zu malloc / free zu sein. Diese Funktionen des virtuellen Speichers bieten Funktionen, die über das hinausgehen, was mit dem Basis-Malloc / Free verfügbar ist. Mit den richtigen Optionen können Sie diese Funktionen jedoch als Ersatz für Malloc / Free verwenden.

Wir haben unseren Testcode geändert, um den Aufruf von malloc durch Folgendes zu ersetzen:

p = (MEM_CHUNK *) VirtualAlloc (NULL, chunk_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

Anrufe zu frei wurden ersetzt durch:

VirtualFree (p, 0, MEM_RELEASE);

We then ran the test application to allocate 24GB of memory in 1K chunks and the results were…not very good.

Der Computer, auf dem wir unsere Tests ausgeführt haben, verfügt über 64 GB Arbeitsspeicher, und die größte Speichermenge, die wir in einem Testlauf erwartet hatten, betrug 24 GB. Nachdem unser Testlauf jedoch in mehreren Stunden nicht abgeschlossen war, stellten wir fest, dass der Leistungsmonitor zeigte, dass in unserem Testprozess alle 64 GB Speicher verwendet wurden. Dies lässt sich leicht durch sorgfältiges Lesen der VirtualAlloc-Dokumentation erklären. Die kleinste Zuordnungsgröße von VirtualAlloc ist eine einzelne Speicherseite. Auf unserem Computer hatte die Speicherseite eine Größe von 4 KB, sodass alle unsere 1 KB-Speicheranforderungen tatsächlich 4 KB reservierten. An den oberen Grenzen unseres Tests würden wir 96 GB Speicher auf einem System anfordern, auf dem nur 64 GB verfügbar waren. Einige Testmodifikationen zum Entfernen von Testläufen für Seitengrößen unter 4 KB haben uns die erhofften Ergebnisse gebracht.

 

VirtualAlloc On Windows Server 2008 R2-Datencenter

VirtualAlloc lief bei kleineren Seitengrößen nicht so gut wie Malloc, bei Seitengrößen über 16 KB jedoch nicht so gut wie Malloc.
 
VirtualAlloc On Windows Server 2008 R2-Datencenter

 

VirtualFree Unter Windows Server 2008 R2 Datacenter

VirtualFree übertraf die Leistung auf ganzer Linie, insbesondere bei Seitengrößen von mehr als 16 KB.
 
VirtualFree Unter Windows Server 2008 R2 Datacenter

 

Reverse VirtualFree unter Windows Server 2008 R2 Datacenter

VirtualAlloc hatte eine ähnliche Leistung, unabhängig davon, ob der Auftragsspeicher freigegeben wurde. Bei Seitengrößen über 8 KB übertraf es malloc.
 
Reverse VirtualFree unter Windows Server 2008 R2 Datacenter

Das Tolle an den VirtualAlloc / VirtualFree-Ergebnissen ist, dass die Datenbankleistung unabhängig von der Reihenfolge, in der der Speicher freigegeben wird, konstant bleibt. Durch Ändern unseres Codes zur Verwendung von VirtualAlloc für die Zuweisung von Puffern größer als 16 KB können wir die Leistung und Vorhersagbarkeit auf Windows-basierten Systemen verbessern.

 

Fazit

Wenn Sie eine Anwendung haben, die in relativ kleinen Blöcken viel Speicherzuweisung verwendet, sollten Sie Alternativen zu malloc / free auf Windows-basierten Systemen in Betracht ziehen. VirtualAlloc / VirtualFree eignen sich zwar nicht zum Zuweisen von weniger als einer Speicherseite, können jedoch die Datenbankleistung und Vorhersagbarkeit erheblich verbessern, wenn Speicher in Vielfachen einer einzelnen Seite zugewiesen werden.

Es ist immer schön, wenn Dinge, die schnell sein sollten, tatsächlich sind.

Get notified about new RDM updates

Be the first to know about new Raima Database Manager updates when they go live, use cases, industry trends and more.