Якщо Apache пише якийсь файл в одне місце і не закінчив його писати, а потім rsync
запускає, rsync
скопіює все, що там сидить.
Значить, якщо Apache має справу з файлом 5 МБ, записано лише 2 МБ і rsync
запускається, частковий файл 2 МБ буде скопійовано. Отже, цей файл здається, що він "пошкоджений" на сервері призначення.
Залежно від розміру файлів, які ви використовуєте, ви можете скористатися --inplace
опцією, rsync
щоб зробити наступне:
Цей параметр змінює, як rsync передає файл, коли дані файлу потребують оновлення: замість методу за замовчуванням створити нову копію файлу та перемістити її на місце, коли вона завершена, rsync замість цього записує оновлені дані безпосередньо до місця призначення файл.
Перевага від цього полягає в тому, що якщо у файлі 5 МБ було скопійовано лише 2 МБ при першому запуску, наступний запуск набереться на рівні 2 МБ і продовжить копіювати файл до повного 5 МБ.
Негативним є те, що це може створити ситуацію, коли хтось звертається до веб-сервера під час копіювання файлу, і тоді вони побачать частковий файл. На мою думку, rsync
найкраще працює в тому, що поведінка за замовчуванням кешується «невидимим» файлом, а потім відразу переміщується на місце. Але --inplace
це добре для сценаріїв, коли великі файли та обмеження пропускної здатності можуть стояти на шляху, коли великий файл легко копіюється з квадратного.
Це сказало, що ви констатуєте це; акцент мій:
Кожні п’ять хвилин rsync виконує крон…
Тож я припускаю, що у вас є якийсь баш сценарій для управління цією роботою cron? Що ж, річ rsync
розумна, щоб лише копіювати файли, які потрібно скопіювати. І якщо у вас є сценарій, який працює кожні 5 хвилин, то, здається, ви намагаєтеся уникати rsync
кроку один на одного, якщо він пройде швидше. Це означає, що якщо ви запускаєте його щохвилини, є ризик того, що один або кілька rsync
процесів все одно будуть працювати через розмір файлу або швидкість мережі, і наступний процес буде просто конкурувати з ним; стан перегонів.
Один із способів уникнути цього - загортати всю свою rsync
команду в скрипт bash, який перевіряє блокування файлу; нижче - рамка сценарію bash script 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
оновлення, що не усуне проблему передачі часткових файлів, але це допоможе прискорити загальний процес, тому повний файл можна буде належним чином скопіювати в якийсь момент.