Как сделаны снимки дисков в Vitastor

30.08.2023

Вообще, в природе существует всего 3 пути реализации снимков (снапшотов): “вперёд”, “назад” и “cow”. А ещё нормальные снимки должны быть атомарные. Что это всё означает?

Путь №1 — «назад», «отмена»

При записи в образ после создания снимка старая версия блока данных копируется в сущность «снимок», новая записывается по месту. Таким образом, самодостаточна наиболее новая версия, а снимки представлены как наборы изменений относительно неё «назад», как «undo логи».

Путь №2 — «вперёд», «повтор»

При создании снимка образ где-то внутри переименовывается в снимок. Создаётся новый пустой объект, олицетворяющий образ. Старые версии данных при записи остаются там же, где были. Новые данные пишутся в новый пустой образ. При чтении сначала проверяется наличие блока в новом образе, потом в старом. Таким образом, самодостаточен только наиболее старый снимок, а все остальные содержат дельты поверх него.

Путь №3 — CoW, “перенаправление”

Блоки данных лежат независимо и у каждого есть счётчик ссылок. При создании снимка создаётся копия ссылок на все блоки данных, и у всех блоков счётчик ссылок увеличивается на 1. При записи записывается новая версия блока и записывается ссылка на него в новый индекс, а счётчик ссылок у старого блока уменьшается на 1, и если приходит в 0, то он удаляется.

Плюсы/минусы

  • Путь №1 оптимизирован под быстрое удаление снимков, но откат к снимку медленный и невозможно поддерживать дерево снимков/клонов.
  • Путь №2 оптимизирован под быстрый откат к снапшоту, ценой некоторого замедления чтения (нужно проверять всю цепочку родителей).
  • Путь №3 — и удаление и откат быстрые, но ценой постоянных тормозов и при записи, и при чтении - индекс “ссылок” на блоки распухает и либо начинает требовать дополнительных чтений с диска, либо расходовать лишнюю память, а “сборка мусора” при удалении требует больше записи метаданных на диск.

В Vitastor всегда (2) и для снапшотов, и для клонов. В классических СХД зачастую (1). В цефе есть и (1) и (2), но оба сделаны плохо. В ZFS (3), так как снапшоты цепочкой, но их можно клонировать, и внутри именно CoW. И оверхед соответственный: где голый диск выжимает 168k iops randwrite Q128, ZFS даёт только 28-38k iops, в зависимости от настроек.

Атомарность снимков

Любая нормальная реализация снимков подразумевает атомарность. Потому что если снимки атомарны, то их можно спокойно делать без остановки нагрузки (ВМ/контейнера) - для приложений атомарный снимок эквивалентен дёрганью сервера из розетки, а это обычно всё-таки все переживают - ну кроме разве что ClickHouse, где это специальный компромисс.

А что есть атомарность снимка? Атомарность — это требование того, чтобы существовал момент времени T, делящий все операции записи на «старые» и «новые». То есть, такой момент времени T, чтобы любая операция записи, отправленная ранее T, попадала в снимок (в «старый» слой), а любая операция записи, отправленная позднее T, попадала в «новый» слой.

То есть, чтобы не было каши вида старый-новый-старый-новый, так как если она будет, то при попытке восстановиться из снимка можно будет наткнуться на битую ФС - из-за неконсистентности журналирования, вызванной отсутствием упорядочивания записей и fsync.

В Vitastor снапшоты атомарны в рамках одного клиента - то есть, однократно подключённого к ВМ диска либо одного демона VDUSE или NBD. Атомарные снапшоты нескольких образов тоже будут, но это спойлер на будущее. :-)