
Обновляем СХД без простоев и потери данных: опыт TATLIN.UNIFIED
Вы наверняка сталкивались с системами хранения данных семейства TATLIN или серверами VEGMAN. Например, когда делали заказ в интернет-магазине или пользовались другими популярными онлайн-сервисами — в глубине ИТ-инфраструктуры для них можно обнаружить продукты YADRO.
Александр Чуриков, технический эксперт отдела сервисного дизайна YADRO, рассказывает о внутренней архитектуре СХД TATLIN.UNIFIED, процессе обновлений ПО и железа и о том, как сделать их быстрыми, безопасными и удобными для инженеров.
- Как контроллеры TATLIN.UNIFIED распределяют нагрузку во время обновлений.
- Как устроен кеш: от защиты данных до адаптации под разные режимы работы.
- Как взаимодействуют ключевые компоненты системы, чтобы обновления проходили последовательно и безопасно.
- Какие инженерные решения позволяют обновлять прошивки и ОС без простоя и без заметного влияния на производительность.
Как устроена СХД: терабайт кеша и умные полки
Система хранения данных (СХД) — это программно-аппаратный комплекс. В основе TATLIN.UNIFIED лежит ОС собственной разработки: Tatlin.OS. Аппаратная часть тоже разработана нами, вместе с соответствующими прошивками. Требования к ней: отказоустойчивость, работа при выходе из строя любого компонента и обслуживание без перерыва доступа к данным.
TATLIN.UNIFIED — это высокопроизводительная система общего назначения со стандартным функционалом: файловый и блочный доступ к данным, работа под высокой нагрузкой без перерывов и поддержка умных полок, в которых располагаются диски. К СХД можно подключить до шести таких полок и в общей сложности более 500 дисков. Общий объем пространства может достигать 9 петабайт на одну систему.
Также в TATLIN.UNIFIED есть единое контроллерное шасси с батарейным модулем и 1 ТБ кеша, который организован в оперативной памяти и имеет очень сложную математическую модель. Батарейный модуль обеспечивает сохранность кеша при отключении электропитания. Алгоритмы внутренней обработки данных, в том числе и работы кеша, улучшаются от версии к версии.
Подсистема кеширования — это то, что делает систему хранения настоящей СХД. Она обеспечивает производительность при случайной записи, сопоставимую с линейной. К подсистеме кеширования предъявляются высокие требования: сохранность данных критична, поэтому есть ряд «железных» компонентов, которые помогают избежать их потери. Они отслеживают состояние окружающей среды, следят за работоспособностью батарейных модулей и так далее.
Например, при отключении электропитания оперативная память сохраняется на NVMe-диск. Дело в том, что в системе хранения работают два контроллера, и кэш на них должен быть синхронизирован. Когда клиент получает ответ от СХД, что данные записаны и можно переходить к следующему блоку, они все еще хранятся в оперативной памяти СХД. Нам нельзя их терять, пока они не записаны на диск, поэтому в случае нештатной ситуации оперативная память сбрасывается на диск.
На основе подсистемы кеширования реализованы такие функции, как снапшоты, толстые и тонкие тома, а также unmap, которая освобождает неиспользуемое пространство. В планах — добавить в TATLIN.UNIFIED дедупликацию.

В чем особенности TATLIN.UNIFIED
В системе два контроллера и батарейный модуль, объединенные в едином шасси. Есть управляющий элемент, который отвечает за работу вентиляторов, а также элементы, управляющие питанием. Для подключения полок используются SAS HBA: полки подключаются цепочкой. Также установлены PCIe-свичи с фронтенд-картами: к ним и подключаются клиенты. Подключение всегда идет к обоим контроллерам, что сделано для резервирования и повышения производительности. Контроллеры работают в режиме active-active: оба активны.


Слева направо: первый и второй контроллеры, затем батарейный модуль. Последний — очень мощный, похож на те, что ставят в электросамокатах. Такая емкость нужна, чтобы при отключении электропитания успеть сбросить около 1 ТБ данных из кеша на NVMe-диск. Это занимает несколько минут, иногда 10−20, и все это время батарейный модуль должен поддерживать работоспособность контроллеров.
Компоненты объединены в единую сеть I2C-шиной:

