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

Курсы

Программирование
iOS Developer. Basic
-23%
Python Developer. Professional
-13%
Разработчик на Spring Framework
-23%
Golang Developer. Professional
-17%
Python Developer. Basic
-16%
iOS Developer. Professional
-13%
Node.js Developer
-15%
Unity Game Developer. Professional
-11%
React.js Developer
-12%
Android Developer. Professional
-7%
Software Architect
-12%
C++ Developer. Professional
-8%
Разработчик C#
-8%
Backend-разработчик на PHP
-8%
Архитектура и шаблоны проектирования
-12%
Программист С Базы данных Framework Laravel PostgreSQL Reverse-Engineering. Professional CI/CD Agile Project Manager Нереляционные базы данных Супер - интенсив по паттернам проектирования Супер-практикум по использованию и настройке GIT IoT-разработчик Advanced Fullstack JavaScript developer Супер-интенсив "Azure для разработчиков"
Инфраструктура
Мониторинг и логирование: Zabbix, Prometheus, ELK
-17%
DevOps практики и инструменты
-18%
Архитектор сетей
-21%
Инфраструктурная платформа на основе Kubernetes
-22%
Супер-интенсив «IaC Ansible»
-16%
Супер-интенсив по управлению миграциями (DBVC)
-16%
Administrator Linux. Professional
-5%
Administrator Linux.Basic
-10%
Супер-интенсив «ELK»
-10%
Базы данных Сетевой инженер AWS для разработчиков Cloud Solution Architecture Разработчик голосовых ассистентов и чат-ботов Внедрение и работа в DevSecOps Супер-практикум по работе с протоколом BGP Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Супер-интенсив «СУБД в высоконагруженных системах»
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

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 в гараже???

Для комментирования необходимо авторизоваться