Блокировки файлов и транзакции

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

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

Возможно, процесс загрузки завершится сбоем после перемещения файла на место, но до создания символической ссылки, указывающей на наличие файла, который необходимо обработать. Я хотел бы знать, как лучше всего поступить в этом случае. Теоретически я могу создать файл в начале процесса загрузки, а затем удалить его после успешного создания символической ссылки, чтобы указать на успешное создание символической ссылки, но это снова приводит к тем же проблемам с блокировкой, что и раньше, потому что существует несколько процессов загрузки, которые требуют координировать между собой.

Есть ли более простой способ справиться со сбоем процесса загрузки?


person David K.    schedule 24.05.2015    source источник
comment
Хммм.... в Unix конвейер - это всегда более одного процесса, соединенного каналами, так что, возможно, вы используете этот термин как-то иначе? Кроме того, если есть только один экземпляр (запущенный процесс) программы, обрабатывающей файлы, вам не нужны никакие блокировки или другая особая магия. Кроме того, блокировка файла символической ссылки — это не то же самое, что блокировка обычного файла. Кроме того, почему может произойти сбой процесса загрузки между двумя простыми файловыми операциями (переименование и символическая ссылка)?   -  person Greg A. Woods    schedule 29.05.2015
comment
Потому что сбои систем и средства отказоустойчивости учитывают эти сбои.   -  person David K.    schedule 29.05.2015


Ответы (1)


Обычный подход к этому типу проблем заключается в проверке «устаревших» файлов.

Если файл блокировки имеет дату модификации более X секунд, вы предполагаете, что процесс, создавший его, умер, и удаляете его.

Если файл данных имеет дату модификации более X секунд, вы предполагаете, что процесс, создавший его, умер, и удаляете его.

Если вы хотите быть действительно в безопасности, а файлы не особенно велики, вы можете сделать X чем-то нелепым, например, день (60 * 60 * 24 секунды).

person Andru Luvisi    schedule 14.07.2015