Каждая точка на схеме — это микроконтроллер. Прошивки для микроконтроллеров мы пишем сами. Это нужно для мониторинга работоспособности отдельных компонентов: если, например, остановятся вентиляторы и система начнет перегреваться, то мы можем отреагировать сразу, а не ждать, пока данные клиента будут утеряны.

Еще один важный элемент TATLIN.UNIFIED — это умная полка. На схеме показана всего одна полка с шестью SAS-экспандерами. Экспандер — это разветвитель, на который приходит один или несколько SAS-каналов, а дальше трафик распределяется на множество дисков: до 48 каналов. У экспандеров есть собственная прошивка.
Внутри полки по I2C-шине организован своеобразный мини-кластер. На каждом узле стоят микроконтроллеры, которые следят за работой экспандеров, вентиляторов и питания.
В случае аварии микроконтроллеры отключают неисправный экспандер и сигнализируют об этом в контроллерное шасси. Вышедший из строя экспандер заменяют новым, который автоматически определяет настройки, входит в наш мини-кластер на полке и начинает работать.

На передней панели видны три мощных вентилятора и два экспандера. Сверху устанавливаются диски — в полке их 96 штук. Сзади — еще пара экспандеров и два блока питания.
Зачем и как обновлять СХД
Разберемся, зачем нам нужны обновления:
- Новая функциональность — клиентам нужны новые фичи.
- Поддержка нового оборудования и ПО. В России много отечественных гипервизоров, и иногда под конкретный вариант нам нужно, например, модифицировать подсистемы таргетов.
- Увеличение лимитов — например, доступных логических дисков (LUN) с 500 в версии 2.5 до 700 в версии 3.1. Также в версии 2.5 мы увеличили количество поддерживаемых дисковых полок — с трех до шести.
- Повышение производительности.
- Устранение ошибок ПО.
Процедура обновления корпоративного СХД, такого как TATLIN.UNIFIED, должно удовлетворять трем основным требованиям:
- сохранять непрерывность доступа к данным,
- занимать минимальное время,
- быть максимально простой.
СХД такого класса обычно работают непрерывно в течение нескольких лет, поэтому выход из строя любого элемента не должен блокировать доступ к хранящимся данным. Даже кратковременный простой СХД может вылиться в существенные потери для бизнеса. Поэтому архитектура и сервисные процедуры системы спроектированы так, чтобы доступ к данным в любом случае был хотя бы по одному плечу.
Обновление должно занимать минимум времени, поскольку в процессе мы перегружаем контроллеры по очереди. В момент, когда один контроллер перезагружается, кеш на запись отключается, и клиент замечает падение производительности. Поэтому всю процедуру нужно провести максимально быстро. Чтобы минимизировать влияние на производительность приложений и сервисов, нужно проводить обновление в периоды минимальной нагрузки на СХД.
Как мы обновляем нашу СХД
TATLIN.UNIFIED — это программно-аппаратный комплекс, и нам нужно обновлять два основных блока:
- ПО Tatlin.OS;
- прошивки «железа»: контрольного шасси, полок, фронтенд-карт, дисков и BIOS/BMC контроллеров.
Обновление «софта»
Первый этап — подготовка к обновлению. Сервисный инженер, который проводит весь процесс обновления, должен убедиться, что:
- На компьютере, с которого выполняется обновление, установлен SSH-клиент, открыты нужные порты и так далее.
- У него есть все права и пароли для копирования образа на контроллер.
- Образ копируется в предназначенную для этого директорию.
Затем начинается процесс обновления ПО, то есть Tatlin.OS

Мы продумывали процесс обновления еще на этапе проектирования архитектуры, поэтому обновление — это неотъемлемая часть Tatlin.OS. У нас есть два stateless-контроллера: на них не хранятся данные: ни настройки, ни пользователи. Все настройки хранятся в ETCD, кластерной базе вида ключ-значение:
- менеджмент-сети,
- пулов,
- логических дисков (LUN) на базе пулов,
- access-листов.

