Гиперконвергентное решение AERODISK vAIR. Основа — файловая система ARDFS
Привет, читатели Хабра. Этой статьей мы открываем цикл, который будет рассказывать о разработанной нами гиперконвергентной системе AERODISK vAIR. Изначально мы хотели первой же статьей рассказать всё обо всём, но система довольно сложная, поэтому будем есть слона по частям.
Начнем рассказ с истории создания системы, углубимся в файловую систему ARDFS, которая является основой vAIR, а также немного порассуждаем о позиционировании этого решения на российском рынке.
В дальнейших статьях мы будем подробнее рассказывать о разных архитектурных компонентах (кластер, гипервизор, балансировщик нагрузки, система мониторинга и т.п.), процессе настройки, поднимем вопросы лицензирования, отдельно покажем краш-тесты и, конечно же, напишем о нагрузочном тестировании и сайзинге. Также отдельную статью мы посвятим community-версии vAIR.
Аэродиск — это вроде история про СХД? Или зачем мы вообще начали заниматься гиперконвергентом?
Изначально идея создать свой гиперконвергент пришла нам где-то в районе 2010-ого года. Тогда ещё не было ни Аэродиска, ни подобных решений (коммерческих коробочных гиперконвергентных систем) на рынке. Задача у нас была следующая: из набора серверов с локальными дисками, объединённых интерконнектом по протоколу Ethernet, надо было сделать растянутое хранилище и там же запускать виртуальные машины и программную сеть. Всё это требовалось реализовать без СХД (ибо на СХД и её обвязку просто не было денег, а своей СХД мы тогда ещё не изобрели).
Мы перепробовали много open source-решений и все-таки задачу эту решили, но решение было очень сложным, и его трудно было повторить. Кроме того, это решение было из разряда «Работает? Не трожь!». Поэтому, решив ту задачу, мы не стали дальше развивать идею превращения результата нашей работы в полноценный продукт.
После того случая мы отошли от этой идеи, но нас все равно не покидало ощущение того, что задача эта вполне решаема, а польза от такого решения более чем очевидна. В дальнейшем вышедшие HCI-продукты зарубежных компаний это ощущение только подтвердили.
Поэтому в середине 2016-ого года мы вернулись к этой задаче уже в рамках создания полноценного продукта. Тогда у нас ещё не было никаких взаимоотношений с инвесторами, потому стенд разработки пришлось покупать за свои не очень большие деньги. Набрав на Авито БУ-шых серверов и коммутаторов, мы принялись за дело.
Основной начальной задачей было создание своей, пусть простой, но своей файловой системы, которая смогла бы автоматически и равномерно распределять данные в виде виртуальных блоков на n-ном количестве нод кластера, которые объединены интерконнектом по Ethernet-у. При этом ФС должна хорошо и легко масштабироваться и быть независимой от смежных систем, т.е. быть отчуждаемой от vAIR в виде «просто хранилки».
Первая концепция vAIR
Мы намеренно отказались от использования готовых open source-решений для организации растянутого хранилища (ceph, gluster, lustre и им подобные) в пользу своей разработки, поскольку уже имели с ними много проектного опыта. Безусловно, сами по себе эти решения прекрасны, и мы до работы над Аэродиском реализовали с ними не один интеграционный проект. Но одно дело — реализовать конкретную задачу одного заказчика, обучить персонал и, возможно, купить поддержу большого вендора, и совсем другое дело — создать легко тиражируемый продукт, который будет использоваться под разные задачи, о которых мы, как вендор, возможно, даже сами знать не будем. Для второй цели существующие open source-продукты нам не подходили, поэтому решили распределенную файловую систему пилить сами.
Через два года силами нескольких разработчиков (которые совмещали работы над vAIR с работой над классической СХД Engine) добились определенного результата.
К 2018-ому году мы написали простейшую файловую систему и дополнили её необходимой обвязкой. Система объединяла по внутреннему интерконнекту физические (локальные) диски с разных серверов в один плоский пул и «резала» их на виртуальные блоки, далее из виртуальных блоков создавались блочные устройства с той или иной степенью отказоустойчивости, на которых с помощью гипервизора KVM создавались и выполнялись виртуальные машины.
С названием файловой системы мы особо заморачиваться не стали и лаконично назвали её ARDFS (догадайтесь, как это расшифровывается))
Этот прототип выглядел хорошо (не визуально, конечно, визуального оформления тогда ещё не было) и показывал хорошие результаты по производительности и масштабированию. После первого реального результата мы дали ход этому проекту, организовав уже полноценную среду разработки и отдельную команду, которая занималась только vAIR-ом.
Как раз к тому времени созрела общая архитектура решения, которая до сих пор не претерпела серьезных изменений.
Погружаемся в файловую систему ARDFS
ARDFS является основой vAIR, которая обеспечивает распределенное отказоустойчивое хранение данных всего кластера. Одна из (но не единственная) отличительных особенностей ARDFS состоит в том, что она не использует никаких дополнительных выделенных серверов под мету и управление. Так было задумано изначально для упрощения конфигурации решения и для его надежности.
Структура хранения
В рамках всех нод кластера ARDFS организовывает логический пул из всего доступного дискового пространства. Важно понимать, что пул — это ещё не данные и не форматированное пространство, а просто разметка, т.е. любые ноды с установленным vAIR-ом при добавлении к кластеру автоматически добавляются в общий пул ARDFS и дисковые ресурсы автоматически становятся общими на весь кластер (и доступными для будущего хранения данных). Такой подход позволяет на лету добавлять и удалять ноды без какого-либо серьезного влияния на уже работающую систему. Т.е. систему очень легко масштабировать «кирпичами», добавляя или убирая ноды в кластере при необходимости.
Поверх пула ARDFS добавляются виртуальные диски (объекты хранения для виртуалок), которые строятся из виртуальных блоков размером 4 мегабайта. На виртуальных дисках непосредственно хранятся данные. На уровне виртуальных дисков также задается схема отказоустойчивости.
Как можно было уже догадаться, для отказоустойчивости дисковой подсистемы мы не используем концепцию RAID (Redundant array of independent Disks), а используем RAIN (Redundant array of independent Nodes). Т.е. отказоустойчивость измеряется, автоматизируется и управляется, исходя из нод, а не дисков. Диски, безусловно, тоже объект хранилища, они, как и всё остальное, мониторятся, с ними можно выполнять все стандартные операции, в том числе и собирать локальный аппаратный RAID, но кластер оперирует именно нодами.
В ситуации, когда очень хочется RAID (например, сценарий, поддерживающий множественные отказы на маленьких кластерах), ничто не мешает использовать локальные RAID-контроллеры, а поверх делать растянутое хранилище и RAIN-архитектуру. Такой сценарий вполне себе живой и поддерживается нами, поэтому мы расскажем о нем в статье про типовые сценарии применения vAIR.
Схемы отказоустойчивости хранилища
Схем отказоустойчиовсти виртуальных дисков в vAIR может быть две:
1) Replication factor или просто репликация — этот метод отказоустойчивости прост «как палка и веревка». Выполняется синхронная репликация между нодами с фактором 2 (2 копии на кластер) или 3 (3 копии, соответственно). RF-2 позволяет виртуальному диску выдержать отказ одной ноды в кластере, но «съедает» половину полезного объема, а RF-3 выдержит отказ 2-х нод в кластере, но зарезервирует уже 2/3 полезного объема под свои нужды. Эта схема очень напоминает RAID-1, то есть виртуальный диск, сконфигурированный в RF-2, устойчив к отказу любой одной ноды кластера. В этом случае с данными будет все в порядке и даже ввод-вывод не остановится. Когда упавшая нода вернется в строй, начнется автоматическое восстановление/синхронизация данных.
Ниже приведены примеры распределения данных RF-2 и RF-3 в штатном режиме и в ситуации отказов.
Имеем виртуальную машину объемом 8МБ уникальных (полезных) данных, которая работает на 4-х нодах vAIR. Понятно, что в реальности вряд ли будет такой малый объем, но для схемы, отражающей логику работы ARDFS, этот пример наиболее понятен. AB — это виртуальные блоки по 4МБ, содержащие уникальные данные виртуальной машины. При RF-2 создаются две копии этих блоков A1+A2 и B1+B2, соответственно. Эти блоки «раскладываются» по нодам, избегая пересечения одних и тех же данных на одной ноде, то есть копия А1 не будет находится на одной ноде с копией A2. С B1 и B2 аналогично.
В случае отказа одной из нод (например, ноды №3, где содержится копия B1), данная копия автоматически активируется на ноде, где нет копии её копии (то есть копии B2).
Таким образом, виртуальный диск (и ВМ, соответственно) легко переживут отказ одной ноды в схеме RF-2.
Схема с репликацией при своей простоте и надежности болеет той же болячкой, что и RAID1 — мало полезного пространства.
2) Erasure coding или удаляющее кодирование (также известно под именами «избыточное кодирование», «стирающее кодирование» или «код избыточности») как раз существует для решения проблемы выше. EC — схема избыточности, которая обеспечивает высокую доступность данных при меньших накладных расходах на дисковое пространство по сравнению с репликацией. Принцип работы этого механизма похож на RAID 5, 6, 6P.
При кодировании процесс EC делит виртуальный блок (по умолчанию 4МБ) на несколько меньших «кусков данных» в зависимости от схемы EC (например, схема 2+1 делит каждый блок 4 МБ на 2 куска по 2МБ). Далее это процесс генерирует для «кусков данных» «куски четности» размером не более одной из ранее разделенных частей. При декодировании EC генерирует недостающие куски, считывая «выжившие» данные по всему кластеру.
Например, виртуальный диск с EC-схемой 2 + 1, реализованный на 4-х нодах кластера, спокойно выдержит отказ одной ноды в кластере так же, как и RF-2. При этом накладные расходы будут ниже, в частности коэффициент полезной емкости при RF-2 равен 2, а при EC 2+1 он будет 1,5.
Если описать проще, то суть заключается в том, что виртуальный блок разделяется на 2–8 (почему от 2-х д 8-ми см. ниже) «кусков», а для этих кусков вычисляются «куски» чётности аналогичного объема.
В итоге данные и чётность равномерно распределяются по всем нодам кластера. При этом, как и при репликации, ARDFS в автоматическом режиме распределяет данные по нодам таким образом, чтобы не допустить хранения одинаковых данных (копий данных и их четности) на одной ноде, чтобы исключить шанс потерять данные из-за того, что данные и их четность внезапно окажутся на одной ноде хранения, которая выйдет из строя.
Ниже пример, с той же виртуалкой в 8 МБ и 4-мя нодами, но уже при схеме EC 2+1.
Блоки A и B делятся на два куска каждый по 2 МБ (на два потому что 2+1), то есть на A1+A2 и B1+B2. В отличие от реплики, A1 не является копией A2, это виртуальный блок A, разделенный на две части, так же и с блоком B. Итого получаем два набора по 4МБ, в каждом из которых лежит по два двухмегабайтных куска. Далее, для каждого из этих наборов вычисляется чётность объемом не более одного куска (т.е. 2-х МБ), получаем дополнительно + 2 куска чётности (A-P и B-P). Итого имеем 4×2 данных + 2×2 четность.
Далее куски «раскладываются» по нодам так, чтобы данные не пересекались с их четностью. Т.е. A1 и A2 не будут лежать на одной ноде с A-P.
В случае отказа одной ноды (допустим, тоже третьей) упавший блок B1 будет автоматически восстановлен из чётности B-P, которая хранится на ноде №2, и будет активирован на ноде, где нет B-четности, т.е. куска B-P. В данном примере — это нода №1
Уверен, у читателя возникает вопрос:
«Все что вы описали, давно реализовано и конкурентами, и в open source-решениях, в чем отличие вашей реализации EC в ARDFS?»
А далее пойдут интересные особенности работы ARDFS.
Erasure coding с упором на гибкость
Изначально мы предусмотрели довольно гибкую схему EC X+Y, где X равен числу от 2-х до 8-ми, а Y равен числу от 1-ого до 8-ми, но всегда меньше или равному X. Такая схема предусмотрена для гибкости. Увеличение числа кусков данных (X), на которые делится виртуальный блок, позволяет снижать накладные расходы, то есть увеличивать полезное пространство.
Увеличение же числа кусков четности (Y) увеличивает надежность виртуального диска. Чем больше значение Y, тем больше нод в кластере может выйти из строя. Само собой, увеличение объема четности снижает объем полезной емкости, но это плата за надежность.
Зависимость производительности от схем EC почти прямая: чем больше «кусков», тем ниже производительность, тут, понятное дело, нужен сбалансированный взгляд.
Такой подход позволяет администраторам максимально гибко конфигурировать растянутое хранилище. В рамках пула ARDFS можно использовать любые схемы отказоустойчивости и их комбинации, что тоже, на наш взгляд, очень полезно.
Ниже приведена таблица сравнения нескольких (не всех возможных) схем RF и EC.
Из таблицы видно, что даже самая «махровая» комбинация EC 8+7, допускающая потерю одновременно до 7-ми нод в кластере, «съедает» меньше полезного пространства (1,875 против 2), чем стандартная репликация, а защищает в 7 раз лучше, что делает этот механизм защиты хоть и более сложным, но значительно более привлекательным в ситуациях, когда нужно обеспечить максимальную надёжность в условиях нехватки дискового пространства. При этом нужно понимать, что каждый «плюс» к X или Y будет дополнительным накладным расходом на производительность, поэтому в треугольнике между надежностью, экономией и производительностью нужно выбирать очень внимательно. По этой причине отдельную статью мы посветим сайзингу удаляющего кодирования.
Надежность и автономность файловой системы
ARDFS локально запускается на всех нодах кластера и синхронизирует их собственными средствами через выделенные Ethernet-интерфейсы. Важным моментом является то, что ARDFS самостоятельно синхронизирует не только данные, но и метаданные, относящиеся к хранению. В ходе работы над ARDFS мы параллельно изучали ряд существующих решений и мы обнаружили, что многие делают синхронизацию меты файловой системы с помощью внешней распределенной СУБД, которую мы тоже используем для синхронизации, но только конфигураций, а не метаданных ФС (об этом и других смежных подсистемах в следующей статье).
Синхронизация метаданных ФС с помощью внешней СУБД решение, конечно, рабочее, но тогда бы консистентность данных, хранимых на ARDFS, зависела бы от внешней СУБД и её поведения (а она, прямо скажем — дама капризная), что на наш взгляд плохо. Почему? Если метаданные ФС повредятся, самим данным ФС тоже можно будет сказать «до свидания», поэтому мы решили пойти по более сложному, но надежному пути.
Подсистему синхронизации метаданных для ARDFS мы сделали самостоятельно, и живет она абсолютно независимо от смежных подсистем. Т.е. ни одна другая подсистема не может повредить данные ARDFS. На наш взгляд — это наиболее надежный и правильный путь, а так ли это на самом деле — покажет время. Кроме того, с таким подходом появляется дополнительное преимущество. ARDFS можно использовать независимо от vAIR, просто как растянутую хранилку, чем мы непременно будем пользоваться в будущих продуктах.
В итоге, разработав ARDFS, мы получили гибкую и надежную файловую систему, дающую выбор, где можно сэкономить на емкости или отдать все на производительности, или же сделать хранилище сверхнадежным за умеренную плату, но снизив требования к производительности.
Вместе с простой политикой лицензирования и гибкой моделью поставки (забегая вперед, лицензируется vAIR по нодам, а поставляется либо софтом, либо как ПАК) это позволяет очень точно заточить решение под самые разные требования заказчиков и в дальнейшем легко поддерживать этот баланс.
Кому это чудо нужно?
С одной стороны, можно сказать, что на рынке уже есть игроки, у которых серьезные решения в области гиперконвергента, и куда мы, собственно, лезем. Кажется, что это утверждение верно, НО…
С другой стороны, выходя «в поля» и общаясь с заказчиками, мы и наши партнеры видим, что это совсем не так. Задач для гиперконвергента много, где-то люди просто не знали, что такие решения есть, где-то это казалось дорого, где-то были неудачные тесты альтернативных решений, а где-то вообще покупать запрещают, ибо санкции. В общем поле оказалось непаханым, поэтому мы пошли поднимать целину))).
Когда СХД лучше чем ГКС?
По ходу работы с рынком нас часто спрашивают, когда лучше применять классическую схему с СХД, а когда — гиперконвергент? Многие компании — производители ГКС (особенно те, у которых в портфеле нет СХД) говорят: «СХД отживает своё, гиперконвергент only!». Это смелое заявление, но оно не совсем отражает действительность.
По правде говоря, рынок СХД, действительно, переплывает в сторону гиперконвергента и подобных решений, но всегда есть «но».
Во-первых, построенные ЦОД-ы и ИТ-инфраструктуры по классической схеме с СХД вот так просто не перестроишь, поэтому модернизация и достройка таких инфраструктур — это ещё наследие лет на 5–7.
Во-вторых, те инфраструктуры, которые строятся сейчас в массе своей (имеется ввиду РФ) строят по классической схеме с применением СХД и не потому, что не знают люди о гиперконвергенте, а потому, что рынок гиперконвергента новый, решения и стандарты ещё не устоялись, ИТ-шники еще не обучены, опыта мало, а строить ЦОД-ы надо здесь и сейчас. И эта тенденция ещё на 3–5 лет (а потом ещё наследие, см. пункт 1).
В-третьих, чисто техническое ограничение в дополнительных небольших задержках в 2 миллисекунды на запись (без учета локального кэша, конечно), которые являются платой за распределенное хранение.
Ну и не будем забывать об использовании больших физических серверов, которые любят вертикальное масштабирование дисковой подсистемы.
Есть много нужных и популярных задач, где СХД ведет себя лучше, чем ГКС. Тут с нами конечно же не согласятся те производители, у которых в продуктовом портфеле нет СХД, но мы готовы аргументировано спорить. Само собой, мы, как разработчики обоих продуктов в одной из будущих публикаций обязательно проведем сравнение СХД и ГКС, где наглядно продемонстрируем, что в каких условиях лучше.
А где гиперконвергентные решения будут работать лучше СХД?
Исходя из тезисов выше, можно сделать три очевидных вывода:
- Там, где дополнительные 2 миллисекунды задержки на запись, которые устойчиво возникают в любом продуктиве (сейчас речь не идет о синтетике, на синтетике можно и наносекунды показать), являются некритичными, гиперконвергент подойдет.
- Там, где нагрузку из больших физических серверов можно превратить в много маленьких виртуальных и распределить по нодам, там тоже гиперконвергент зайдёт хорошо.
- Там, где горизонтальное масштабирование более приоритетно, чем вертикальное, там тоже ГКС зайдут прекрасно.
Какие это решения?
- Все стандартные инфраструктурные сервисы (служба каталогов, почта, СЭД, файловые серверы, небольшие или средние ERP и BI системы и пр.). Мы это называем «общие вычисления».
- Инфраструктура облачных провайдеров, где необходимо быстро и стандартизованно горизонтально расширяться и легко «нарезать» большое количество виртуальных машин для клиентов.
- Инфраструктура виртуальных рабочих столов (VDI), где много маленьких пользовательских виртуалок запускаются и спокойно «плавают» внутри единообразного кластера.
- Филиальные сети, где в каждом филиале нужно получить стандартную, отказоустойчивую, но при этом недорогую инфраструктуру из 15–20 виртуальных машин.
- Любые распределенные вычисления (big data-сервисы, например). Там, где нагрузка идет не «вглубь», а «вширь».
- Тестовые среды, где допустимы дополнительные небольшие задержки, но есть бюджетные ограничения, ибо это тесты.
На текущий момент именно для этих задач мы сделали AERODISK vAIR и именно на них делаем упор (пока успешно). Возможно, скоро это изменится, т.к. мир не стоит на месте.
Итак…
На этом первая часть большого цикла статей завершена, в следующей статьей мы расскажем об архитектуре решения и используемых компонентах.
Будем рады вопросам, предложениям и конструктивным спорам.