lsyncd: синхронизация файлов между несколькими серверами | OTUS
Запланируйте обучение с выгодой в Otus!
-15% на все курсы до 22.11 Забрать скидку! →
Выбрать курс

lsyncd: синхронизация файлов между несколькими серверами

Linux_Deep_29.3_site-5020-0766ac.png

Исходная ситуация Есть несколько нод веб-сервера, картинки проекта подключены симлинком и физически лежат на хранилище, подключённом по NFS. Отсюда имеем одну точку отказа — лежит NFS: нет картинок, ну и скорость чтения так себе, учитывая накладные расходы на сетевую передачу.

Что будем реализовывать Несколько веб-серверов, картинки лежат на них локально на отдельно подключённом быстром диске и синхронизируют картинки через отдельное хранилище. Таким образом, чтение становится быстрее за счёт нахождения файлов локально. Также в случае падения какой-то ноды, проект продолжает работать. И так как картинки в основном читаются, а пишутся редко (1-2 раза в день), можно в спокойном режиме переподнять хранилище для обмена, чтобы растащить новые картинки по остальным нодам.

nfs-4271-b89416.png

Для реализации замысла был выбран lsyncd, так как другие решения имели недостатки: — DRBD - идеально для синхронизации между двумя серверами, но в более сложных конфигурациях нужно сильно «велосипедить»; — Ceph - слишком сложно для данного кейса; — GlusterFS - оказалось медленнее NFS в моём случае.

Итак, реализация

Выбираем/создаём каталог для синхронизации и создаём его на обоих серверах. Затем создаём ключи для пользователя, от имени которого будет происходить синхронизация:

ssh-keygen

Добавляем ключи на сервер. Чтобы это сделать, копируем содержимое созданного файла ~/.ssh/id_rsa.pub с сервера, на котором создали ключ для подключения, в файл ~/.ssh/authorized_keys на сервере, к которому будет подключаться. Пробуем подключиться к целевому серверу:

ssh username@server

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

Далее устанавливаем lsyncd на обоих серверах:

sudo yum install lsyncd -y

Редактируем conf-файл. Файл /etc/lsyncd.conf пишется в формате lua. Самое простое — сделать один конфиг со всеми нодами и скопировать его на сервера, закомментировав ненужные куски конфига. У меня файл получился примерно таким для сервера nfs-exchange, через который будет происходить обмен:

settings {
  logfile    = "/var/log/lsyncd/lsyncd.log", --[[log-файл с событиями синхронизации и ошибками]]
  statusFile = "/var/log/lsyncd/lsyncd.status", --[[файл, где указано какие каталоги отслеживает inotify и какие каталоги будут синхронизированы]]
  statusInterval = 5, --[[интервал обновления файла lsyncd.status в секундах]]
}

--[[
sync {
  default.rsyncssh, --[[выбор протокола синхронизации]]
  source = "/nfssync/pics", --[[каталог-источник для синхронизации]]
  host = "nfs-exchange", --[[целевой хост, куда каталог будет синхронизироваться]]
  targetdir = "/nfssync/pics", --[[целевой каталог на сервере, заданной в параметре host]]
  rsync = {
       _extra = { "-ausS", "--temp-dir=/tmp", "-e", "/usr/bin/ssh -l username -i /home/username/.ssh/id_rsa -o StrictHostKeyChecking=no" }
  }, 
  --[[дополнительные параметры синхронизации:
    a — режим архивации; равносильно -rlptgoD, тоесть копировать рекурсивно, вместе с симлинками и специальными файлами, сохраняя права доступа, группу, владельца.
    u — не обновлять файлы на получателе если они новее;    
    s — на случай если в имени файла попадется пробел.
    S — оптимизировать передачу данных состоящих из нулей.
    temp-dir нужна если синхронизация двухсторонняя
    далее я задал пользователя и его ключ, чтобы синхронизация происходила под пользователем, для которого мы ранее создали ключи и раскидали их по серверам.
    Опция -o StrictHostKeyChecking=no решает проблему ошибки Permission denied.



    Более подробно в man и тут:
    https://github.com/mralexjuarez/lsyncd-tutorial

        ]]
  delay = 3, --[[пауза между запуском синхронизации]]
}
]]

sync {
  default.rsyncssh,
  source = "/nfssync/pics",
  host = "node01",
  targetdir = "/nfssync/pics",
  rsync = {
       _extra = { "-ausS", "--temp-dir=/tmp", "-e", "/usr/bin/ssh -l username -i /home/username/.ssh/id_rsa -o StrictHostKeyChecking=no" }
  },
  delay = 3
}