То есть все настройки СХД хранятся в ETCD. Всем этим управляет оркестратор Pacemaker: он запускает сервисы на контроллерах и следит за их работой.
Когда мы меняем контроллер и включаем новый, он проходит инициализацию, определяет свою роль (первый или второй), обнаруживает запущенные кластерные службы, видит Pacemaker и через него поднимает нужные сервисы, подгружая значения настроек из ETCD.
Такой дизайн был заложен изначально: у нас stateless-контроллеры, поэтому при обновлении или замене не требуется вручную переносить конфигурации.
В других системах хранения, где не используются stateless-контроллеры, заметная часть времени уходит на сохранение настроек и данных (шаги 1, 3 и 5 на схеме ниже). В TATLIN.UNIFIED конфигурация хранится централизованно: контроллер включается, синхронизируется и входит в кластер.

Чем больше исправлений и нового функционала в обновлении, тем дольше идет весь процесс, так как мы вносим в Tatlin.OS много изменений. Когда мы обновляем Tatlin.OS, контроллер работает с раздела 0 (part0).

Инженер получает бандл — архив размером около 1,5−2 ГБ. Он копирует его на контроллер и запускает процесс обновления. После старта выполняется проверка системы. Один из элементов бандла — образ SquashFS, который целиком разворачивается на раздел part 1 без каких-либо модификаций.
Затем контроллер перезагружается и уже работает с новой версией. Все это быстро и просто. Также нам не нужно следить за совместимостью пакетов и определять очередность их установки: вся установка идет одним бандлом.
Кроме того, есть раздел Rescue — туда временно распаковывается бандл. И есть раздел Persistent — он предназначен для данных, которые нельзя удалять: для логов и файлов конфигурации. Pacemaker и ETCD работают в кластере, но иногда СХД отключают, и нам важно не потерять настройки — они периодически сохраняются в разделе Persistent, а также фиксируются при выключении. При старте СХД снова запускается Pacemaker: он читает данные из Persistent и поднимает кластер.
Схематически процесс обновления Tatlin.OS можно представить так:

Сначала выполняется предварительная проверка — нужно убедиться, что комплекс исправен и все компоненты работают. Иначе можно обновить и перезагрузить один контроллер, а второй, оказывается, был неисправен.
Затем образ ОС разворачивается на втором разделе, перезагружается сначала первый контроллер, затем второй, после чего вносятся изменения в кластер. Модификация кластера нужна, если вместе с релизом приходит новая фича и требуются новые ключи в ETCD или новые настройки в Pacemaker.
В финале обновления запускается постпроверка, чтобы убедиться в работоспособности всей системы.
Однако уже на первых инсталляциях мы столкнулись с неочевидным сценарием — после перезагрузки первый контроллер стартует и сообщает кластеру о своей готовности:

Но на практике серверы не успевают восстановить подключение. В результате второй контроллер тоже уходит в перезагрузку, и клиент одновременно теряет доступ к обоим контроллерам. Возникает риск потери данных, а этого мы должны всегда избегать.
Поэтому мы ввели ручную перезагрузку и добавили процедуру проверки доступности путей от сервера:

Перед стартом процедуры и в середине старта, когда первый контроллер уже запустился, — второй не перезагружается автоматически. Мы проверяем пути и доступность обоих контроллеров. После проверки подтверждаем клиенту, что все ок.
Обновление «железа»
Название раздела условное, ведь у всех «железных» компонентов TATLIN.UNIFIED есть прошивки. Чтобы организовать максимально безболезненный процесс обновления, мы занялись их серьезным изучением и выяснили много интересных нюансов.
В ранних версиях, когда мы запрашивали версию прошивки микроконтроллера, в ответ возвращался номер коммита. В итоге получалось несоответствие: файл помечен как 1.3, а прошивка отвечает 2aa8217 — непонятно, какая версия установлена. Мы модифицировали прошивку, чтобы она возвращала именно версию, а не номер коммита.
Мы сами разрабатываем BIOS/BMC, и перед началом обновления нужно узнать их текущие версии. Самый логичный путь — через IPMI, но выяснилось, что он показывает только два разряда версии BIOS: вместо 1.10.2 мы видим 1.10. Часто третий разряд фиксирует баги, поэтому мы используем два способа: узнаем точную версию через BMC CLI, либо используем Redfish.
Схема обновления прошивок экспандеров:

