C Programm blieb unter ununterbrochenes Warten beim Durchführen von Scheiben -E/A auf Mac OS X Snow Leopard

StackOverflow https://stackoverflow.com/questions/2017283

  •  19-09-2019
  •  | 
  •  

Frage

Eine Hintergrundlinie: Ich bin der Entwickler von Redis, eine NoSQL -Datenbank. Eine der neuen Funktionen, die ich implementiere, ist der virtuelle Speicher, da Redis alle Daten im Speicher nimmt. Dank VM Redis kann es selten verwendete Objekte vom Speicher auf die Festplatte übertragen, es gibt eine Reihe von Gründen, warum dies viel besser funktioniert, als das Betriebssystem die Arbeit für uns tauschen zu lassen (Redis -Objekte werden aus vielen kleinen Objekten erstellt, die in nicht zusammenhängender Nutzung zugewiesen wurden Orte, wenn sie durch Redis serialisiert wurden, nehmen sie zehnmal weniger Platz im Vergleich zu den Speicherseiten, auf denen sie leben und so weiter).

Jetzt habe ich eine Alpha -Implementierung, die perfekt unter Linux funktioniert, aber nicht so gut auf Mac OS X Snow Leopard. Von Zeit zu Zeit, während Redis versucht, eine Seite vom Speicher auf die Festplatte zu verschieben, tritt der Redis -Prozess für Minuten in den unterbrechungsfreien Wartezustand ein. Ich konnte das nicht debuggen, aber dies geschieht entweder in einem Anruf fseeko() oder fwrite(). Nach Minuten kehrt der Anruf schließlich zurück und Redis funktioniert ohne Probleme weiter: kein Absturz.

Die Menge der übertragenen Daten ist sehr klein, so etwas wie 256 Bytes. Es sollte also keine sehr große Menge an E/A -durchgeführt sein.

Es gibt jedoch ein interessantes Detail über die Swap -Datei, die das Ziel des Schreibvorgangs ist. Es handelt fopen() und dann vergrößert mithilfe ftruncate(). Schließlich ist die Datei unlink()Ed, damit Redis weiterhin einen Verweis darauf nimmt, aber wir sind sicher, dass, wenn der Redis -Prozess das Betriebssystem beendet, die Swap -Datei wirklich befreien wird.

Ok, das ist alles, aber ich bin hier für weitere Details. Und übrigens können Sie sogar den tatsächlichen Code im Redis -Git finden, aber es ist nicht trivial, in fünf Minuten zu verstehen, da dies ein ziemlich komplexes System ist.

Vielen Dank für jede Hilfe.

War es hilfreich?

Lösung

Soweit ich es verstehe, hat HFS+ sehr schlechte Unterstützung für spärliche Dateien. Es kann also sein, dass Ihr Schreiben eine Dateiausdehnung auslöst, die einen großen Teil der Datei initialisiert/materialisiert.

Zum Beispiel weiß ich, dass MMAP eine neue große leere Datei und dann an einigen zufälligen Standorten eine sehr große Datei auf der Festplatte mit HFS+erzeugt. Es ist ziemlich ärgerlich, da MMAP- und Sparse -Dateien eine äußerst bequeme Art der Arbeit mit Daten sind, und praktisch alle anderen Plattform-/Dateisysteme da draußen verarbeiten dies anmutig.

Ist die Swap -Datei linear geschrieben? Das heißt, wir ersetzen entweder einen vorhandenen Block oder schreiben am Ende einen neuen Block und erhöhen einen freien Space -Zeiger? Wenn ja, würde es möglicherweise häufiger kleinere Aufrufe zur Erweiterung der Datei zu kürzeren Pausen führen.

Abgesehen davon bin ich gespannt, warum Redis VM MMAP nicht verwendet und dann nur Blöcke herum bewegen, um heiße Blöcke in heiße Seiten zu konzentrieren.

Andere Tipps

Antirez, ich bin mir nicht sicher, ob ich viel Hilfe machen werde, da meine Apple -Erfahrung auf die beschränkt ist Apple ][, aber ich werde es versuchen.

Das erste ist eine Frage. Ich hätte gedacht, dass für den virtuellen Speicher die Geschwindigkeit des Betriebs eine wichtigere Maßnahme als Speicherplatz wäre (insbesondere für eine NoSQL -DB, bei der die Geschwindigkeit der ganze Punkt ist, sonst verwenden Sie SQL, nein?). Aber wenn Ihre Swap-Datei 26G ist, vielleicht nicht :-)

Einige Dinge zu versuchen (wenn möglich).

  1. Versuchen Sie, das Problem tatsächlich mit der Suche oder Schreiben zu isolieren. Es fällt mir schwer zu glauben, dass ein Such so lange dauern könnte, da es im schlimmsten Fall eine Änderung des Pufferzeigers sein sollte. Trotzdem habe ich OSX nicht geschrieben, also kann ich nicht sicher sein.
  2. Stellen Sie die Größe der Swap -Datei ein, um festzustellen, ob dies das Problem verursacht.
  3. Erweitern Sie die SWAP-Datei jemals dynamisch (im Gegensatz zur Voranierung)? Wenn Sie dies tun, kann das das Problem verursachen.
  4. Schreiben Sie immer so niedrig in der Datei wie möglich? Es kann sein, dass das Erstellen einer 26G -Datei sie möglicherweise nicht mit Daten füllt, aber wenn Sie sie erstellen, müssen das Betriebssystem die Bytes möglicherweise vorher auf Null (falls vorhanden die Initialisierung verschieben).
  5. Was passiert, wenn Sie nur die gesamte Datei vorbereiten (an jedes Byte schreiben) und sie nicht zu verinkeln? Mit anderen Worten, lassen Sie die Datei dort zwischen den Läufen Ihres Programms (erstellen Sie sie, wenn sie natürlich noch nicht vorhanden ist). In Ihrem Startcode für Redis initialisieren Sie dann einfach die Datei (Zeiger und dergleichen). Dies kann Probleme wie die oben genannten Punkte 4 loswerden.
  6. Fragen Sie auch auf den verschiedenen BSD -Websites. Ich bin mir nicht sicher, wie sehr Apple unter den Cover verändert wurde, aber OSX ist nur BSD auf dem niedrigsten Niveau (Pax Ducks für Deckung).
  7. Fragen Sie auch auf den Apple -Websites (wenn Sie dies noch nicht getan haben).

Nun, das ist mein kleiner Beitrag, hoffentlich hilft es. Viel Glück mit Ihrem Projekt.

Haben Sie das Caching der Datei für Ihre Datei ausgeschaltet? dh fcntl (fd, f_global_nocache, 1)

Haben Sie versucht, mit DTRACE und / / / Instrumenten zu debuggen (Apples experimentelles Dtrace Front-End)?

Erkundung von Leopard mit DTRACE

Debugging Chrome unter OS X

Wie Linus einmal auf der GIT -Mailingliste sagte:

"Mir ist klar, dass OS X -Leute es schwer haben, es zu akzeptieren, aber OS X -Dateisysteme sind im Allgemeinen total und völlig Mist - noch mehr als Windows."

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top