Скопируй и спаси: как устроена репликация в TATLIN.BACKUP

Серьезное хранилище резервных копий не просто дедуплицирует данные и не теряет все при вылете одного диска — оно как минимум состоит из двух нод на случай, если одна сломается. Серьезное хранилище умеет делать снапшоты, чтобы злоумышленник не испортил всё, получив доступ к файловым шарам. У такого хранилища есть дедупликация на клиенте. А еще действительно серьезное хранилище умеет реплицировать данные на другую систему. Без всех этих опций индустрия просто не рассмотрит такое Purpose Built Backup Appliance как достойного кандидата занять вакантное место в стойке.
Под катом я расскажу о репликации в TATLIN.BACKUP: зачем нужно, как работает, какие особенности есть.
Что такое репликация и почему она важна всем
С определенной точки зрения защита данных сводится к тому, что они копируются между точками хранения, находящимися в разных средах. Если одна из точек будет уничтожена, вторая останется в сохранности и данные не будут потеряны. Более того, репликация даже просочилась в регуляторные требования для финансовых и медицинских информационных систем.
Можно копировать между дисками с помощью RAID, тогда копия уходит на сторонний носитель. Другой способ — репликация, копирование между системами хранения данных. Здесь возможны разные сценарии:
СХД стоят в одной стойке;
СХД стоят в одном дата центре;
СХД в разных дата-центрах на одном континенте;
СХД в разных дата-центрах на разных континентах.
Репликация между системами разблокирует множество возможностей защиты: от банальной пересылки только что сохраненных данных до концепции «бункера».
Тем временем угроз потери данных становится только больше: кибератаки, аварии, случайные ошибки администраторов, а в последнее время и угроза физического уничтожения целой площадки. Если у вас есть хранилище резервных копий, которое не удастся вывести из строя, вы всегда сможете восстановить критические для бизнеса системы.
Как копировать
Для начала договоримся о терминах: есть источник и цель репликации. Данные из источника текут в цель. Между ними существует репликационное отношение, у которого есть направление — откуда и куда данные идут.
Кратко напомню: с NAS-системами клиенты общаются по протоколам обмена файлового уровня, и пользователи работают с файлами. В SAN с СХД клиенты общаются по протоколам обмена блочного уровня и работают с дисками. Получается, что в NAS гранулярность репликации может быть очень произвольной: по файлам, директориям или по всей файловой системе. В SAN репликационным отношением связываются диски.
Тут возникает логичный вопрос: не дороговато ли по времени и нагрузке на сеть копировать терабайтные файлы или диски целиком? Дороговато. По этой причине действительно дорогой выходит первая репликация. А все остальные досылают разницу разной степени гранулярности в зависимости от метода. При репликации дисков могут досылать треки, при репликации файлов rsync досылается разница в файлах: подходов много. Так или иначе, каналы не резиновые, а RPO и RTO надо соблюдать.
Концептуально сама репликация может быть устроена следующими способами:

Синхронная репликация нужно в условиях нагруженных систем с высокой стоимостью секунды простоя и отсутствием толерантности к потере данных. Такие системы обычно защищаются с помощью механизма аварийного восстановления, и переключение на резервный сайт происходит прозрачно.
Асинхронная репликация применяется, если соединение с СХД медленное или нестабильное. СХД может находиться на другом континенте. В случае асинхронной репликации данные объединяются в батчи разного рода в зависимости от конкретной реализации и пересылаются по сети.
Если говорить более инженерным языком: тип репликации подбирается в зависимости от целевых RPO и RTO.
TATLIN.BACKUP (далее просто TB) предназначен для хранения резервных копий, поэтому репликация:
не требовательна к задержке, но требовательна к пропускной способности;
может происходить по медленным каналам;
работает как защита не только от уничтожения хранилища, но и на случай атаки.
В таких условиях стоит более детально рассмотреть репликацию снапшотов, о которых уже было рассказано в этой статье.
Репликация снапшотов в TATLIN.BACKUP

Концептуально репликация устроена достаточно просто:
Берем два снапшота.
Считаем разницу.
Пересылаем разницу.
Но это пока мы не начинаем разбираться, что действительно происходит.
Гранулярность репликации — это снапшот Virtual File System, виртуальной файловой системы (VFS). VFS в общем смысле — это аналог файловой системы из Linux. Просто за счет дедупликации она может оказаться практически безразмерной.
Что важного со снапшотом можно сделать:
создать,
откатить к нему VFS,
смонтировать в read-only-режиме,
удалить.
Принципиально для репликации достаточно иметь два снапшота: предыдущий и пересылаемый. Для них же достаточно уметь считать разницу.
Таким образом, репликация распадается на ряд задач:
найти разницу,
передать разницу,
сохранить разницу,
применить разницу.
Хранение данных, обработка IO, создание снапшотов — все находится в ведении файловой системы, которую мы тоже разрабатываем сами.
Архитектурно важен следующий вопрос: а насколько гибким должен быть механизм репликации, который предоставляет TBFS (TATLIN BACKUP File System)? Специфика разработки файловых систем предполагает кучу проблем вокруг сериализации, обратной совместимости, поддержки старых СХД-клиентов. Так что хотелось заложиться сразу по максимуму, чтобы потом высокоуровневый сервис-оркестратор репликации взаимодействовал с лаконичным, но комбинаторно мощным интерфейсом. Иными словами, нам бы действительно не хотелось железно привязываться к концепции двух снапшотов, чтобы в дальнейшем не получить проблем с переработкой и совместимостью.
Как устроена репликация в TBFS
Направление копирования
Первый важный архитектурный вопрос: кто инициирует репликацию?
В репликации есть две стороны: источник и цель.

