Еще год назад мы считали, что снапшоты без репликации не являются приоритетом для нашей команды. Но практика показала обратное: вирусы-шифровальщики, сбои и ошибки могут повредить резервные копии и нарушить их целостность. Чтобы защитить данные и при необходимости быстро восстановить их в неизменном виде, мы реализовали поддержку снапшотов в TATLIN.BACKUP. Новый функционал уже доказал свою эффективность и получил положительные отзывы клиентов.
Меня зовут Ростислав, я эксперт по разработке ПО отдела систем обработки данных в YADRO. Сегодня разберемся, как устроены наши снапшоты и какие у них особенности. Для этого совершим экскурс в мир систем хранения данных (СХД) и рассмотрим их устройство.

Файловые и блочные СХД
Прежде чем перейти к устройству снапшотов в TATLIN.BACKUP, поговорим о способах доступа СХД к данным. Их можно разделить на две большие категории:
блочные (SAN, Storage Area Network),
файловые (NAS, Network Attached Storage).
Способ доступа определяется протоколом, который связывает хост, выполняющий операции ввода-вывода, и СХД, где хранятся данные.
Типичный пример блочного протокола — SCSI (Small Computer System Interface). Он передает в СХД небольшие команды — например, на чтение или запись блоков данных по смещению с использованием адресации LBA (Logical Block Addressing).
В блочной СХД базовой единицей хранения выступает логический диск (LUN, Logical Unit Number). Диск разбит на блоки фиксированного размера, и работать можно с ними только целиком. Чтобы изменить один байт, нужно считать весь блок, внести изменения и записать его обратно.
В файловых протоколах, например CIFS (Common Internet File System), команды оперируют файлами, а не блоками. СХД с файловым доступом полностью управляет файловой системой и «знает», что такое файл, его метаданные и структуру. Пользователь напрямую не видит физические диски — они отсутствуют в протоколе.
Таким образом, в СХД с файловым доступом мы получаем большую гибкость при реализации снапшотов, чем в системе с блочным доступом:
файловые СХД позволяют делать снапшоты как на уровне диска, так и на уровне файловой системы,
блочные СХД — только на уровне диска.
Снапшоты: какие они бывают и зачем нужны
Снапшот — это зафиксированное состояние данных в определенный момент времени. Он позволяет в любой момент вернуться к этому состоянию, восстановив систему после сбоев, ошибок или атак. При этом текущая рабочая версия данных продолжает изменяться независимо от снапшота.
Такая возможность полезна в ряде сценариев:
восстановление после атаки вируса-шифровальщика или случайных пользовательских ошибок,
фиксация данных для аудита и соответствия регламентам,
защита логической целостности информации,
репликация данных между СХД,
анализ изменений во времени.
Существует несколько способов создания и хранения снапшотов, разберем их ниже.
Что такое маппер в СХД TATLIN.UNIFIED: тонкие тома, снапшоты и клоны.
Полное копирование — берем все данные и копируем в новый набор. Метод работает всегда, но в современных системах почти не используется — он слишком медленный и требует много дискового пространства.

Copy-on-Write (CoW) — с этим подходом при создании снапшота ничего не копируется. Система создает метаданные, указывающие на те же блоки данных, что и исходный логический диск. Снапшот и исходный логический диск сначала ссылаются на одни и те же блоки, занимая минимум места. Затем, когда в исходный логический диск происходит запись:
Определяется блок данных, который будет изменен.
Этот блок, который нужен для сохранения состояния снапшота, копируется в специальную область — «пространство снапшота». На его место записывается измененный блок.
Метаданные снапшота обновляются, чтобы указывать на сохраненный блок.

Copy-on-Write позволяет мгновенно создавать снапшот, а дисковое пространство используется только при изменениях. Однако у этого подхода есть недостаток по сравнению с Redirect-on-Write: поскольку нужно выполнить три операции ввода-вывода (одну на чтение и две на запись), то производительность системы в процессе записи снижается. Также снапшоты в CoW со временем фрагментируются.
В случае с Redirect-on-Write (RoW), как и с CoW, создание снапшота происходит практически моментально, но схема изменения данных другая:
Новые данные записываются в свободное место на диске.
Метаданные исходного логического диска обновляются, чтобы указывать на новый блок с измененными данными.
Метаданные снапшота продолжают указывать на старый блок, который остается неизменным вплоть до удаления снапшота.
RoW работает быстрее, так как требует выполнения только двух операций ввода-вывода: чтение и запись. Однако у этого подхода есть недостаток: со временем сам диск может фрагментироваться, соответственно, время доступа к данным на нем — увеличиваться.

