HeadlinesBriefing HeadlinesBriefing.com

Go GC-Pausen-Spitze: Swap-Auslagerung

Hacker News •
×

Ich schreibe das hier, damit Sie nicht wie ich fast mitten auf die Stirn hämmern, als ich beschlossen habe, Swap in der Produktion für die Pufferung von Speicherspitzen zu aktivieren. Ich hatte einen cgroup mit zwei Prozessen: ein Prozess ist ein Go-Prozess, der io. ReadAll aufruft und dann proto.

Unmarshal, wodurch ein Blob und anschließend eine Grafikstruktur erstellt wird (die als Scan vom Go-Allocator markiert ist). Der andere Prozess ist ein HTTP-Server, der meistens still bleibt. Jedes Mal, wenn der Collector läuft, liest er diese Scan-Spans, Zeiger für Zeiger, und entscheidet, was damit zu tun ist.

Also dachte ich: Gut, unter Speicherdruck wird der Kernel Seiten auf das Swap-Gerät auslagern, aber da die Auslagerung pro cgroup und nicht pro Prozess erfolgt, werden die Seiten beider Prozesse ausgelagert — also ist die Chance, dass dies zu einem traurigen Swap-In- und Swap-Out-Tanz zwischen Kernel und Garbage Collector wird, nur gering. Ich lag falsch. Während ich das experimentell testete, fand ich ein Problem, das mich hätte treffen können: Der Go-Garbage-Collector liest seine Metadaten (außerhalb des Heaps, in einem Bereich, der nicht freigegeben wird) während einer Stop-the-World-Pause, und diese Metadaten können im Swap sein.

Ich führte einen Simulationslauf auf einem Hetzner-Server mit Kernel 6.8 und aktiviertem MGLRU durch. Die mittlere Pause betrug etwa 51 µs. Mit den Metadaten auf dem NVMe, betrug die schlimmste Pause 40 ms.

Um zu überprüfen, wo diese 40 ms geblieben sind, schrieb ich ein kleines bpf-Skript, das Seitenfehler während der Welt gestoppt zählt. Das war der schlimmste Fall: 39902 µs, 228 Fehler währenddessen, 39013 µs in Fehlern. 39 dieser 40 ms wurden in 228 Seitenfehlern aufgewendet. Diese Fehler trugen innerhalb der GC-Buchführung statt.

Das ist ein potenzielles Fehlerszenario. Der Go-GC muss die Welt an zwei Stellen stoppen: wenn er eine Sweep-Terminierung durchführt, und wenn er eine Mark-Terminierung durchführt. Wir hatten 312 dieser Pausen in 30 Minuten.

Hier ist also, warum das passiert: Die Laufzeit weist diese Seiten zu. Sie werden nicht freigegeben, sonder.

Quelle: Hacker News · Zusammengefasst von HeadlinesBriefing