rsync с cron заданием каждую минуту

380
ALi

Я передаю файлы по сети с помощью rsync в задании cron, которое запускается каждые 1 минуту, задача состоит в том, чтобы при появлении нового файла загружать его на удаленный сервер:

Так как я новичок, я делаю здесь большую ошибку:

* * * * * rsync -azP /local_path user@x.x.x.x:/remote_path > /dev/null 

rsync создает временный файл (на удаленном конце), и на следующей минуте он снова создает временный файл (на удаленном конце), через несколько минут мои сети начинают задыхаться и пропускной способности загрузки не остается, затем я убиваю все процессы rsync и копирую их одновременно.

Нужно это автоматизировать, пожалуйста, помогите.

Спасибо

0
Узнайте, сколько времени действительно занимает rsync, и запланируйте, по крайней мере, четверку этого времени. Каждую минуту это переусердствует - ваш компьютер не будет делать ничего, кроме rsync. harrymc 5 лет назад 0

2 ответа на вопрос

1
Deltik

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

Вы можете убедиться, что только один экземпляр этого rsyncзапускается с помощью файла блокировки. util-linuxвключает в себя упаковщик блокировки файлов flock, который вы можете использовать в вашем crontab следующим образом:

* * * * * /usr/bin/flock -n '/tmp/example.lock' -c 'rsync -azP /local_path user@x.x.x.x:/remote_path' > /dev/null 

В приведенном выше примере путь к файлу блокировки есть /tmp/example.lock, но вы можете установить для него что-нибудь разумное. -nбудет препятствовать тому, чтобы flockкоманды накапливались, потому что он выйдет немедленно, а не будет ждать продолжения снятия блокировки.


Кроме того, вы также можете предотвратить накопление команды cron, создав скрипт с довольно простой блокировкой, которая гарантирует, что одновременно может выполняться только один экземпляр скрипта:

#!/bin/bash  PIDFILE=/tmp/example.pid  if [ -f "$PIDFILE" ] then PID="$(cat "$PIDFILE")" ps -p $PID > /dev/zero 2>&1 if [ $? -eq 0 ] then echo "Instance of this script is still running as PID $PID" exit 1 fi fi  echo $$ > $PIDFILE if [ $? -ne 0 ] then echo "Could not create PID file: $PIDFILE" exit 1 fi  # YOUR CODE GOES BELOW rsync -az /local_path user@x.x.x.x:/remote_path # YOUR CODE GOES ABOVE  rm -f "$PIDFILE" 

Механизм блокировки, вдохновленный предотвращением повторных выполнений заданий cron Бенджамином Кейном

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

Сохраните этот скрипт где-нибудь, например, в /usr/local/bin/example.sh, chmod +x /usr/local/bin/example.shи затем вызовите его из вашего crontab следующим образом:

* * * * * /usr/local/bin/example.sh > /dev/null 
Опасный сценарий. Если машина будет принудительно остановлена ​​или произойдет сбой питания, сохраненный файл PID будет жить вечно, предотвращая запуск rsync. Кроме того, команда `rm` в таком скрипте должна выполняться через` trap`, чтобы быть уверенным, что в случае, например, перезапуска или события выключения, PID-файл будет удален. Кроме того, поощряйте студентов выполнять хотя бы часть своих работ, а не давать им бесплатные решения. Alex 5 лет назад 1
0
Alex

Прежде всего, уберите -Pопцию, cron действительно не увидит прогресс.

Вам нужно реализовать некоторый механизм блокировки, не вызывать rsyncнапрямую из cron, а вместо этого создать скрипт, который будет использоваться в cron. В сценарии проверьте первое условие, если оно rsyncуже выполняется (например, вывод grep ps), если оно выполняется, просто выйдите из сценария, в противном случае выполните rsync.

Похожие вопросы