Из просмотра кода на https://metacpan.org/pod/File :: NFSLock Я вижу, что блокировка реализована только физическим файлом в системе. Я работаю почти во всех проектах с одним и тем же логикой c блокировки процесса.
При использовании блокировки процесса крайне важно не устанавливать слишком жесткий stale_lock_timeout
. Или произойдет " Состояние гонки ", как это также упоминается в комментариях к коду.
Как вы упомянули, 3 процесса начинают конкурировать за одну и ту же блокировку, потому что задание занимает > 5 мин и вы установите tale_lock_timeout
на 5 мин. Если у вас есть фиксатор времени, такой как crond
, он будет запускать процесс каждые 5 минут. Каждый процесс примет блокировку как устаревшую , потому что 5 минут уже прошло, хотя процесс занимает более > 5 минут
Для описания возможного сценария: Некоторое задание БД занимает 4 минуты, но в перегруженной системе это может занять до 7 минут и более. Теперь, если служба crond
запускает процесс каждые 5 минут В 0 минут первый процесс process1
найдет задание как новое, установит блокировку и запустит задание, которое займет до 7 минут. Теперь через 5 минут Служба crond
запустит process2
, который обнаружит блокировку process1
, но решит, что она уже устаревшая , потому что уже 5 минут с момента блокировки создан и будет принят как устаревший . Так что process2
снимает блокировку и забирает ее для себя. Позже через 7 минут process1
уже завершил задание и, не проверяя, является ли он его блокировкой, снимает блокировку process2
и завершает работу. Теперь через 10 минут process3
запускается и не обнаруживает никаких блокировок, поскольку блокировка process2
уже была освобождена process1
и устанавливает свою собственную блокировку. На самом деле этот сценарий действительно проблематичен c, поскольку он приводит к накоплению процессов и накоплению рабочей нагрузки, а также к непредсказуемым результатам.
Предложение для устранения этой проблемы:
- Установите
stale_lock_timeout
на сумму, намного большую, чем та, что потребуется для работы (например, 10 минут или 15 минут). stale_lock_timeout
, но больше, чем график выполнения. - Установите график выполнения более просторным, чтобы дать каждому процессу достаточно времени для завершения sh своей задачи (каждые 10 минут или каждые 15 минут)
- Рассмотрите возможность объединения Задания
process1
, process2
и process3
в один только process_master
, который запускает каждый процесс после завершения предыдущих этапов.