Если Apache записывает какой-то файл в одно место и не завершил его запись, а затем включается rsync
, rsync
скопирует все, что там находится.
Это означает, что если Apache имеет дело с 5-мегабайтным файлом, только 2 Мбайт записывается и rsync
запускается, частичный 2-мегабайтный файл будет скопирован. Таким образом, этот файл может показаться «поврежденным» на конечном сервере.
В зависимости от размера файлов, которые вы используете, вы можете использовать --inplace
опцию в, rsync
чтобы сделать следующее:
Этот параметр изменяет способ, которым rsync передает файл, когда необходимо обновить данные файла: вместо метода по умолчанию для создания новой копии файла и перемещения его на место по завершении, rsync вместо этого записывает обновленные данные непосредственно в место назначения файл.
Преимущество этого состоит в том, что если в файле объемом 5 МБ скопировано только 2 МБ при первом запуске, то при следующем запуске будет загружено 2 МБ и продолжится копирование файла до тех пор, пока не будут заполнены все 5 МБ.
Недостатком является то, что это может создать ситуацию, когда кто-то обращается к веб-серверу во время копирования файла, и тогда он увидит частичный файл. На мой взгляд, rsync
лучше всего работает по умолчанию кэширование «невидимого» файла, а затем сразу же перемещать его на место. Но --inplace
это хорошо для сценариев, когда большие файлы и ограничения пропускной способности могут помешать тому, чтобы большой файл легко копировался из квадратного.
Это сказало, что Вы заявляете это; Акцент мой
Каждые пять минут cron run rsync…
Итак, я предполагаю, что у вас есть некоторый bash-скрипт для управления этой работой cron? Ну, дело в том, что он rsync
достаточно умен, чтобы копировать только те файлы, которые нужно скопировать. И если у вас есть скрипт, который запускается каждые 5 минут, похоже, вы пытаетесь не rsync
наступать друг на друга, если он идет быстрее. Это означает, что если вы запускаете его каждую минуту, существует риск того, что один или несколько rsync
процессов все равно будут работать из-за размера файла или скорости сети, и следующий процесс будет просто конкурировать с ним; гоночное состояние.
Один из способов избежать этого - заключить всю rsync
команду в скрипт bash, который проверяет блокировку файла; ниже приведен шаблонный сценарий bash, который я использую для подобных случаев.
Обратите внимание, что некоторые люди порекомендуют использовать, flock
но так flock
как он не установлен на некоторых системах, которые я использую - и я часто переключаюсь между Ubuntu (у которого он есть) и Mac OS X (без него) - я использую эту простую среду без каких-либо реальных проблем:
LOCK_NAME="MY_GREAT_BASH_SCRIPT"
LOCK_DIR='/tmp/'${LOCK_NAME}.lock
PID_FILE=${LOCK_DIR}'/'${LOCK_NAME}'.pid'
if mkdir ${LOCK_DIR} 2>/dev/null; then
# If the ${LOCK_DIR} doesn't exist, then start working & store the ${PID_FILE}
echo $$ > ${PID_FILE}
echo "Hello world!"
rm -rf ${LOCK_DIR}
exit
else
if [ -f ${PID_FILE} ] && kill -0 $(cat ${PID_FILE}) 2>/dev/null; then
# Confirm that the process file exists & a process
# with that PID is truly running.
echo "Running [PID "$(cat ${PID_FILE})"]" >&2
exit
else
# If the process is not running, yet there is a PID file--like in the case
# of a crash or sudden reboot--then get rid of the ${LOCK_DIR}
rm -rf ${LOCK_DIR}
exit
fi
fi
Идея заключается в том, что общее ядро - где у меня есть echo "Hello world!"
- это то, где лежит сердце вашего сценария. В остальном это в основном механизм блокировки / логика на основе mkdir
. Хорошее объяснение концепции в этом ответе :
mkdir создает каталог, если он еще не существует, и если он существует, он устанавливает код выхода. Что еще более важно, он делает все это в одном атомном действии, что делает его идеальным для этого сценария.
Так что в случае вашего rsync
процесса я бы порекомендовал использовать этот скрипт, просто изменив echo
команду на вашу rsync
команду. Кроме того, измените на LOCK_NAME
что-то вроде, RSYNC_PROCESS
и тогда вы можете идти.
Теперь, когда вы rsync
завернуты в этот сценарий, вы можете настроить выполнение задания cron каждую минуту без риска возникновения состояния гонки, когда два или более rsync
процесса борются за одно и то же. Это позволит вам увеличить скорость или rsync
обновления, что не устранит проблему частичной передачи файлов, но поможет ускорить весь процесс, чтобы в какой-то момент весь файл можно было правильно скопировать.