Во многих СХД предпочтение отдают RoW — поскольку он уменьшает задержку записи (write latency).
Описанные выше подходы к созданию снапшотов используются в блочных СХД, которые работают с логическими дисками. TATLIN.BACKUP — это файловая СХД. Она оперирует файлами и их метаданными, поэтому «знает» точно, что и где хранится.
Файловый доступ позволяет реализовать снапшоты гранулярностью меньше, чем диск, опираясь на метаданные файловой системы. В нашем случае снапшот делается для VFS (Virtual File System). Также это упрощает разработку, потому что отпадает необходимость согласовывать блочный снапшот с дедупликацией в TATLIN.BACKUP.
Поэтому снапшоты в нашей СХД — файловые, а не блочные.
Как реализованы снапшоты в TATLIN.BACKUP
TATLIN.BACKUP — это система хранения данных с файловым доступом и глобальной дедупликацией. Она режет файлы на блоки данных (чанки) переменной длины и хранит их так, чтобы одинаковые блоки существовали в системе только один раз.
Подробнее об архитектуре TATLIN.BACKUP можно прочитать в статье о создании дедуплицирующей файловой системы для СХД с нуля.
Три важных термина, которые помогут лучше понять принцип работы снапшотов в нашей СХД:
Чанк (блок данных) — минимальная единица данных. В TATLIN.BACKUP имеет переменную длину: в среднем 10–12 килобайт.
Экстент — структура, которая описывает непрерывную последовательность чанков. Экстент не хранит данные, а содержит ссылки на чанки.
Уникальный идентификатор экстента — фиксированное значение, с помощью которого происходит идентификация конкретного экстента в системе.
В отличие от классических файловых систем (например, ext4), которые выделяют фиксированные блоки на диске, TATLIN.BACKUP:
Режет файл специальным алгоритмом на чанки произвольного размера.
Проверяет каждый чанк на уникальность.
Сохраняет его в контейнеры фиксированного размера на диск.
Из непрерывной последовательности чанков формируется экстент, которому присваивается уникальный идентификатор. Файл в TATLIN.BACKUP представляет собой набор идентификаторов экстентов:

У каждого экстента есть набор основных свойств:
уникальный идентификатор,
неизменяемость (immutability) — при модификации файла всегда создается новый экстент, при этом старый остается неизменным,
может содержать ссылки на один или несколько чанков.
Поэтому для создания снапшота достаточно скопировать список идентификаторов. При этом мы работаем только с метаданными, а сами данные в хранилище не перемещаются. Неизменяемость экстентов означает, что в результате модификации другого файла данные не будут перезаписываться.
Процесс создания снапшота файловой системы:
Берем список идентификаторов экстентов, на которые ссылаются файлы в файловой системе.
Копируем выбранные идентификаторы в метаданные нового снапшота.
При этом не нужно копировать сами чанки и экстенты. Снапшот фиксирует состояние файловой системы в заданный момент времени, для чего мы просто копируем идентификаторы на нужные экстенты.

Такой подход к созданию снапшотов имеет три ключевых преимущества, особенно важных для СХД:
Скорость — создание снапшота сводится к копированию набора идентификаторов экстентов. Эти метаданные хранятся в специализированной базе на быстрых носителях, поэтому копирование проходит быстро.
Безопасность — экстенты неизменяемы, поэтому снапшот всегда останется консистентным.
Экономия дискового пространства — данные физически хранятся в одном экземпляре, а повторно используются через ссылки.
Избавляемся от мусора
В TATLIN.BACKUP удаление файла или снапшота не означает мгновенного освобождения дискового пространства. Дело в том, что:
один чанк может быть использован сразу в нескольких экстентах,
один экстент может быть связан с несколькими снапшотами.
Пока существует хотя бы один владелец, удалять объект нельзя. Поэтому мы разработали сборщик мусора (garbage collector), который периодически анализирует метаданные и удаляет бесхозные объекты.
В классических блочных СХД все просто: удалили LUN — освободили место. В файловой СХД, особенно с дедупликацией, ситуация сложнее: нужно пройти цепочку владения от файлов и снапшотов до чанков и удалить только те объекты, у которых нет владельцев. Есть два алгоритма поиска и удаления мусора:
Mark-and-Sweep (алгоритм пометок) — проходит по всем объектам и помечает достижимые (live), а недостижимые (dead) — удаляет. Похожим образом работает сборщик мусора в Java или Go.
Reference Counting (счетчик ссылок) — у каждого объекта есть один или несколько владельцев, при обнулении счетчика объект удаляется.
В TATLIN.BACKUP мы выбрали алгоритм Mark-and-Sweep по нескольким причинам. Основная проблема Reference Counting заключается в том, что экстенты и чанки хранятся на дисках и обновление счетчика ссылок потребовало бы частых синхронных записей. Кроме того, если питание СХД будет отключено, то счетчик ссылок может получить неверные значения, что приведет к ошибкам.
Наконец, наша иерархическая модель данных позволяет обойти дерево метаданных в один проход, что делает Mark-and-Sweep оптимальным выбором.

