Es fällt mir schwer, mich darum zu kümmern.
Mein Test-Setup enthält ein Shell-Skript, das kontinuierlich 'ls -la' für eine 1G-Datei aufruft und die Zeit seit der letzten Ausführung ausgibt. Ich führe dann ein Programm aus, um Teile der Datei zu ändern und sie mit der Festplatte zu synchronisieren.
Es spielt keine Rolle, ob ich fsync aufrufe oder das System eine Synchronisierung durchführt oder selbst wenn ich pwrite verwende, um die verschiedenen Teile zu schreiben (und dieses Bit immer noch teste), friert das 'ls -la' für die gesamte Zeit ein Synchronisationszeit - zwischen 7 und 40 Sekunden (abhängig von der Sparsamkeit der Modifikationen).
Wenn ich Chunks gleichzeitig mit msync synchronisiere oder versuche, beim Schreiben häufiger mit fsync zu arbeiten, wird die Dauer viel länger (vielleicht 10x so lang, aber noch länger, je nachdem, wie oft ich das mache). Die obige msync schreibt nur mit 16 KB / Transaktion, auch wenn die Seiten sequentiell sind.
Ich habe irgendwo gelesen, dass OpenBSD 'Partial File Writes' implementiert hat oder so. Ich kann mich jetzt nicht recht erinnern.
Kann ich sowieso etwas Ähnliches mit der Effizienz von fsync machen, ohne dass die Dateieinstellungen für die ganze Zeit gesperrt sind?
Tatsächlich besteht das A-Problem (für das ich denke, dass dieses B die Lösung ist) darin, einfach mit großen Dateien zu arbeiten und sie zum Schreiben auf die Festplatte zu ermutigen, damit der Speicher bei Bedarf schnell freigegeben werden kann Sein. NO_SYNC einfach wegzulassen ist nicht gut, da die Änderungen ungefähr zur gleichen Zeit stattfinden und diese Situation verursachen. Keine der anderen Optionen von madvise scheint ebenfalls zu helfen. Das heißt, wenn ich nicht synchronisiere, scheinen die Seiten so lange zu bleiben, bis mir der Speicher ausgeht, wo sie plötzlich zu tauschen beginnen (wenn auch nur bei 16 KB / Transaktion und sehr niedrigen MB / s).
Wie um alles in der Welt arbeiten Sie mit großen Dateien auf FreeBSD?
LÖSUNG:
Ich fand heraus, dass durch Optimieren meiner msync-Blöcke und Verwenden von MS_ASYNC anstelle von MS_SYNC im msync-Aufruf die gewünschte Leistung erzielt werden kann, während andere Prozesse weiterhin die Datei öffnen und mmap / read können.
Sie lösen Ihr Problem (Status der Überwachungsdatei) völlig falsch. Anstatt den Dateistatus regelmäßig zu überprüfen (und gelegentlich Probleme mit der E / A-Parallelität zu bekommen), sollte Ihr Programm einfach den Kernel auffordern, benachrichtigt zu werden, wenn sich eine bestimmte Datei (oder eine Sammlung von Dateien) ändert.
Mechanismen dafür gibt es auf allen modernen Unixen, aber leider sind sie nicht die gleichen ...
In der BSD-Familie von Unixes geschieht dies mit kqueue / kevent . Unter Linux gibt es inotify. Unter Solaris gibt es poll und / dev / poll.
Es gibt plattformübergreifende Bibliotheken, die die Details der Betriebssystemimplementierung verbergen und Ihnen eine portable API bieten. Wenn Sie Portabilität benötigen, suchen Sie nach File Alterations Monitor oder seiner moderneren Untergruppe namens gamin (portiert in / usr / ports / devel / gamin). Wenn Sie sich nur für (Free) BSD bewerben, können Sie kqueue / kevent direkt verwenden.
quelle
http://www.unix.com/man-page/FreeBSD/4/syncer/
Erklärt Ihr Problem klar. Der Synchronisator leert regelmäßig verschmutzte Puffer (aktualisierten Cache) auf die Festplatte. Diese "periodischen" Flushes möchten Sie vermeiden. Sehen Sie, was sysctl für Ihr Problem tun kann.
quelle