Если нужно обновить прошивку экспандера на первом контроллере: обновляем прошивку, выключаем контроллер, перезагружаем экспандер со второго контроллера и снова включаем первый. Процедура довольно сложная. Поэтому мы реализовали такую схему:

Сначала мы обновляем Tatlin.OS на первом и втором контроллере, затем — прошивки. Однако у наших клиентов процесс будет отличаться. У нас получается пять проверок:

Проверки занимают время сопоставимое, а часто и больше, чем сами операции на системе хранения. У наших клиентов бывает до 700 хостов, и проверка доступности всех путей на каждом из них отнимает много времени. В некоторых случаях обновление занимало полтора часа, а проверка — от трех до 12 часов. Это нас не устраивало, и мы изменили порядок обновлений.
Теперь обновляем ОС первого контроллера и сразу микрокод его аппаратных компонентов. Затем переходим ко второму контроллеру и тоже сразу обновляем его прошивки — и так далее.

В итоге мы снова пришли к трем проверкам, а время сократилось кардинально. Но обновление еще должно быть простым.
Если попытаться описать все процедуры пошагово, получится около 150 шагов, которые должен выполнить инженер. Поэтому мы все шаги разбили на 7 стадий:

Для каждой стадии мы написали скрипт, который выполняет действия, нужные именно на этой стадии. После завершения скрипт выдает понятный результат: либо «ОК», либо сообщение с описанием проблемы. Логи при этом сохраняются.
Если обновление выполняет инженер L1 или инженер партнера и сталкивается с проблемой, то он заводит тикет на следующий уровень — L2. Если там не удается решить, эскалируем на L3. Если и L3 не справляется, открываем тикет в R&D.
Сервисная служба работает круглосуточно: L1 и L2 дежурят 24/7. Есть дежурный по телефону от R&D и от L3. Даже в праздники — если случается инцидент (не только при обновлениях) — мы оперативно подключаем R&D.
Заключение
Поделюсь несколькими советами, которые пригодятся, если вы работаете с обновлениями СХД или других высоконагруженных систем.
1. Обновление нужно учитывать еще при проектировании продукта. Нельзя рассчитывать, что после создания MVP необходимости вы просто сотрете его и поставите новую версию — у клиента уже есть данные, которые нельзя потерять, поэтому обновление должно сохранять их.
Все компоненты должны иметь версионность, которую можно легко проверить штатной командой.
2. Автоматизировать надо все, что можно. Длинные скрипты лучше превращать в простые команды с минимальными вариантами — по возможности в одну. Если нужно проверить хеш-сумму, команда должна выводить простой результат: «OK» или «Error». Не надо заставлять человека сравнивать значения вручную — обычно этого никто не делает, максимум проверят пару цифр.
3. Сервисная процедура должна иметь четкую инструкцию на русском языке. В ней указываем время выполнения, требуемый уровень доступа и какие именно инженеры ее выполняют. Мы удаляем ветвления вроде «если у вас NVMe такой-то модели — сделайте шаги 1−3, иначе переходите к шагу 5». Прыжки по тексту — источник ошибок. Лучше вынести такие случаи в конец, либо сделать шаги условно безопасными для выполнения всегда — пусть скрипт сам решит, нужно ли что-то обновлять.
4. Обновление должно быть комплексным. Проектируя свой небольшой компонент, помните, что над ним есть вышестоящее оборудование и оно тоже будет обновляться. Это нужно учитывать в плане обновления и в дизайне компонента.