Пошаговая схема работы алгоритма:
Обойти все файлы и снапшоты, чтобы собрать список используемых экстентов.
Обойти хранилище экстентов и по списку, сформированному на предыдущем шаге, удалить неиспользуемые.
Для каждого оставшегося экстента собрать список чанков.
Пройти по хранилищу чанков и удалить все неиспользуемые.
Благодаря такому подходу удаление файлов и снапшотов происходит мгновенно для пользователя, однако требует значительных вычислительных ресурсов и времени на фактическую очистку данных. Поэтому пользователи заранее планируют и настраивают запуск сборщика мусора между интервалами бэкапа, а также могут регулировать интенсивность его работы, чтобы он не препятствовал операциям чтения и записи.
Результаты тестов трех сценариев резервного копирования с Кибер Бэкап и TATLIN.BACKUP: более 4 000 ГБ за 11 минут.
Что дальше?
Снапшоты — один из ключевых инструментов в СХД, который позволяет эффективно защищать резервные копии от любых изменений и угроз. Их использование открывает путь к ряду важных возможностей, которые мы планируем внедрить в TATLIN.BACKUP.
Во-первых, это интеграция с TBoost SDK и управление снапшотами через REST. T-BOOST — это проприетарный протокол дедупликации данных, разработанный командой TATLIN.BACKUP. Он оптимизирует процесс передачи данных, сокращая их объем и снижая нагрузку на сеть. Следующим шагом в развитии технологии станет внедрение TBoost SDK — библиотеки, позволяющей интегрировать T-BOOST в сторонние программные комплексы.
SDK обеспечит прямое взаимодействие с файловыми системами, минуя FUSE, механизм ядра Linux, позволяющий смонтировать userspace файловую систему на папку. Так мы обойдем ограничения FUSE, обращение к которому снижает производительность по сравнению с файловой системой в ядре, и добьемся более глубокой интеграции с системами резервного копирования (СРК). Это позволит:
создавать консистентные снимки виртуальной файловой системы по требованию СРК,
гарантировать согласованность не только отдельного снапшота, но и всей цепочки — это особенно важно при резервном копировании взаимосвязанных систем.
Во-вторых, снапшот в TATLIN.BACKUP можно использовать как единицу репликации. Он будет представлять собой накапливаемую дельту изменений, которую можно отправить на удаленную систему для репликации. Такой подход позволит:
минимизировать объем передаваемых данных,
ускорить синхронизацию между основным и резервным хранилищем,
повысить надежность передачи, так как репликация будет выполняться атомарно на уровне готовых снапшотов.
Наша команда планирует в ближайшее время сосредоточиться на реализации именно этих двух возможностей. В следующей статье расскажем о результатах и опыте внедрения.
Комментарии (2)
gaussssss
02.09.2025 12:16Но практика показала обратное: вирусы-шифровальщики, сбои и ошибки могут повредить резервные копии и нарушить их целостность. Чтобы защитить данные и при необходимости быстро восстановить их в неизменном виде, мы реализовали поддержку снапшотов
А чем отличается создание снапшотов от резервного копирования в плане защищённости от порчи вирусами и сбоями? И то и другое можно повредить.
vmcore
1) с RoW каждая write операция превращается минимум в две, причем сначала нужно дождаться записи анных в новый блок, только потом указатель на него писать. значит если уровень выше делает sync (в виде флага к req или отдельный flush req), то write latency увеличивается в два раза?
2) как выбирать размер блока? на одном томе может быть несколько логических с разными fs и, соответственно, разными собственными блоками? если размер блока снапшота больше размера блока fs, то write провращается в read-write