Происходит копирование снапшотов с источника на цель. Задача оркестратора репликации состоит в том, чтобы инициировать пересылку. Когда задумываешься об этом, первое решение, которое приходит в голову — инициация пересылки с источника. Снапшот создается — инициатор отправляет. Однако в таком случае TB-цель должна быть открыт для входящих соединений и, соответственно, для кибератак.
Что, если инициация будет происходить на цели, а не на источнике? В таком случае цель может исполнять роль защищенного хранилища, недоступного инфраструктуре. Источник же будет доступен инфраструктуре и всем СРК. Инициализация копирования будет оркестрироваться в таком случае со стороны цели. В случае заражения вредоносному ПО будет затруднительно доступиться до TB-цели, закрытой файрволом. Поэтому TB-цель у нас и инициализирует реплику.
Найти разницу
В чем может быть гибкость в поиске снапшотов?
Например, в том, что TBFS на самом деле может найти разницу между двумя любыми снапшотами. Это позволяет потенциально строить более гибкие системы с аварийным восстановлением, которое включает снятие бэкапов с записью уже на цель репликации, перенаправление репликации при переключении с площадки на площадку, возможность реализовать торрент при скачивании данных из сети.
VFS можно откатить к какому-то снапшоту этой же VFS, не поглощая этот снапшот. Откат провоцирует ветвление дерева снапшотов, так более ранний снапшот может оказаться не в той ветке. Принципиально это разрешено, но в контексте репликации требуется хотя бы один общий снапшот-предок для источника и приемника. Если его нет, придется передавать целиком.
Поэтому TBFS при расчете разницы на обеих сторонах определяет ближайшего общего предка, и если он есть, то ищет разницу именно с ним. Затем открывается поток изменений, который абстрагирует получение изменений для дальнейшей пересылки.

Пересылка
В этой статье мы уже рассказывали про T-BOOST — файловый протокол с функцией дедупликации на источнике, чтобы передавать только уникальные данные. Такой протокол хорошо ложится в концепцию репликации, когда передаются только изменения.
Строго говоря, есть два потока изменений: изменения метаданных и изменения данных, то есть inode, экстенты (длинные непрерывные последовательности байт) и блоки данных, из которых экстенты состоят. Обрабатываются они отдельно.
Передачу экстентов удалось положить на T-BOOST: наше key-value-хранилище экстентов и блоков данных отделено от сервиса inode. Это сильно сократило сроки разработки и позволило переиспользовать код. Обрабатываются экстенты не просто отдельно, мы реализовали параллелизацию скачивания: несколько экстентов одного и того же файла могут скачиваться одновременно. Блоки данных передаются сжатыми и хранятся в контейнерах. Зачастую файлы состоят из сотен экстентов, так параллелизация позволяет значительно ускорить скачивание снапшотов с небольшим числом крупных файлов.
Метаданные разных файлов также могут скачиваться параллельно, для этого мы реализовали специальный протокол.
Кроме того, удалось задействовать уже существующие механизмы защиты данных от одновременной очистки Garbage Collector. Это позволило не плодить новые сущности и достаточно легко согласовать все возможные комбинации ситуаций: с I/O на целевую машину в другую VFS, запуски GC, репликацию, создание снапшотов. Тут наша основная сложность в том, что дедупликация глобальная, и она в некотором смысле связывает все эти процессы.

