С чем нам пришлось столкнуться при использовании утилиты Csync2

s6t2mrtelmc_stzj3xfymcnqdwq.jpeg

Csync2 — достаточно старая утилита, которая предназначена для синхронизации файлов между серверами. Она позволяет настроить синхронизацию файлов по приоритетам, либо по последней модификации в файле (проверяются не сами изменения в файле, а дата его модификации). Также данная утилита позволяет настроить выполнения какого-либо действия при изменении определённого файла. Например при изменении конфигурации nginx, выполнить перечитывание конфигурации. Мы начали её использовать достаточно давно на небольших проектах (кластер минимум из 3-х серверов) и всё было хорошо до того момента, пока эти маленькие кластера не начали развиваться, а именно:


  1. Заметно увеличился объем файлов, которые необходимо синхронизировать между серверами.
  2. Увеличилась интенсивность добавления этих файлов.

Сегодня мы поделимся нашим опытом использования такой утилиты как csync2 и о том, какие проблемы могут возникнуть при ее использовании.

Для наглядности рассмотрим один из проектов, который стоит у нас на обслуживании и на котором используется утилита csync2 версии 2.0–8-g175a01c-4. Данная версия является последней для Debian 9. В примере используется политика разрешения конфликтов auto younger — кто новее, тот и прав.

Ниже представлена схема использования Csync2 на данном проекте:

fhyp11y0ygoqkuz6_dnhm1p4bw4.jpeg

Тут ничего необычного. Происходит синхронизация файлов внутри каталогов между серверами по принципу какой новее, тот и синхронизируем. То же происходит и с удалением. Если после действия над файлом было его удаление на первом сервере, то он удалится и на втором). По данному принципу всё хорошо работает пока проект сравнительно небольшой, менее 1 000 000 файлов и менее 10G синхронизируемых данных, но после того как проект вырастет, то есть перейдет планку, указанную выше, есть вероятность столкнуться со следующими проблемами:


  1. После синхронизации, файлу присваивается некорректный владелец.
  2. Возникновение конфликтов при синхронизации файлов.

Отмечу, что проблема с присвоением некорректного владельца файла после синхронизации наблюдается вне зависимости от размера проекта.

Далее поговорим о каждой обозначенной проблеме более детально.


После синхронизации, файлу присваивается некорректный владелец

Для наглядности рассмотрим следующий пример, возникающий на практике. Допустим, у нас есть файл /var/www/index.php с правами 644 и владельцем www-data на первом сервере, но этого файла нет на втором сервере, а т.к. каталоги /var/www должны быть идентичными, запускается процесс синхронизации данного файла утилитой csync2. После завершения работы утилиты, на втором сервере файл получил корректные права (644), но изменился владелец с www-data на root.

Такая проблема может возникнуть в нескольких случаях:


  • У пользователей, которым принадлежит файл, разные UID и GID на разных узлах кластера. Если на первом сервере UID у владельца файла, например, 1000, а на другом пользователя с этим UID не существует, то пользователь с таким же именем на втором сервере не сможет прочитать файл.
  • Если во время синхронизации с первого сервера на второй запускается обратный процесс синхронизации на втором сервере, возможен баг, при котором владельцем файла становится root-пользователь.
Server 1
ls -l __page_0855c931430c4324f491ed2cf13401c3
drwxr-xr-x 2 test_user test_user 4096 июн 20 09:59 __page_0855c931430c4324f491ed2cf13401c3

Server 2
ls -l __page_0855c931430c4324f491ed2cf13401c3
drwx------ 2 root         root         4096 июн 20 09:59 __page_0855c931430c4324f491ed2cf13401c3

Нами было найдено 2 варианта решения данной проблемы:


  1. Использование неофициальных патчей. Разработчики данных патчей не дают никаких гарантий и не несут какой-либо ответственности в случае потери данных.
  2. Отказ от auto younger и перенастройка csync2 таким образом, что один из серверов будет считаться мастером (все файлы будут считаться актуальными именно на мастер сервере), а второй слейвом.

Оба варианта не самые лучшие, т.к. первый ненадёжен, а в случае со вторым, мы теряем достаточно большую часть производительности, поскольку второй сервер простаивает и используется только в случае возникновения проблем на первом. У себя для решения этой проблемы мы выбираем второй вариант из выше предложенных, т.к. он более надежен.


Начали возникать конфликты в синхронизациях

Данная проблема возникает гораздо реже нежели предыдущая, но она также имеет место быть. В нашем случае она наблюдалась только когда происходило частое обновление одного и того же файла на всех серверах. Например, есть файл /var/www/tmp/index.php на всех узлах кластера и он обновляется 1 раз в секунду на каждом узле. При попытке его синхронизировать может возникнуть конфликт, т.к. во время синхронизации данный файл в базе csync2 на узле куда происходит синхронизация, окажется новее, что приведёт к возникновению конфликта, который csync2 не может решить в автоматическом режиме:

[12.02.2020 13:04:18.610567]    (16038) INFO:           child stderr (buffer size: 96 bytes): Updating /var/www/test.ru/data/index.php on Server-2 ...                                                                                  
[12.02.2020 13:04:18.612108]    (16038) INFO:           child stderr (buffer size: 103 bytes): Do not auto-resolve conflict: Lost 'younger/older' test.                                                                                                                        

File stays in dirty state. Try again later...       

Для решения данной проблемы мы обычно вручную запускали принудительную синхронизацию, т.е. меняли статус файла в базе данных на одном из серверов с chary на force в зависимости о того, где файл актуальнее. Поскольку с политикой auto younger данная проблема возникает достаточно редко, то мы просто знаем о её наличии и при необходимости решаем в ручном режиме.


Итого, стоило ли использовать csync на тот момент когда он был актуален, или можно было использовать что-то другое?

Что ж, инструмент csync2 достаточно прост и хорошо себя показывает при работе с небольшим объемом данных. Но при росте проекта вы можете столкнуться с описанными выше проблемами и попытаться их решить предложенными способами. Но если есть возможность перейти на синхронную репликацию и использовать распределенные файловые системы, которых сейчас достаточно много и они весьма производительны, то мы бы рекомендовали это сделать.


Также читайте другие статьи в нашем блоге:


© Habrahabr.ru