Системные администраторы годами использовали связку cron+rsync для синхронизации данных между несколькими машинами. При всей простоте эта связка совершенно не подходит для случаев когда надо обеспечить "моментальную" синхронизацию файлов, сразу после их создания или изменения. Например для синхронизации файлов между узлами CDN.
Утилита inosync использует подсистему inotify ядра Linux для отслеживания изменений в указанной директории и сразу синхронизирует эти изменения между основной и "ведомыми" машинами. Далее будет показан пример использования inosync для синхронизации файлов на небольшой CDN.
Опишем задачу подробнее: файлы заливаются администратором сайта через веб интерфейс в директорию "/home/webuser/domain.com/cdn" на основном сервере. Файлы "раздаются" с серверов CDN из точно такой же директории. Необходимо организовать автоматическую синхронизацию файлов с основном сервера на узлы CDN.
Во внутренней сети проекта основной сервер имеет IP-адрес 10.10.0.1, узлы CDN имеют адреса 10.21.0.1, 10.21.0.2 и 10.21.0.3. Все сервера работают под управлением Ubuntu 14.04. У синхронизируемых файлов в качестве владельца указан пользователь "webuser".
Установим inosync:
apt-get install inosync
Создаём директорию для файлов конфигурации:
mkdir -p /etc/inosync
Сгенерируем ключи, которые будем использовать для авторизации (Важно: ключ не должен быть защищён паролем!):
ssh-keygen -t rsa -f /etc/inosync/sync_key
Далее публичный ключ ("/etc/inosync/sync_key.pub") необходимо скопировать на узлы CDN:
for host in 10.21.0.{1,2,3}; do \ ssh-copy-id -i /etc/inosync/sync_key.pub webuser@${host}; \ done
Теперь создадим файл "/etc/inosync/default.py" следующего содержания:
# Эту директорию мы будем синхронизировать wpath = "/home/webuser/domain.com/cdn/" # Список исключений rexcludes = [] # Путь на узлах CDN, куда будем синхронизировать rpath = "/home/webuser/domain.com/cdn/" # Имя пользователя ruser = "webuser" # Полные пути для синхронизации rnodes = [ ruser + "@10.21.0.1:" + rpath, ruser + "@10.21.0.2:" + rpath, ruser + "@10.21.0.3:" + rpath, ] # Ограничение скорости в kB/s. # Если 0 то скорость не ограничивается rspeed = 0 # event mask (only sync on these events) emask = [ "IN_CLOSE_WRITE", "IN_CREATE", "IN_DELETE", "IN_MOVED_FROM", "IN_MOVED_TO", ] # Задержка в секундах перед началом синхронизации # Позволит избежать синхронизации неполных файлов edelay = 3 # Лог-файл logfile = "/var/log/inosync.log" # Путь к rsync rsync = "/usr/bin/rsync"
Самая большая проблема заключается в невозможности указать путь к SSH-ключам. Однако это можно обойти. Поскольку мы будем запускать inosync с правами пользователя "webuser", то конфигурацию SSH rsync будет искать в директории "/home/webuser/.ssh", следовательно конфигурацию необходимо писать в файл "/home/webuser/.ssh/config". Нам понадобится добавить туда следующие строки (если файл не существует - надо его создать):
Host 10.21.0.1 IdentityFile /etc/inosync/sync_key Host 10.21.0.2 IdentityFile /etc/inosync/sync_key Host 10.21.0.3 IdentityFile /etc/inosync/sync_key
И наконец запустим демона командой:
su -c '/usr/bin/inosync -d' webuser
Для автоматического запуска inosync при старте системы нужно добавить в "/etc/rc.local" строку:
/bin/su -c '/usr/bin/inosync -d' webuser
Для тестирования inosync нужно создать/изменить один или несколько файлов в синхронизируемой директории. В случае нормальной работы в логе будут примерно такие записи:
2015/06/16 09:32:22 [20850] building file list 2015/06/16 09:32:22 [20850] .d..t...... ./ 2015/06/16 09:32:23 [20850] cd+++++++++ 2015-06-16/ 2015/06/16 09:32:23 [20850] <f+++++++++ 2015-06-16/13ab932e121b182ba9f6de2a92d050f9.jpg 2015/06/16 09:32:23 [20850] <f+++++++++ 2015-06-16/aa94018bc94bc4e7fc84f0058db54949.jpg 2015/06/16 09:32:23 [20850] <f+++++++++ 2015-06-16/bbf27a102f107c56bbc69a9b39c3bb07.jpg 2015/06/16 09:32:23 [20850] <f+++++++++ 2015-06-16/beda6529838d434802820aaf4a79cabc.jpg 2015/06/16 09:32:23 [20850] <f+++++++++ 2015-06-16/c686a352595ab7f95109361efe11539c.jpg 2015/06/16 09:32:23 [20850] <f+++++++++ 2015-06-16/fb51b253c2f50d2c1b9d704388c3dc0b.jpg 2015/06/16 09:32:23 [20850] sent 181,044 bytes received 191 bytes total size 88,217,986 2015/06/16 09:32:24 [20941] building file list 2015/06/16 09:32:24 [20941] .d..t...... ./ 2015/06/16 09:32:24 [20941] cd+++++++++ 2015-06-16/ 2015/06/16 09:32:24 [20941] <f+++++++++ 2015-06-16/13ab932e121b182ba9f6de2a92d050f9.jpg 2015/06/16 09:32:24 [20941] <f+++++++++ 2015-06-16/aa94018bc94bc4e7fc84f0058db54949.jpg 2015/06/16 09:32:24 [20941] <f+++++++++ 2015-06-16/bbf27a102f107c56bbc69a9b39c3bb07.jpg 2015/06/16 09:32:24 [20941] <f+++++++++ 2015-06-16/beda6529838d434802820aaf4a79cabc.jpg 2015/06/16 09:32:24 [20941] <f+++++++++ 2015-06-16/c686a352595ab7f95109361efe11539c.jpg 2015/06/16 09:32:24 [20941] <f+++++++++ 2015-06-16/fb51b253c2f50d2c1b9d704388c3dc0b.jpg 2015/06/16 09:32:24 [20941] sent 181,048 bytes received 195 bytes total size 88,217,986 2015/06/16 09:32:26 [20950] building file list 2015/06/16 09:32:26 [20950] .d..t...... ./ 2015/06/16 09:32:26 [20950] cd+++++++++ 2015-06-16/ 2015/06/16 09:32:26 [20950] <f+++++++++ 2015-06-16/13ab932e121b182ba9f6de2a92d050f9.jpg 2015/06/16 09:32:26 [20950] <f+++++++++ 2015-06-16/aa94018bc94bc4e7fc84f0058db54949.jpg 2015/06/16 09:32:26 [20950] <f+++++++++ 2015-06-16/bbf27a102f107c56bbc69a9b39c3bb07.jpg 2015/06/16 09:32:26 [20950] <f+++++++++ 2015-06-16/beda6529838d434802820aaf4a79cabc.jpg 2015/06/16 09:32:26 [20950] <f+++++++++ 2015-06-16/c686a352595ab7f95109361efe11539c.jpg 2015/06/16 09:32:26 [20950] <f+++++++++ 2015-06-16/fb51b253c2f50d2c1b9d704388c3dc0b.jpg 2015/06/16 09:32:27 [20950] sent 181,048 bytes received 195 bytes total size 88,217,986
Если что-то не работает то поиск ошибок так же следует начинать с лог файла.
На этом всё. Приятной работы!
Anonymous 2015-10-28 14:33:06 (#)
Хотя для себя давно открыл костыль в виде замены cron на incron (как cron, только срабатывает по событиям inotify)