Таким образом, как и раньше, гарантируется устойчивость к сбоям питания: базы останутся в консистентном состоянии.
Сохранить и применить разницу
Для каждой VFS и каждого снапшота в ней есть своя база данных, которая содержит метаданные файлов, записанных в TBFS. Параллельно существует хранилище экстентов, которое хранит данные. Передача приводит к созданию еще одной базы метаданных и пополнению хранилища экстентов.
Передача базы оптимизирована за счет знания о ближайшем общем предке на TB-источнике и TB-цели. Это позволяет использовать базу общего предка как «основу» и применить к ней разницу с последним созданным снапшотом на источнике. Благодаря структуре базы можно остановить внесение изменений и продолжить после за счет транзакционного доступа и WAL.
В подобном механизме сохранение снапшота — это создание базы, а применение — это простая процедура копирования базы снапшота на место базы VFS.
Прерывание репликации и НЕОЖИДАННОЕ прерывание репликации
Нам показалось логичным, чтобы оркестратор репликации не заботился о том, что произойдет, если вдруг разорвется соединение и снапшот скопируется не полностью. Гарантия возможности продолжить вынесена на сторону TBFS.
Пока снапшот в состоянии incomplete, он не сохранен и его скачивание можно просто продолжить. Сделать это можно за счет механизма поиска изменений: открыть поток изменений между любыми снапшотами, даже не до конца скачанными. Дополнительно у нас есть интервальная фиксация на диск, чтобы потери в случае разрыва не привели к необходимости повторного скачивания крупных объемов данных.
Оркестратор репликации
Оркестратор репликации устанавливает отношение репликации между двумя TB, а затем управляет репликацией. Это не такая простая задача, потому что отношения должны быть доверительные, а стороны — совместимые. TATLIN.BACKUP не может реплицироваться на себя. А сама передача снапшотов может быть затруднена сбоями сети, сбоями железа, рестартами сервисов… Короче всем, что мы так «любим».
Как и у многих других СХД, у каждого TB есть свой уникальный идентификатор для установления отношений. Он используется в процессе изначального «рукопожатия».
Партнерство может разорваться с консистентным изменением конфигурации обеих сторон, но его можно разорвать и в одностороннем порядке. Это полезно, если одна из машин сломана или недоступна. После установки партнерства можно делать очень много интересного:
создавать репликационные пары между системами (партнерами);
запускать, останавливать, приостанавливать репликацию пары;
смотреть историю запусков репликации для пары;
организовывать запуск репликации по расписанию.
Важно указать, что инициализация репликации делается оркестратором на стороне TB-цели аналогично тому, как это сделано в TBFS. Это позволяет глобально организовать закрытие портов на TB-цели. Если порты цели закрыты , для цели предусмотрена специальная команда, вызов которой проверить состояние источника. Если источник ответит, что успешно проинициализирован, то цель тоже переведет свое состояние в готовое к работе.
А еще мы разрешаем создавать пользовательские снапшоты на стороне источника или цели.
Организация репликации
В данный момент репликация снапшотов может отработать:
По запросу. В этом случае оркестратор контролирует, что на снапшот запущено не более одной сессии репликации.
По расписанию. В этом случае оркестратор не начинает создание нового снапшота, пока старый не передался до конца, даже если по расписанию пришло время.
Направление копирования и длина цепочки потенциально не ограничены со стороны TBFS, но в данный момент оркестратор поддерживает конфигурацию один-к-одному и двунаправленную.

Иными словами, если снапшоты VFS1 копируются с A на B, то для VFS2 направление может быть противоположным. Ограничений на направление копирования разных VFS в рамках пары TB нет.
Сам алгоритм репликации упрощенно выглядит следующим образом:
На источнике создается снапшот VFS.
Снапшот передается в VFS TB-цели.
VFS восстанавливается к снапшоту.
Таким образом, VFS всегда готова к монтированию и для нее будет выводиться корректная статистика.
Благодаря немедленному применению снапшота получить доступ к скопированным данным можно двумя способами:
создать снапшот VFS и cмонтировать его в режиме RO;
удалить репликационную пару и просто смонтировать VFS.
Дальнейшее развитие

Архитектура репликации получилась достаточно гибкой, и нам открывается несколько интересных возможностей:
Организация бункера — TB с закрытыми портами, который забирает снапшоты с источника и буквально недоступен для атак.
Создание сложных цепочек репликации — каскады, топологии типа «звезда» и многие другие.
Организация «торрент-сети», состоящей из TATLIN.BACKUP. В таком режиме пользовательские данные скачиваются не только с TB источника, но и с других — главное, чтобы там были нужные экстенты и нужные блоки данных. Это возможно за счет того, что ключи экстентов уникальны, а содержимое блока определяет его ключ.
FASTCOPY файлов между VFS и между отдельными системами, когда файл не восстанавливается целиком, а копируются его метаданные напрямую из базы в базу. Это сокращает количество промежуточных шагов и ускоряет процесс. Для этого вполне может быть использован протокол репликации.
Разработка быстрой первой репликации, когда данные собираются не по экстентам, а целыми контейнерами, которые являются минимальной единицей хранения.
Копирование снапшотов в существующие VFS. Это разрешит запуск обратной репликации при переключении на резервный сайт.
Еще можно организовать запись бэкапа с помощью T-BOOST сразу на два TB — получается своего рода синхронная репликация, которая за счет дедупликации еще и достаточно быстро должна работать. Будет больше репликации хорошей и разной для надежной инфраструктуры хранения резервных копий.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.