Привет, Хабр!
Сегодня я хочу рассказать о том, как работает резервное копирование сервера CommuniGate Pro, если делать его с помощью Кибер Бэкап 15. Под катом — схема взаимодействия наших решений, а также подробности о том, как работает бэкап-агент в наиболее сложных для него ситуациях.
Начнем с того, почему CommuniGate Pro. Дело в том, что одной из сильных сторон Кибер Бэкап на сегодняшний день является поддержка широкого спектра платформ и возможность организации резервного копирования для разных операционных систем, разных систем виртуализации и СУБД из единой консоли. Это помогает экономить рабочее время администраторов, а также позволяет добиться защищенности и доступности ИТ-инфраструктуры в целом.
Сегодня в число важных для бизнеса ИТ-решений входят также системы корпоративных коммуникаций. Они обеспечивают совместную работу и обмен сообщениями, которые также нужно сохранять и защищать. Традиционно многие компании использовали MS Exchange, чтобы упорядочить работу корпоративной электронной почты, а в последнее время в моду вошли корпоративные платформы, объединенные с чатами, системами ВКС и возможностью совместной работы.
Но теперь, когда продление лицензий Microsoft 365 сильно затруднено (да и вообще непонятно, каковы перспективы пользования этими сервисами), возросла популярность альтернативных решений. Они, кстати, успешно находили своих поклонников и до этого. Например, сервер CommuniGate Pro активно используется российскими (и не только) компаниями, обеспечивая одновременно работу с почтой, поддержку чатов и ВКС, а также общую работу с файлами. “Удобно и практично, и еще припаять бы к нему бэкап” — подумали мы в прошлом году, и в итоге сделали устойчивую интеграцию.
Немного об архитектуре CommuniGate Pro
С точки зрения разработчика, который хочет организовать бэкап сервера CommuniGate Pro, архитектура системы оказалась весьма удачной. Объекты на сервере организованы в иерархическую файловую структуру. На верхнем уровне находятся папки (folders). Они могут представлять собой ящики для писем, календари, наборы заметок, задач и т.д. В папках могут быть другие папки того же типа или соответственно сами письма, события календаря, отдельные заметки, задачи и т.п.
Каждая папка может обладать некоторыми метаданными, например, датой создания или изменения, а каждый объект помимо этого содержит некоторый объем полезных данных, например, собственно, текст письма. Для Кибер Бекапа это оказалось очень удобно, поскольку хорошо совпадает с нашей внутренней моделью представления данных.
Из многообразия протоколов взаимодействия с сервером CommuniGate Pro мы остановились на IMAP, CLI и XIMMS. После консультаций с разработчиками CommuniGate для работы были выбраны первые два. IMAP (расширенный специфичными для CommuniGate командами) используется для основной работы с письмами, а CLI позволяет выполнять некоторые служебные операции, например удостоверяться в доступности защищённого IMAP соединения и переключаться на него.
Как видно из схемы, бекап агент обращается к данным через посредника — Data Source Provider (DSP). DSP — это отдельный сервис, который с одной стороны понимает устройство "полезной нагрузки" - объектов, подлежащих сохранению/восстановлению и умеет с ними обращаться - получать, создавать, изменять удалять. С другой стороны DSP может предоставлять эти данные для архива в общем виде по фиксированному протоколу или получать данные из архива при восстановлении. Сам DSP представляет собой stateless-приложение и использует REST API для общения с агентом резервного копирования.
Поскольку новая архитектура поддержки приложений, в составе которой работает DSP появилась не так давно, то первые реализации работали с плоскими структурами данных. Так что, хотя API DSP и был разработан под иерархические структуры, в первой практической реализации выявилось множество мелких недоработок, как в самом DSP, так и в сопряженных с ним компонентах. Все эти недоработки пришлось устранить, а функционал дополнить.
При обращении на сервер CommuniGate Pro мы получаем иерархическую структуру, которую передает нам модуль DSP. В результате, как и для других поддерживаемых объектов и систем, мы можем использовать один из двух видов бэкапа:
Полный, когда мы складируем данные из ящика пользователя на резервные накопители и, в случае запроса на восстановление, просто возвращаем все на свои места.
Инкрементальный. Когда мы сравниваем текущее положение дел с предыдущим бэкапом и записываем в хранилище только изменения.
В качестве основной команды для общения с сервером используется оператор Sync. Это дополнительная команда, которая возвращает общее число значений, не запрашивая все письма. Использование Sync для отслеживания изменений на сервере намного лучше, чем Fetch из базового протокола IMAP, так как мы экономим время и получаем данные быстрее.
Как я уже говорил, в процессе инкрементального бэкапа необходимо сравнить актуальные письма с сохраненными копиями. При подходе "в лоб" это предполагает извлечение всего содержимого ящиков из CommuniGate только затем, чтобы убедиться, что ничего не изменилось и отбросить. Но команда FETCH из протокола IMAP довольна нетороплива хотя бы потому, что возвращает весь объём письма, содержащего, например вложение на несколько мегабайт. Это неэффективно.
К счастью, разработчики CommuniGate Pro дополнили IMAP протокол командой SYNC, которая возвращает идентификаторы новых или изменившихся писем. Что не только позволяет извлекать с помощью FETCH лишь изменившиеся письма, но также избежать дорогостоящей и сложной процедуры сравнения старых и новых данных на стороне СРК.
Не все так просто - три заковырки на нашем пути
На первый взгляд все выглядит очень просто. Поскольку объекты CommuniGate Pro похожи на папки и файлы, мы просто берем их и бэкапим. Но, как обычно “дьявол кроется в деталях”. И именно поэтому большинство систем резервного копирования (и наша в прошлом тоже) не способны гарантировать ни 100% бэкап, ни 100% восстановление коммуникационного сервера.
Чтобы никакие сообщения или записи не потерялись, нужно удостовериться в том, что СРК и сервер действительно могут взаимодействовать напрямую и быть глубоко интегрированными. Это непростая задача, решение которой требует времени и кропотливой работы. Мы ее уже провели и сегодня рассмотрим несколько интересных заковырок, которые нам пришлось решать на этом пути.
Заковырка №1. Проблема уникальности элементов.
Работа с CommuniGate Pro происходит по расширенному протоколу IMAP. С одной стороны это очень удобно, потому что в протоколе есть все стандартные функции. Но с другой стороны, для идентификации писем и, соответственно, всех других элементов, которые тоже передаются как письма, существует несколько способов идентификации.
Поскольку объектов в системе много, CommuniGate Pro использует свои собственные идентификаторы. И вы в любой момент можете запросить объекты (как письма), указав их идентификаторы в параметрах Sync, а потом вытащить письма запросом Fetch по идентификаторам.
Да, вы получите письма, например, № 14001, 14002 и 14003, но практика показала, что идентификаторы могут плавать. Например, кто-то удалил письмо, кто-то прислал еще одно письмо, встречу в календаре отменили и удалили, потом создали новую. Из-за этого их порядок меняется. И в случае резервного копирования и восстановления могут возникнуть два объекта с одним и тем же идентификатором. Как вы понимаете, это нехорошо, очень нехорошо.
Чтобы решить эту проблему возникла идея использовать UID. Но с ними тоже оказалось не все так гладко. Письма и любые другие объекты прозрачно идентифицируются в своей папке. Мы можем ее забэкапить. Но если пользователь удалил папку, а потом он же (или кто-то другой) создал папку с тем же именем и в результате дал ей такой же идентификатор, в случае восстановления возникает конфликт. Потому что мы не можем с уверенностью сказать — это то же самое письмо, но поврежденное…или совершенно другое?
Следующий вариант — MessageID. Согласно спецификациям RFC, эти идентификаторы должны быть уникальны. Существует мнение, что они уникальны и нет двух писем с одинаковым MessageID в принципе. Другие считают, что MessageID будет уникальным только в рамках одного сервера. В принципе нам хватило бы и этого, ведь мы получаем гарантированный идентификатор письма….
Но по факту CommuniGate Pro работает не только с письмами и поэтому опирается на внутренние идентификаторы. Так что в некоторых случаях на запрос MessageID система возвращает…а ничего не возвращает.
Тем не менее, мы решили использовать MessageID, когда он есть и дорабатывать систему, когда его нет. Для этого мы вычитываем письмо или другой элемент целиком, считаем его хэш и сравниваем объекты с конфликтными идентификаторами по хэшам. Таким образом мы приняли решение восстанавливать то, что отсутствует, но не затереть то что присутствует. В крайнем (и весьма редком) случае может получиться два аналогичных объекта — старый и новый. Но зато обе версии будут доступны, и мы ничего не потеряем при восстановлении.
Заковырка №2. Производительность
Чтобы передать запрос на CommuniGate Pro, необходимо открыть сессию. И по умолчанию сессия открывается на каждый новый запрос. После выполнения одной или нескольких команд соединение разрывается. И тут нужно учесть ряд минусов.
CommuniGate Pro имеет ограничение числа параллельных сессий. И его можно исчерпать, если открывать, скажем, 10 соединений одновременно.
Само открытие/закрытие сессии подразумевает до 3 дополнительных команд. А это приводит к определенным издержкам. Например, для достаточно большого сервера резервное копирование может происходить дольше вплоть до 25%.
Чтобы решить эту проблему, мы начали использовать пулы соединений. Для этого был доработан модуль DSP. Мы устанавливаем соединение, а после этого передаем команды, которые хотим послать. Далее соединение поддерживается активным еще 15 секунд (и это при желании можно изменить в файле настроек), на случай, если через короткий промежуток времени понадобится послать еще команду.
Заковырка №3. Тонкости инкрементального бэкапа
Когда речь идет о хранении и защите большого объема информации, например истории совместной работы и переписки за полгода или год, очевидно, что все захотят использовать инкрементальный бэкап. Но если полную резервную копию сделать достаточно просто (берем и достаем из сервера все подряд, не разрывая сессии), для создания инкремента нужно как-то узнать, что же изменилось на сервере.
Делать это в лоб — выкачивать все снова и сравнивать с тем, что уже лежит в бэкапе, крайне непрактично. А если речь идет о корпоративном сервере на тысячи писем, то и вовсе невозможно в рабочие часы.
Решением этого вопроса занималась команда Communigate. Мы использовали дополнительную команду, которую они добавили в протокол IMAP — SYNC. Она возвращает изменения от предыдущего запроса команды Sync в данной папке. Чтобы результат был правильным, в SYNC нужно передать токен от предыдущего запуска команды.
Чтобы токены не терялись, мы записываем в их метаданные каждой резервной копии сервера Communigate (то есть в наших архивах).
Результаты и перспективы
В результате мы комбинируем различные команды расширенного протокола IMAP, который используется в CommuniGate Pro. Sync помогает составить план бэкапа, а несколько команд Fetch обеспечивают вытягивание данных из разных папок. В результате за один запрос мы можем получить достаточно большое количество элементов и делать бэкап, что называется постранично.
Как я уже говорил, DSP не хранит состояние, и поэтому все, что связано с бэкапом, мы сохраняем в метаданные архива. Бэкап CommuniGate Pro формируется слоями, чередуя данные пользователей и метаданные. Это не позволяет системе “забыть”, что и откуда было скопировано, что изменилось и как с этим дальше работать.
Благодаря тому, что в CommuniGate передача данных идет через IMAP и внутренний протокол CLI, совместными усилиями мы создали стабильную систему инкрементного бэкапа с гранулярностью до уровня пользователя. Теперь каждый отдельно взятый аккаунт CommuniGate Pro можно восстановить по требованию. А мы продолжаем работать над тем, чтобы дополнительно ускорить коммуникацию между серверами и нашей системой резервного копирования.