Стоит ли беспокоиться о состоянии гонки при передаче/обработке SFTP?

Стоит ли беспокоиться о состоянии гонки при передаче/обработке SFTP?

Сценарий:

Я использую SFTP для автоматической передачи файлов между двумя системами, A и B.

Система A запускает сервер SFTP. Система A будет периодически (скажем, раз в минуту) опрашивать свой локальный каталог SFTP на предмет наличия файлов *.dat, и если они будут найдены, импортировать и удалять их.

Система B генерирует файлы *.dat и по мере их создания отправляет их в систему A, подключаясь к этому хосту SFTP и загружая их.

Вопросы:

  1. Возможно ли, что система A увидит и начнет обрабатывать файл до того, как система B закончит его загрузку? Или SFTP каким-то образом предотвратит это, например, не помещая файлы в папку до завершения сетевой передачи?

  2. Разумно/рекомендуется ли для System B загружать под другим именем файла, например *.locked или *.part, а затем переименовывать в *.dat после завершения передачи по сети? Или есть лучший способ справиться с этим?

решение1

Это не состояние гонки по определению, однако возможно, что файл, частично загруженный, открыт для чтения Системой A и, следовательно, содержит недопустимые данные. Система A может проверить файл на согласованность, может проверить на фиксированный размер, если это уместно, может проверить на определенные разрешения файла (которые вы устанавливаете после загрузки) и в любом случае отложить открытие файла в случае, если условия не выполняются, сделав это на следующей итерации.

Я бы загрузил во временный файл или местоположение, а затем переименовал/переместил в правильную папку/расширение для вашей программы. т. е. загрузил в filename.part, а затем переименовал в filename.dat или загрузил в pending/filename.dat, а затем переместил из папки pending. Это решит все подобные проблемы. В системах UNIX/Linux и Windows операция перемещения (или операция переименования) будет атомарной, и вы никогда не получите частичный файл.

Нет лучшего способа справиться с этим. Вам нужно сообщить системе A, что файл не полный и между системами не настроено межпроцессное взаимодействие. Ваши варианты: использовать файл блокировки, чтобы запретить программе открывать файл (и позже удалить его), использовать временный файл (а затем переименовать/переместить файл в соответствующее имя) или выполнить какую-то проверку целостности (что, вероятно, является пустой тратой ресурсов).

Вы также можете рассмотреть, в зависимости от того, как часто это происходит, запуск Системы A из Системы B. Если файл там находится 99% времени, то предложенный вами способ (с блокировкой) вероятно наиболее эффективен. С другой стороны, если вы будете находить данные только изредка, это может быть пустой тратой ресурсов (и потребует долго работающей или запускаемой cron программы). Если у вас есть SFTP, у вас может быть доступ SSH. В таком случае настройте сертификаты между системами (чтобы избежать необходимости в паролях, см. ssh-copy-id) и запустите какую-нибудь модифицированную версию

ssh system_a.yourdomain.com 'processfile /home/user/data/*.dat'

Связанный контент