Однажды мне нужно было сделать несколько зеркал в разных странах на файлы которые часто скачивались пользователями, по этому я сделал два скрипта для синхронизации.
Первый сервер мог подключаться к основному по SSH с использованием ключей, по этому я использовал rsync:
#!/bin/bash
rsync -avh -e "ssh -p 22" --log-file=/srv/logs/$(date +%Y%m%d)_rsync_mirror.log user@ixnfo.com:/var/www/downloads/file.dmg /var/www/mirror/file.dmg
# Clear old logs
find /srv/logs/ -type d -mtime +90 -exec rm -rfv {} \;
И добавил скрипт в /etc/crontab чтобы он выполнялся каждые 3 часа в 30 минут:
30 */3 * * * root /srv/scripts/rsync_mirror.sh > /dev/null 2>&1
На втором сервере нельзя было подключаться к основному по SSH, по этому я решил просто по основной ссылке проверять дату файла и если файл новее чем на зеркале, то тогда скачивать (основа скрипта взята тут https://gist.github.com/jacksgt/56dd2dfc115fde19ccf0):
#!/bin/bash
# Exit codes:
# -1 = local file up to date, nothing to do
# 0 = updated local file, successfull
# 1 (and above) = failure
REMOTE_FILE="https://ixnfo.com/testfile";
LOCAL_FILE="/var/www/mirror2/testfile";
REMOTE_DATE=$( date -d "$( curl -Is $REMOTE_FILE | grep 'Modified' | cut -d',' -f2 )" "+%s" );
if [[ ! "$REMOTE_DATE" =~ [[:digit:]] ]]; then
exit 1;
fi
if [[ -e "$LOCAL_FILE" ]]; then
LOCAL_DATE=$( stat "$LOCAL_FILE" -c "%Y" );
else
LOCAL_DATE=0;
touch "$LOCAL_FILE" >> /dev/null 2>&1;
if [ $? -eq 1 ]; then
exit 1;
fi
fi
# Check if we actually got only a digit
if [[ ! "$LOCAL_DATE" =~ [[:digit:]] ]]; then
exit 1;
fi
# Check if local file is younger than remote file
if [ $LOCAL_DATE -gt $REMOTE_DATE ]; then
exit -1;
else
curl -s "$REMOTE_FILE" -o "$LOCAL_FILE";
fi
exit 0;
Для теста можно создать пустой файл на несколько гигабайт, чтобы убедится что скрипт скачивает файл с основного сервера только тогда когда он изменился:
dd if=/dev/zero of=testfile bs=4G count=1
Смотрите также мои статьи:
Установка и использование rsync в Linux
Как скомпилировать cURL в Ubuntu