große Dateien synchronisieren FreeBSD

6

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.

Haru
quelle

Antworten:

1

freeBSD verwendet wie andere UNIX-Betriebssysteme freien Speicher, um Festplatten-E / A zwischenzuspeichern. Auf einem System mit viel freiem Speicher und wenigen Benutzern können sehr große Dateien vollständig im Speicher abgelegt werden. Damit sieht es so aus, als würde mehr Speicher verbraucht.

close()( fclose()) und fsync( fflush() ) sind die einzigen Systemaufrufe, die das Betriebssystem zwingen, den Cache zu schreiben. Dies ist nur dann der Fall, wenn kein anderer Prozess die Datei geöffnet hat. freeBSD hat nicht fdatasyncnur zwischengespeicherte Daten geschrieben, sondern keine Metadaten auf die physische Festplatte.

Ab BSD 4.4 können Sie Paging und Datei-Caching mit dem mincore()Syscall verfolgen .

Sie müssen also alle paar Schreibvorgänge neu starten.

Spielen Sie mit den Festplatten-Caching-Parametern:

http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/configtuning-disk.html
Jim Mcnamara
quelle
Danke für die Links. Ich denke, meine Frage wird besser mit meiner zweiten Bearbeitung gestellt - ich bin ziemlich froh, dass die gesamte Datei zwischengespeichert wird, das ist im Wesentlichen das, was ich will - das Problem ist, dass, wenn alles zwischengespeichert ist, irgendwann geschrieben werden muss In diesem Fall ist die Datei für die gesamte Zeit gesperrt. Die Datei sollte immer noch zum Lesen verfügbar sein. Wenn die Anwendung nach einigen Schreibvorgängen geleert wird, wird sie von der Festplatte begrenzt, auch wenn viel Speicher verfügbar ist.
Haru
1

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.

Mikhail T.
quelle
1
Ich glaube, Sie haben meinen Zweck für das Polling falsch verstanden - es sollte nur zeigen, dass während der Synchronisierung nichts anderes die Datei öffnen / lesen kann. Ich möchte, dass andere Prozesse (die möglicherweise nicht von mir gesteuert werden) die Daten öffnen und lesen können, während sie synchronisiert werden. Ich kann das jetzt mit msync unter Verwendung von MS_ASYNC tun. Aber danke - ich benutze kqueue / kevent für die Überwachung von Dateiänderungen usw. in anderen Bereichen.
Haru
0

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.

Jim Mcnamara
quelle
1
Die periodischen Löschvorgänge können durch Mapping mit NO_SYNC vermieden werden. Das Problem ist, dass die Daten irgendwann auf die Festplatte synchronisiert werden müssen. In diesem Fall wird alles auf einmal ausgeführt und die Datei für die Dauer der Synchronisierung gesperrt. Bei großen Dateien kann dies leicht einige Minuten dauern. Wenn ich absichtlich sehr oft synchronisiere, damit die Datei nicht so lange gesperrt bleibt, wird die Anwendung durch die Festplattengeschwindigkeit begrenzt, auch wenn viel Speicher verfügbar ist.
Haru
Sie benötigen wahrscheinlich SSD-Laufwerke, wenn dies tatsächlich das Problem ist, das Sie erkennen. Nach dem, was Sie gesagt haben, gibt es keine wirkliche Lösung für das Warten. Jetzt geben Sie an, dass Ihre periodische Synchronisierung den Prozess auf Festplatten-E / A-Geschwindigkeiten verlangsamt hat, was in der Computerwelt immer der Fall war. Die Antwort ist eine schnellere Festplatten-E / A, es gibt keine andere Antwort.
Jim Mcnamara
Das Problem ist die exklusive Sperre des Betriebssystems für die Datei beim Synchronisieren. Um zu zeigen, dass Disk io kein Problem sein sollte, stellen Sie sich 2 identische MMAP-Dateien vor. Schreiben Sie die Daten in beide. Lassen Sie alle Lesevorgänge in einer Datei ablaufen. Synchronisieren Sie die andere Datei mit der Festplatte. Benutzer können weiterhin auf die nicht synchronisierte Datei zugreifen, da sie nicht synchronisiert wird. Sobald die erste synchronisiert ist, vertauschen Sie die Zeiger und entfernen Sie die temporäre Datei. Die Anwendung wird unabhängig von der Synchronisierung mit Speichergeschwindigkeit ausgeführt. Nachteil - Komplexität und Verwendung von 2x Speicher!
Haru
1
Update - Ich habe festgestellt, dass das Problem tatsächlich nur beim Öffnen (oder Mmaping) oder beim Synchronisieren der Datei auftritt. Es hat keinen Einfluss auf die Lesbarkeit der Zuordnung, wenn die Datei bereits geöffnet und zugeordnet ist. Dies ist jedoch immer noch ein Problem für mich. (Hängt auch beim Aufrufen von "read" / "pread". Ich vermute, alle dateibezogenen Systemaufrufe.
Haru