Muss ich mir bei der SFTP-Übertragung/-Verarbeitung über Race Conditions Gedanken machen?

Muss ich mir bei der SFTP-Übertragung/-Verarbeitung über Race Conditions Gedanken machen?

Szenario:

Ich verwende SFTP, um Dateien automatisch zwischen zwei Systemen, A und B, zu übertragen.

Auf System A läuft ein SFTP-Server. System A wird in regelmäßigen Abständen (etwa einmal pro Minute) sein lokales SFTP-Verzeichnis auf das Vorhandensein von *.dat-Dateien abfragen und diese, falls vorhanden, importieren und löschen.

System B generiert *.dat-Dateien und sendet sie nach der Generierung an System A, indem es eine Verbindung zu diesem SFTP-Host herstellt und sie hochlädt.

Fragen:

  1. Ist es möglich, dass System A eine Datei sieht und mit der Verarbeitung beginnt, bevor System B sie vollständig hochgeladen hat? Oder verhindert SFTP dies irgendwie, indem es beispielsweise Dateien erst dann im Ordner ablegt, wenn die Netzwerkübertragung abgeschlossen ist?

  2. Ist es sinnvoll/empfohlen, dass System B die Datei unter einem anderen Dateinamen wie *.locked oder *.part hochlädt und sie nach Abschluss der Netzwerkübertragung in *.dat umbenennt? Oder gibt es eine bessere Möglichkeit, dies zu handhaben?

Antwort1

Es handelt sich per Definition nicht um einen Race Condition, es ist jedoch möglich, dass eine teilweise hochgeladene Datei von System A zum Lesen geöffnet wird und daher ungültige Daten enthält. System A könnte die Datei auf Konsistenz prüfen, ggf. auf eine feste Größe testen, auf bestimmte Dateiberechtigungen testen (die Sie nach dem Hochladen festlegen) und in jedem Fall das Öffnen der Datei verschieben, falls die Bedingungen nicht erfüllt sind, und dies bei der nächsten Iteration tun.

Ich würde in einen temporären Dateinamen oder Speicherort hochladen und dann in den richtigen Ordner/die richtige Erweiterung für Ihr Programm umbenennen/verschieben. D. h. in Dateiname.Teil hochladen und dann in Dateiname.dat umbenennen oder in ausstehend/Dateiname.dat hochladen und dann aus dem ausstehenden Ordner verschieben. Dadurch werden alle derartigen Probleme gelöst. Auf UNIX/Linux- und Windows-Systemen ist ein Verschiebevorgang (oder Umbenennungsvorgang) atomar und Sie erhalten nie eine Teildatei.

Es gibt keine wirklich bessere Möglichkeit, damit umzugehen. Sie müssen System A mitteilen, dass die Datei nicht vollständig ist und keine Interprozesskommunikation zwischen den Systemen eingerichtet ist. Sie haben die Möglichkeit, eine Sperrdatei zu verwenden, um zu verhindern, dass Ihr Programm die Datei öffnet (und sie später zu entfernen), eine temporäre Datei zu verwenden (und Ihre Datei dann umzubenennen/auf den entsprechenden Namen zu verschieben) oder eine Art Integritätsprüfung durchzuführen (was wahrscheinlich eine Verschwendung von Ressourcen ist).

Sie könnten auch in Betracht ziehen, je nachdem, wie oft dies geschieht, System A von System B aus auszulösen. Wenn dort in 99 % der Fälle eine Datei vorhanden ist, ist die von Ihnen vorgeschlagene Methode (mit einer Sperre) wahrscheinlich am effizientesten. Wenn Sie andererseits nur gelegentlich Daten finden, ist dies möglicherweise eine Verschwendung von Ressourcen (und erfordert ein lang laufendes oder von Cron ausgelöstes Programm). Wenn Sie SFTP haben, haben Sie möglicherweise SSH-Zugriff. Richten Sie in diesem Fall Zertifikate zwischen den Systemen ein (um die Notwendigkeit von Passwörtern zu vermeiden, siehe ssh-copy-id) und führen Sie eine modifizierte Version von

ssh system_a.IhreDomain.com 'Prozessdatei /home/Benutzer/Daten/*.dat'

verwandte Informationen