Plattformunabhängige Dateisperren?
-
21-08-2019 - |
Frage
Ich bin mit einer sehr rechenintensive wissenschaftliche Arbeit, die jeder jetzt Ergebnisse ausspuckt und dann. Der Job ist im Grunde nur die gleiche Sache eine ganze Reihe von Zeiten zu simulieren, so dass es auf mehrere Rechner aufgeteilt, die unterschiedliche Betriebssysteme verwenden. Ich mag die Ausgabe von all diesen Fällen auf die gleiche Datei leiten, da alle Computer das gleiche Dateisystem über NFS / Samba sehen. Hier sind die Einschränkungen:
- Müssen sicher gleichzeitige Appends ermöglichen. blockieren muß, wenn eine andere Instanz auf einem anderen Computer derzeit auf die Datei angehängt wird.
- Performance hat nicht count. I / O für jede Instanz ist nur wenige Bytes pro Minute.
- Einfachheit zählt. Der ganze Sinn dieser (neben reiner Neugier) ist, so kann ich jede Instanz in eine andere Datei schreiben anhalten zu müssen und diese Dateien manuell zusammen zu verschmelzen.
- darf nicht auf die Details des Dateisystems abhängen. Muss mit einem unbekannten Dateisystem auf einem NFS oder Samba Mount arbeiten.
Die Sprache Ich verwende D ist, in dem Fall, dass es ankommt. Ich habe sieht, gibt es nichts in dem Standard-lib, dass dies zu tun scheint. Sowohl D-spezifische und allgemeine, sprachunabhängig Antworten sind völlig akzeptabel und geschätzt.
Lösung
über NFS stellen Sie einige Probleme mit Client-seitiges Caching und veralteten Daten. Ich habe ein Betriebssystem unabhängige Schlossmodul geschrieben, bevor sie über NFS zu arbeiten. Die einfache Idee, eine [Datenfile] .lock Datei funktioniert nicht gut über NFS. Die Grundidee um es zu arbeiten, ist eine Sperrdatei [Datenfile] .lock zu schaffen, die, falls vorhanden, bedeutet Datei nicht gesperrt wird und ein Verfahren, das eine Sperre benennt die Datei in einen anderen Namen wie [Datenfile] .lock erwerben will. [ Hostname]. [pid]. Die Umbenennungs ist eine atomare genug Operation, die gut genug, um über NFS arbeitet Exklusivität des Schlosses zu gewährleisten. Der Rest ist im Grunde ein Bündel von fail safe, Schleifen, Fehlerprüfung und Verriegelungs Retrieval falls der Prozess stirbt, bevor die Verriegelung gelöst und die Umbenennung die Sperrdatei zurück auf [Daten-Datei] .lock
Andere Tipps
Die klassische Lösung ist eine Lock-Datei zu verwenden, oder genauer gesagt ein Schloss-Verzeichnis. Auf allen gängigen Betriebssystemen Erstellen eines Verzeichnisses eine atomare Operation ist, so dass die Routine ist:
- versuchen, eine Sperre Verzeichnis mit einem festen Namen in einem festen Standort erstellen
- , wenn der ausgefallene create, warten Sie eine Sekunde oder so und versuchen Sie es erneut - wiederholen, bis Erfolg
- schreiben Sie Ihre Daten in die reale Datendatei
- löschen Sie das Verzeichnis sperren
Dies wurde durch Anwendungen wie CVS seit vielen Jahren in vielen Plattformen verwendet. Das einzige Problem tritt in den seltenen Fällen, wenn Ihre Anwendung abstürzt, während das Schreiben und vor dem Schloss zu entfernen.
Warum nicht nur einen einfachen Server aufzubauen, die zwischen der Datei und den anderen Computern sitzen?
Dann, wenn Sie jemals das Datenformat ändern wollten, würden Sie nur den Server zu ändern, und nicht alle Clients.
Meiner Meinung nach einem Server bauen wäre viel einfacher, als zu versuchen, ein Netzwerk-Dateisystem zu verwenden.
Datei sperrt mit einem Twist
Wie andere Antworten erwähnt haben, ist die einfachste Methode ist, eine Sperrdatei im selben Verzeichnis wie die Daten-Datei zu erstellen.
Da Sie die gleiche Datei über mehrere PC zugreifen zu können, die beste Lösung, die ich denken kann, ist enthalten nur die Kennung der Maschine, die gerade in die Datendatei geschrieben werden.
So ist die Sequenz in die Datendatei zum Schreiben wäre:
-
Überprüfen Sie, ob eine Sperrdatei vorhanden
-
Wenn es eine Sperrdatei ist, ob ich derjenige bin es durch Überprüfung zu besitzen, dass ihr Inhalt meiner Kennung hat.
Wenn das der Fall ist, schreiben Sie einfach auf die Datendatei dann die Sperrdatei löschen.
Wenn das nicht der Fall ist, warten Sie nur eine Sekunde oder eine kleine zufällige Zeitdauer, und wiederholen Sie den gesamten Zyklus. -
Wenn es keine Sperrdatei ist, erstellen Sie eine mit meiner Kennung und versuchen, den gesamten Zyklus wieder Race-Bedingung zu vermeiden (erneut prüfen, ob die Sperrdatei ist wirklich von mir).
Zusammen mit der Kennung, würde ich einen Zeitstempel in der Sperrdatei aufnehmen und prüfen, ob es älter ist als ein vorgegebener Timeout-Wert.
Wenn der Zeitstempel zu alt ist, dann davon ausgehen, dass die Sperrdatei veraltet ist und einfach zu löschen, da es eines der PC auf die Datendatei zu schreiben Mea würde abgestürzt oder die Verbindung verloren gegangen ist.
Eine andere Lösung
Wenn Sie die Kontrolle das Format der Datendatei sind, könnte eine Struktur am Anfang der Datei zu reservieren um aufzuzeichnen, ob es gesperrt ist oder nicht.
Wenn Sie nur ein Byte für diesen Zweck reservieren, können Sie davon ausgehen, zum Beispiel, dass 00
würde die Datendatei bedeuten nicht gesperrt ist, und dass andere Werte würden die Kennung der Maschine zur Zeit schriftlich an sie stellen.
Probleme mit NFS
OK, ich bin Hinzufügen von ein paar Dinge, weil Jiri Klouda wies darauf hin, dass richtig NFS verwendet Client-seitiges Caching dass führt in die eigentliche Sperrdatei in einem unbestimmten Zustand zu sein.
Ein paar Möglichkeiten, dieses Problem zu lösen:
-
mount das NFS-Verzeichnis mit den
noac
odersync
Optionen. Das ist einfach, aber nicht vollständig die Konsistenz der Daten zwischen Client und Server garantieren obwohl, so gibt es immer noch Probleme sein kann, obwohl in Ihrem Fall kann es in Ordnung sein. -
Öffnen Sie die Sperrdatei oder eine Datendatei, die
O_DIRECT
verwenden, dieO_SYNC
oderO_DSYNC
Attribute. Dies soll Caching vollständig deaktivieren.
Dadurch wird die Leistung senken, aber die Kohärenz gewährleisten. -
Sie können können
flock()
verwenden, um die Datendatei zu sperren aber die Umsetzung ist nicht so doll, und Sie müssen überprüfen, ob Ihre speziellen OS tatsächlich den NFS-Sperrdienst verwendet. Es kann gar nicht anders nichts tun.
Wenn die Datendatei gesperrt ist, dann wird ein anderer Kunde es zum Schreiben öffnen scheitern.
Ach ja, und es scheint nicht auf SMB-Freigaben zu arbeiten, so ist es wahrscheinlich am besten, es einfach zu vergessen.