sync {
  default.rsyncssh,
  source = "/nfssync/pics",
  host = "node02",
  targetdir = "/nfssync/pics",
  rsync = {
       _extra = { "-ausS", "--temp-dir=/tmp", "-e", "/usr/bin/ssh -l username -i /home/username/.ssh/id_rsa -o StrictHostKeyChecking=no" }
  },
  delay = 3,
}

sync {
  default.rsyncssh,
  source = "/nfssync/pics",
  host = "node03",
  targetdir = "/nfssync/pics",
  rsync = {
       _extra = { "-ausS", "--temp-dir=/tmp", "-e", "/usr/bin/ssh -l username -i /home/username/.ssh/id_rsa -o StrictHostKeyChecking=no" }
  },
  delay = 3,
}

На остальных нодах закомментированы все ноды и раскомментирован только участок конфига, касающийся хоста nfs-exchange.

settings {
  logfile    = "/var/log/lsyncd/lsyncd.log",
  statusFile = "/var/log/lsyncd/lsyncd.status",
  statusInterval = 5,
}


sync {
  default.rsyncssh,
  source = "/nfssync/pics",
  host = "nfs-exchange",
  targetdir = "/nfssync/pics",
  rsync = {
       _extra = { "-ausS", "--temp-dir=/tmp", "-e", "/usr/bin/ssh -l username -i /home/username/.ssh/id_rsa -o StrictHostKeyChecking=no" }
  },
  delay = 3,
}


--[[
sync {
  default.rsyncssh,
  source = "/nfssync/pics",
  host = "node01",
  targetdir = "/nfssync/pics",
  rsync = {
       _extra = { "-ausS", "--temp-dir=/tmp", "-e", "/usr/bin/ssh -l username -i /home/username/.ssh/id_rsa -o StrictHostKeyChecking=no" }
  },
  delay = 3
}


sync {
  default.rsyncssh,
  source = "/nfssync/pics",
  host = "node02",
  targetdir = "/nfssync/pics",
  rsync = {
       _extra = { "-ausS", "--temp-dir=/tmp", "-e", "/usr/bin/ssh -l username -i /home/username/.ssh/id_rsa -o StrictHostKeyChecking=no" }
  },
  delay = 3,
}

sync {
  default.rsyncssh,
  source = "/nfssync/pics",
  host = "node03",
  targetdir = "/nfssync/pics",
  rsync = {
       _extra = { "-ausS", "--temp-dir=/tmp", "-e", "/usr/bin/ssh -l username -i /home/username/.ssh/id_rsa -o StrictHostKeyChecking=no" }
  },
  delay = 3,
}
]]

Когда конфиги созданы, можем включать lsyncd с обеих сторон на серверах. Желательно, конечно, включить с одной стороны, посмотреть log, и если все хорошо, включать с другой стороны.

systemctl start lsyncd
systemctl enable lsyncd

Тюнинг ядра

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

echo "
fs.inotify.max_user_watches = 16777216  
fs.inotify.max_queued_events = 65536
" >> /etc/sysctl.conf

Если всё сделано правильно, файлы должны синхронизироваться. Далее, можно и нужно настроить мониторинг службы lsyncd с помощью monit, например, по этому мануалу.

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
4 комментария
0

Достаточно просто написано, что очень радует, но возник вопрос какое преимущество от rsyncd настроенного по крону. Мне кажется все же rsyncd проще.

0

Я вот хочу на lsync перейти, т.к. по крону раз в 5 минут репликация с основного на резервный сервер идет. Последний раз материнка сломалась, пока ездили до дата-центра, пока тащили сервак в офис, пока всё чинили, едва едва сайты не выпали из поиска. Сейчас на домашний сервак репликация, чтоб если что домен перекрутить и всё работает, можно неспеша чинить. Только меня одно напрягает, rsync создает локальный список файлов, отправляет его на удаленный, тот говорит что у меня всё есть и на этом заканчивается. Локальный список формируется примерно минуту, на удаленный сервер передается около 150 мегабайт, мне кажется излишние издержки сетевые, кидать на удаленный комп столько инфы, да и построение списка файлов слишком тугое... Лучше было бы если локальный комп мониторил то что изменилось (за пару часов может только один файл поменяться), и отправлял только нужное, а не всё сразу...

У меня только вопрос к автору, как тут быть с --exclude, у меня например /var/www копируется, но там всякое типа кеши, логи, сессии, их очень много, они быстро создаются, постоянно меняются, но на резервном сервере мне не надо их актуальными хранить...

0

Rsyncd сервер 3.5 Тб попробуй синхронизировать через крон ) Да и еще интервал синхронизации подбери )

0

monit? на centos7?? накой велосипед изобретать, коли systemd в гараже???

Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто
Черная пятница в Otus! ⚡️
Скидка 15% на все курсы до 22.11 →