2010-06-24 8 views
8

Ich führe eine Reihe von Python-Skripten auf einem Linux-Cluster, und die Ausgabe von einem Auftrag ist in der Regel die Eingabe in ein anderes Skript, möglicherweise auf einem anderen Knoten ausgeführt. Ich finde, dass es einige nicht unbedeutende Verzögerungen gibt, bevor Python Dateien bemerkt, die auf anderen Knoten erstellt wurden - os.path.exists() gibt false zurück und open() schlägt ebenfalls fehl. Ich kann eine Weile nicht os.path.exists (Mypath) Schleife, bis die Datei erscheint, und es kann mehr als eine volle Minute dauern, die nicht optimal in einer Pipeline mit vielen Schritten und potenziell viele Datensätze parallel ausgeführt wird.os.path.exists() liegt

Die einzige Problemumgehung, die ich bisher gefunden habe, ist subprocess.Popen aufzurufen ("ls% s"% (pathdir), shell = True), was das Problem magisch behebt. Ich denke, das ist wahrscheinlich ein Systemproblem, aber irgendwie könnte Python dies verursachen? Irgendeine Art von Cache oder etwas? Mein Systemadministrator hat bisher nicht viel geholfen.

+0

Sie können sehen, ob 'os.access' das gleiche Problem hat:' os.access ("/ foo", os.F_OK) ' – Amber

+0

' os.access() 'erscheint, um die gleiche Antwort wie' os zu geben. path.exists() ' – Noah

+1

Was ist, wenn Sie zuerst [' reload (os) '] (http://docs.python.org/library/functions.html#reload) eingeben? –

Antwort

9

os.path.exists() ruft nur die Funktion der C-Bibliothek auf.

Ich glaube, dass Sie in der Kernel-NFS-Implementierung in einen Cache laufen. Im Folgenden finden Sie einen Link zu einer Seite, auf der das Problem beschrieben wird, sowie einige Methoden zum Leeren des Caches.

Datei-Handle Caching

Verzeichnisse Cache-Dateinamen zu Dateizugriffszuordnung. Die häufigsten Probleme dabei sind:

• Sie haben eine geöffnete Datei, und Sie müssen überprüfen, ob die Datei durch eine neuere Datei ersetzt wurde. Sie müssen den Dateihandle-Cache des übergeordneten Verzeichnisses leeren, bevor stat() die Informationen der neuen Datei und nicht die der geöffneten Datei zurückgibt.

◦Dieser Fall hat ein anderes Problem: Die alte Datei wurde möglicherweise gelöscht und durch eine neue Datei ersetzt, aber beide Dateien haben möglicherweise denselben Inode. Sie können diesen Fall überprüfen, indem Sie den Attributcache der geöffneten Datei leeren und dann sehen, ob fstat() mit ESTALE fehlschlägt.

• Sie müssen prüfen, ob eine Datei existiert. Zum Beispiel eine Sperrdatei. Kernel hat möglicherweise zwischengespeichert, dass die Datei nicht existiert, auch wenn es in Wirklichkeit ist. Sie müssen den negativen Dateizugriffsspeicher des übergeordneten Verzeichnisses leeren, um zu sehen, ob die Datei wirklich existiert.

Ein paar Möglichkeiten, um die Datei-Handle-Cache zu leeren:

• Wenn das übergeordnete Verzeichnis des mtime geändert, die Datei-Handle-Cache durch Spülen sein Attribut Cache geleert wird. Dies sollte ziemlich gut funktionieren, wenn der NFS-Server eine Auflösung im Nanosekunden- oder Mikrosekundenbereich unterstützt.

• Linux: chown() das Verzeichnis zu seinem aktuellen Besitzer. Der Dateizugriffsspeicher wird geleert, wenn der Aufruf erfolgreich zurückgegeben wird.

• Solaris 9, 10: Die einzige Möglichkeit besteht darin, das übergeordnete Verzeichnis rmdir() zu versuchen. ENOTEPTY bedeutet, dass der Cache geleert wird. Beim Versuch, rmdir() zu erstellen, schlägt das aktuelle Verzeichnis mit EINVAL fehl und löscht den Cache nicht.

• FreeBSD 6.2: Die einzige Möglichkeit ist, rmdir() entweder das übergeordnete Verzeichnis oder die Datei darunter zu versuchen. Fehler ENOTEPTY, ENOTDIR und EACCES bedeuten, dass der Cache geleert wird, aber ENOENT hat ihn nicht gelöscht. FreeBSD cache negative Einträge nicht, so dass sie nicht geleert werden müssen.

http://web.archive.org/web/20100912144722/http://www.unixcoding.org/NFSCoding

+1

danke, das ist die richtige Antwort obwohl nicht gerade eine optimale Lösung :(aber der Systemadministrator kann es hoffentlich von hier aus nehmen. – Noah

+0

Link funktioniert nicht mehr ...: | – Chau

1

Das Problem wird mit der Tatsache zusammen, dass der Python Prozess in eigenen Schale verläuft. Wenn Sie subprocess.Popen(shell=True) ausführen, erstellen Sie eine neue Shell, die das Problem, das bei Ihnen auftritt, bearbeitet.

Python verursacht dieses Problem nicht. Es ist eine Kombination aus NFS (Dateispeicher) und Verzeichnislisten unter Linux.

Verwandte Themen