forked from vitalif/vitastor
582 lines
50 KiB
Markdown
582 lines
50 KiB
Markdown
## Vitastor
|
||
|
||
[Read English version](README.md)
|
||
|
||
## Идея
|
||
|
||
Я всего лишь хочу сделать качественную блочную SDS!
|
||
|
||
Vitastor - распределённая блочная SDS, прямой аналог Ceph RBD и внутренних СХД популярных
|
||
облачных провайдеров. Однако, в отличие от них, Vitastor быстрый и при этом простой.
|
||
Только пока маленький :-).
|
||
|
||
Архитектурная схожесть с Ceph означает заложенную на уровне алгоритмов записи строгую консистентность,
|
||
репликацию через первичный OSD, симметричную кластеризацию без единой точки отказа
|
||
и автоматическое распределение данных по любому числу дисков любого размера с настраиваемыми схемами
|
||
избыточности - репликацией или с произвольными кодами коррекции ошибок.
|
||
|
||
## Возможности
|
||
|
||
Vitastor на данный момент находится в статусе предварительного выпуска, расширенные
|
||
возможности пока отсутствуют, а в будущих версиях вероятны "ломающие" изменения.
|
||
|
||
Однако следующее уже реализовано:
|
||
|
||
- Базовая часть - надёжное кластерное блочное хранилище без единой точки отказа
|
||
- Производительность ;-D
|
||
- Несколько схем отказоустойчивости: репликация, XOR n+1 (1 диск чётности), коды коррекции ошибок
|
||
Рида-Соломона на основе библиотеки jerasure с любым числом дисков данных и чётности в группе
|
||
- Конфигурация через простые человекочитаемые JSON-структуры в etcd
|
||
- Автоматическое распределение данных по OSD, с поддержкой:
|
||
- Математической оптимизации для лучшей равномерности распределения и минимизации перемещений данных
|
||
- Нескольких пулов с разными схемами избыточности
|
||
- Дерева распределения, выбора OSD по тегам / классам устройств (только SSD, только HDD) и по поддереву
|
||
- Настраиваемых доменов отказа (диск/сервер/стойка и т.п.)
|
||
- Восстановление деградированных блоков
|
||
- Ребаланс, то есть перемещение данных между OSD (дисками)
|
||
- Поддержка "ленивого" fsync (fsync не на каждую операцию)
|
||
- Сбор статистики ввода/вывода в etcd
|
||
- Клиентская библиотека режима пользователя для ввода/вывода
|
||
- Драйвер диска для QEMU (собирается вне дерева исходников QEMU)
|
||
- Драйвер диска для утилиты тестирования производительности fio (также собирается вне дерева исходников fio)
|
||
- NBD-прокси для монтирования образов ядром ("блочное устройство в режиме пользователя")
|
||
- Утилита для удаления образов/инодов (vitastor-cli rm-data)
|
||
- Пакеты для Debian и CentOS
|
||
- Статистика операций ввода/вывода и занятого места в разрезе инодов
|
||
- Именование инодов через хранение их метаданных в etcd
|
||
- Снапшоты и copy-on-write клоны
|
||
- Сглаживание производительности случайной записи в SSD+HDD конфигурациях
|
||
- Поддержка RDMA/RoCEv2 через libibverbs
|
||
- CSI-плагин для Kubernetes
|
||
- Базовая поддержка OpenStack: драйвер Cinder, патчи для Nova и libvirt
|
||
- Слияние снапшотов (vitastor-cli {snap-rm,flatten,merge})
|
||
- Консольный интерфейс для управления образами (vitastor-cli {ls,create,modify})
|
||
|
||
## Планы развития
|
||
|
||
- Поддержка удаления снапшотов (слияния слоёв)
|
||
- Более корректные скрипты разметки дисков и автоматического запуска OSD
|
||
- Другие инструменты администрирования
|
||
- Плагины для OpenNebula, Proxmox и других облачных систем
|
||
- iSCSI-прокси
|
||
- Более быстрое переключение при отказах
|
||
- Фоновая проверка целостности без контрольных сумм (сверка реплик)
|
||
- Контрольные суммы
|
||
- Поддержка SSD-кэширования (tiered storage)
|
||
- Поддержка NVDIMM
|
||
- Web-интерфейс
|
||
- Возможно, сжатие
|
||
- Возможно, поддержка кэширования данных через системный page cache
|
||
|
||
## Архитектура
|
||
|
||
Так же, как и в Ceph, в Vitastor:
|
||
|
||
- Есть пулы (pools), PG, OSD, мониторы, домены отказа, дерево распределения (аналог crush-дерева).
|
||
- Образы делятся на блоки фиксированного размера (объекты), и эти объекты распределяются по OSD.
|
||
- У OSD есть журнал и метаданные и они тоже могут размещаться на отдельных быстрых дисках.
|
||
- Все операции записи тоже транзакционны. В Vitastor, правда, есть режим отложенного/ленивого fsync
|
||
(коммита), в котором fsync не вызывается на каждую операцию записи, что делает его более
|
||
пригодным для использования на "плохих" (десктопных) SSD. Однако все операции записи
|
||
в любом случае атомарны.
|
||
- Клиентская библиотека тоже старается ждать восстановления после любого отказа кластера, то есть,
|
||
вы тоже можете перезагрузить хоть весь кластер разом, и клиенты только на время зависнут,
|
||
но не отключатся.
|
||
|
||
Некоторые базовые термины для тех, кто не знаком с Ceph:
|
||
|
||
- OSD (Object Storage Daemon) - процесс, который хранит данные на одном диске и обрабатывает
|
||
запросы чтения/записи от клиентов.
|
||
- Пул (Pool) - контейнер для данных, имеющих одну и ту же схему избыточности и правила распределения по OSD.
|
||
- PG (Placement Group) - группа объектов, хранимых на одном и том же наборе реплик (OSD).
|
||
Несколько PG могут храниться на одном и том же наборе реплик, но объекты одной PG
|
||
в норме не хранятся на разных наборах OSD.
|
||
- Монитор - демон, хранящий состояние кластера.
|
||
- Домен отказа (Failure Domain) - группа OSD, которым вы разрешаете "упасть" всем вместе.
|
||
Иными словами, это группа OSD, в которые СХД не помещает разные копии одного и того же
|
||
блока данных. Например, если домен отказа - сервер, то на двух дисках одного сервера
|
||
никогда не окажется 2 и более копий одного и того же блока данных, а значит, даже
|
||
если в этом сервере откажут все диски, это будет равносильно потере только 1 копии
|
||
любого блока данных.
|
||
- Дерево распределения (Placement Tree / CRUSH Tree) - иерархическая группировка OSD
|
||
в узлы, которые далее можно использовать как домены отказа. То есть, диск (OSD) входит в
|
||
сервер, сервер входит в стойку, стойка входит в ряд, ряд в датацентр и т.п.
|
||
|
||
Чем Vitastor отличается от Ceph:
|
||
|
||
- Vitastor в первую очередь сфокусирован на SSD. Также Vitastor, вероятно, должен неплохо работать
|
||
с комбинацией SSD и HDD через bcache, а в будущем, возможно, будут добавлены и нативные способы
|
||
оптимизации под SSD+HDD. Однако хранилище на основе одних лишь жёстких дисков, вообще без SSD,
|
||
не в приоритете, поэтому оптимизации под этот кейс могут вообще не состояться.
|
||
- OSD Vitastor однопоточный и всегда таким останется, так как это самый оптимальный способ работы.
|
||
Если вам не хватает 1 ядра на 1 диск, просто делите диск на разделы и запускайте на нём несколько OSD.
|
||
Но, скорее всего, вам хватит и 1 ядра - Vitastor не так прожорлив к ресурсам CPU, как Ceph.
|
||
- Журнал и метаданные всегда размещаются в памяти, благодаря чему никогда не тратится лишнее время
|
||
на чтение метаданных с диска. Размер метаданных линейно зависит от размера диска и блока данных,
|
||
который задаётся в конфигурации кластера и по умолчанию составляет 128 КБ. С блоком 128 КБ метаданные
|
||
занимают примерно 512 МБ памяти на 1 ТБ дискового пространства (и это всё равно меньше, чем нужно Ceph-у).
|
||
Журнал вообще не должен быть большим, например, тесты производительности в данном документе проводились
|
||
с журналом размером всего 16 МБ. Большой журнал, вероятно, даже вреден, т.к. "грязные" записи (записи,
|
||
не сброшенные из журнала) тоже занимают память и могут немного замедлять работу.
|
||
- В Vitastor нет внутреннего copy-on-write. Я считаю, что реализация CoW-хранилища гораздо сложнее,
|
||
поэтому сложнее добиться устойчиво хороших результатов. Возможно, в один прекрасный день
|
||
я придумаю красивый алгоритм для CoW-хранилища, но пока нет - внутреннего CoW в Vitastor не будет.
|
||
Всё это не относится к "внешнему" CoW (снапшотам и клонам).
|
||
- Базовый слой Vitastor - простое блочное хранилище с блоками фиксированного размера, а не сложное
|
||
объектное хранилище с расширенными возможностями, как в Ceph (RADOS).
|
||
- В Vitastor есть режим "ленивых fsync", в котором OSD группирует запросы записи перед сбросом их
|
||
на диск, что позволяет получить лучшую производительность с дешёвыми настольными SSD без конденсаторов
|
||
("Advanced Power Loss Protection" / "Capacitor-Based Power Loss Protection").
|
||
Тем не менее, такой режим всё равно медленнее использования нормальных серверных SSD и мгновенного
|
||
fsync, так как приводит к дополнительным операциям передачи данных по сети, поэтому рекомендуется
|
||
всё-таки использовать хорошие серверные диски, тем более, стоят они почти так же, как десктопные.
|
||
- PG эфемерны. Это означает, что они не хранятся на дисках и существуют только в памяти работающих OSD.
|
||
- Процессы восстановления оперируют отдельными объектами, а не целыми PG.
|
||
- PGLOG-ов нет.
|
||
- "Мониторы" не хранят данные. Конфигурация и состояние кластера хранятся в etcd в простых человекочитаемых
|
||
JSON-структурах. Мониторы Vitastor только следят за состоянием кластера и управляют перемещением данных.
|
||
В этом смысле монитор Vitastor не является критичным компонентом системы и больше похож на Ceph-овский
|
||
менеджер (MGR). Монитор Vitastor написан на node.js.
|
||
- Распределение PG не основано на консистентных хешах. Вместо этого все маппинги PG хранятся прямо в etcd
|
||
(ибо нет никакой проблемы сохранить несколько сотен-тысяч записей в памяти, а не считать каждый раз хеши).
|
||
Перераспределение PG по OSD выполняется через математическую оптимизацию,
|
||
а конкретно, сведение задачи к ЛП (задаче линейного программирования) и решение оной с помощью утилиты
|
||
lp_solve. Такой подход позволяет обычно выравнивать распределение места почти идеально - равномерность
|
||
обычно составляет 96-99%, в отличие от Ceph, где на голом CRUSH-е без балансировщика обычно выходит 80-90%.
|
||
Также это позволяет минимизировать объём перемещения данных и случайность связей между OSD, а также менять
|
||
распределение вручную, не боясь сломать логику перебалансировки. В таком подходе есть и потенциальный
|
||
недостаток - есть предположение, что в очень большом кластере он может сломаться - однако вплоть до
|
||
нескольких сотен OSD подход точно работает нормально. Ну и, собственно, при необходимости легко
|
||
реализовать и консистентные хеши.
|
||
- Отдельный слой, подобный слою "CRUSH-правил", отсутствует. Вы настраиваете схемы отказоустойчивости,
|
||
домены отказа и правила выбора OSD напрямую в конфигурации пулов.
|
||
|
||
## Понимание сути производительности систем хранения
|
||
|
||
Вкратце: для быстрой хранилки задержки важнее, чем пиковые iops-ы.
|
||
|
||
Лучшая возможная задержка достигается при тестировании в 1 поток с глубиной очереди 1,
|
||
что приблизительно означает минимально нагруженное состояние кластера. В данном случае
|
||
IOPS = 1/задержка. Ни числом серверов, ни дисков, ни серверных процессов/потоков
|
||
задержка не масштабируется... Она зависит только от того, насколько быстро один
|
||
серверный процесс (и клиент) обрабатывают одну операцию.
|
||
|
||
Почему задержки важны? Потому, что некоторые приложения *не могут* использовать глубину
|
||
очереди больше 1, ибо их задача не параллелизуется. Важный пример - это все СУБД
|
||
с поддержкой консистентности (ACID), потому что все они обеспечивают её через
|
||
журналирование, а журналы пишутся последовательно и с fsync() после каждой операции.
|
||
|
||
fsync, кстати - это ещё одна очень важная вещь, про которую почти всегда забывают в тестах.
|
||
Смысл в том, что все современные диски имеют кэши/буферы записи и не гарантируют, что
|
||
данные реально физически записываются на носитель до того, как вы делаете fsync(),
|
||
который транслируется в команду сброса кэша операционной системой.
|
||
|
||
Дешёвые SSD для настольных ПК и ноутбуков очень быстрые без fsync - NVMe диски, например,
|
||
могут обработать порядка 80000 операций записи в секунду с глубиной очереди 1 без fsync.
|
||
Однако с fsync, когда они реально вынуждены писать каждый блок данных во флеш-память,
|
||
они выжимают лишь 1000-2000 операций записи в секунду (число практически постоянное
|
||
для всех моделей SSD).
|
||
|
||
Серверные SSD часто имеют суперконденсаторы, работающие как встроенный источник
|
||
бесперебойного питания и дающие дискам успеть сбросить их DRAM-кэш в постоянную
|
||
флеш-память при отключении питания. Благодаря этому диски с чистой совестью
|
||
*игнорируют fsync*, так как точно знают, что данные из кэша доедут до постоянной
|
||
памяти.
|
||
|
||
Все наиболее известные программные СХД, например, Ceph и внутренние СХД, используемые
|
||
такими облачными провайдерами, как Amazon, Google, Яндекс, медленные в смысле задержки.
|
||
В лучшем случае они дают задержки от 0.3мс на чтение и 0.6мс на запись 4 КБ блоками
|
||
даже при условии использования наилучшего возможного железа.
|
||
|
||
И это в эпоху SSD, когда вы можете пойти на рынок и купить там SSD, задержка которого
|
||
на чтение будет 0.1мс, а на запись - 0.04мс, за 100$ или даже дешевле.
|
||
|
||
Когда мне нужно быстро протестировать производительность дисковой подсистемы, я
|
||
использую следующие 6 команд, с небольшими вариациями:
|
||
|
||
- Линейная запись:
|
||
`fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4M -iodepth=32 -rw=write -runtime=60 -filename=/dev/sdX`
|
||
- Линейное чтение:
|
||
`fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4M -iodepth=32 -rw=read -runtime=60 -filename=/dev/sdX`
|
||
- Запись в 1 поток (T1Q1):
|
||
`fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=1 -fsync=1 -rw=randwrite -runtime=60 -filename=/dev/sdX`
|
||
- Чтение в 1 поток (T1Q1):
|
||
`fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=1 -rw=randread -runtime=60 -filename=/dev/sdX`
|
||
- Параллельная запись (numjobs используется, когда 1 ядро CPU не может насытить диск):
|
||
`fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=128 [-numjobs=4 -group_reporting] -rw=randwrite -runtime=60 -filename=/dev/sdX`
|
||
- Параллельное чтение (numjobs - аналогично):
|
||
`fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=128 [-numjobs=4 -group_reporting] -rw=randread -runtime=60 -filename=/dev/sdX`
|
||
|
||
## Теоретическая максимальная производительность Vitastor
|
||
|
||
При использовании репликации:
|
||
- Задержка чтения в 1 поток (T1Q1): 1 сетевой RTT + 1 чтение с диска.
|
||
- Запись+fsync в 1 поток:
|
||
- С мгновенным сбросом: 2 RTT + 1 запись.
|
||
- С отложенным ("ленивым") сбросом: 4 RTT + 1 запись + 1 fsync.
|
||
- Параллельное чтение: сумма IOPS всех дисков либо производительность сети, если в сеть упрётся раньше.
|
||
- Параллельная запись: сумма IOPS всех дисков / число реплик / WA либо производительность сети, если в сеть упрётся раньше.
|
||
|
||
При использовании кодов коррекции ошибок (EC):
|
||
- Задержка чтения в 1 поток (T1Q1): 1.5 RTT + 1 чтение.
|
||
- Запись+fsync в 1 поток:
|
||
- С мгновенным сбросом: 3.5 RTT + 1 чтение + 2 записи.
|
||
- С отложенным ("ленивым") сбросом: 5.5 RTT + 1 чтение + 2 записи + 2 fsync.
|
||
- Под 0.5 на самом деле подразумевается (k-1)/k, где k - число дисков данных,
|
||
что означает, что дополнительное обращение по сети не нужно, когда операция
|
||
чтения обслуживается локально.
|
||
- Параллельное чтение: сумма IOPS всех дисков либо производительность сети, если в сеть упрётся раньше.
|
||
- Параллельная запись: сумма IOPS всех дисков / общее число дисков данных и чётности / WA либо производительность сети, если в сеть упрётся раньше.
|
||
Примечание: IOPS дисков в данном случае надо брать в смешанном режиме чтения/записи в пропорции, аналогичной формулам выше.
|
||
|
||
WA (мультипликатор записи) для 4 КБ блоков в Vitastor обычно составляет 3-5:
|
||
1. Запись метаданных в журнал
|
||
2. Запись блока данных в журнал
|
||
3. Запись метаданных в БД
|
||
4. Ещё одна запись метаданных в журнал при использовании EC
|
||
5. Запись блока данных на диск данных
|
||
|
||
Если вы найдёте SSD, хорошо работающий с 512-байтными блоками данных (Optane?),
|
||
то 1, 3 и 4 можно снизить до 512 байт (1/8 от размера данных) и получить WA всего 2.375.
|
||
|
||
Кроме того, WA снижается при использовании отложенного/ленивого сброса при параллельной
|
||
нагрузке, т.к. блоки журнала записываются на диск только когда они заполняются или явным
|
||
образом запрашивается fsync.
|
||
|
||
## Пример сравнения с Ceph
|
||
|
||
Железо - 4 сервера, в каждом:
|
||
- 6x SATA SSD Intel D3-4510 3.84 TB
|
||
- 2x Xeon Gold 6242 (16 cores @ 2.8 GHz)
|
||
- 384 GB RAM
|
||
- 1x 25 GbE сетевая карта (Mellanox ConnectX-4 LX), подключённая к свитчу Juniper QFX5200
|
||
|
||
Экономия энергии CPU отключена. В тестах и Vitastor, и Ceph развёрнуто по 2 OSD на 1 SSD.
|
||
|
||
Все результаты ниже относятся к случайной нагрузке 4 КБ блоками (если явно не указано обратное).
|
||
|
||
Производительность голых дисков:
|
||
- T1Q1 запись ~27000 iops (задержка ~0.037ms)
|
||
- T1Q1 чтение ~9800 iops (задержка ~0.101ms)
|
||
- T1Q32 запись ~60000 iops
|
||
- T1Q32 чтение ~81700 iops
|
||
|
||
Ceph 15.2.4 (Bluestore):
|
||
- T1Q1 запись ~1000 iops (задержка ~1ms)
|
||
- T1Q1 чтение ~1750 iops (задержка ~0.57ms)
|
||
- T8Q64 запись ~100000 iops, потребление CPU процессами OSD около 40 ядер на каждом сервере
|
||
- T8Q64 чтение ~480000 iops, потребление CPU процессами OSD около 40 ядер на каждом сервере
|
||
|
||
Тесты в 8 потоков проводились на 8 400GB RBD образах со всех хостов (с каждого хоста запускалось 2 процесса fio).
|
||
Это нужно потому, что в Ceph несколько RBD-клиентов, пишущих в 1 образ, очень сильно замедляются.
|
||
|
||
Настройки RocksDB и Bluestore в Ceph не менялись, единственным изменением было отключение cephx_sign_messages.
|
||
|
||
На самом деле, результаты теста не такие уж и плохие для Ceph (могло быть хуже).
|
||
Собственно говоря, эти серверы как раз хорошо сбалансированы для Ceph - 6 SATA SSD как раз
|
||
утилизируют 25-гигабитную сеть, а без 2 мощных процессоров Ceph-у бы не хватило ядер,
|
||
чтобы выдать пристойный результат. Собственно, что и показывает жор 40 ядер в процессе
|
||
параллельного теста.
|
||
|
||
Vitastor:
|
||
- T1Q1 запись: 7087 iops (задержка 0.14ms)
|
||
- T1Q1 чтение: 6838 iops (задержка 0.145ms)
|
||
- T2Q64 запись: 162000 iops, потребление CPU - 3 ядра на каждом сервере
|
||
- T8Q64 чтение: 895000 iops, потребление CPU - 4 ядра на каждом сервере
|
||
- Линейная запись (4M T1Q32): 2800 МБ/с
|
||
- Линейное чтение (4M T1Q32): 1500 МБ/с
|
||
|
||
Тест на чтение в 8 потоков проводился на 1 большом образе (3.2 ТБ) со всех хостов (опять же, по 2 fio с каждого).
|
||
В Vitastor никакой разницы между 1 образом и 8-ю нет. Естественно, примерно 1/4 запросов чтения
|
||
в такой конфигурации, как и в тестах Ceph выше, обслуживалась с локальной машины. Если проводить
|
||
тест так, чтобы все операции всегда обращались к первичным OSD по сети - тест сильнее упирался
|
||
в сеть и результат составлял примерно 689000 iops.
|
||
|
||
Настройки Vitastor: `--disable_data_fsync true --immediate_commit all --flusher_count 8
|
||
--disk_alignment 4096 --journal_block_size 4096 --meta_block_size 4096
|
||
--journal_no_same_sector_overwrites true --journal_sector_buffer_count 1024
|
||
--journal_size 16777216`.
|
||
|
||
### EC/XOR 2+1
|
||
|
||
Vitastor:
|
||
- T1Q1 запись: 2808 iops (задержка ~0.355ms)
|
||
- T1Q1 чтение: 6190 iops (задержка ~0.16ms)
|
||
- T2Q64 запись: 85500 iops, потребление CPU - 3.4 ядра на каждом сервере
|
||
- T8Q64 чтение: 812000 iops, потребление CPU - 4.7 ядра на каждом сервере
|
||
- Линейная запись (4M T1Q32): 3200 МБ/с
|
||
- Линейное чтение (4M T1Q32): 1800 МБ/с
|
||
|
||
Ceph:
|
||
- T1Q1 запись: 730 iops (задержка ~1.37ms latency)
|
||
- T1Q1 чтение: 1500 iops с холодным кэшем метаданных (задержка ~0.66ms), 2300 iops через 2 минуты прогрева (задержка ~0.435ms)
|
||
- T4Q128 запись (4 RBD images): 45300 iops, потребление CPU - 30 ядер на каждом сервере
|
||
- T8Q64 чтение (4 RBD images): 278600 iops, потребление CPU - 40 ядер на каждом сервере
|
||
- Линейная запись (4M T1Q32): 1950 МБ/с в пустой образ, 2500 МБ/с в заполненный образ
|
||
- Линейное чтение (4M T1Q32): 2400 МБ/с
|
||
|
||
### NBD
|
||
|
||
NBD расшифровывается как "сетевое блочное устройство", но на самом деле оно также
|
||
работает просто как аналог FUSE для блочных устройств, то есть, представляет собой
|
||
"блочное устройство в пространстве пользователя".
|
||
|
||
NBD - на данный момент единственный способ монтировать Vitastor ядром Linux.
|
||
NBD немного снижает производительность, так как приводит к дополнительным копированиям
|
||
данных между ядром и пространством пользователя. Тем не менее, способ достаточно оптимален,
|
||
а производительность случайного доступа вообще затрагивается слабо.
|
||
|
||
Vitastor с однопоточной NBD прокси на том же стенде:
|
||
- T1Q1 запись: 6000 iops (задержка 0.166ms)
|
||
- T1Q1 чтение: 5518 iops (задержка 0.18ms)
|
||
- T1Q128 запись: 94400 iops
|
||
- T1Q128 чтение: 103000 iops
|
||
- Линейная запись (4M T1Q128): 1266 МБ/с (в сравнении с 2800 МБ/с через fio)
|
||
- Линейное чтение (4M T1Q128): 975 МБ/с (в сравнении с 1500 МБ/с через fio)
|
||
|
||
## Установка
|
||
|
||
### Debian
|
||
|
||
- Добавьте ключ репозитория Vitastor:
|
||
`wget -q -O - https://vitastor.io/debian/pubkey | sudo apt-key add -`
|
||
- Добавьте репозиторий Vitastor в /etc/apt/sources.list:
|
||
- Debian 11 (Bullseye/Sid): `deb https://vitastor.io/debian bullseye main`
|
||
- Debian 10 (Buster): `deb https://vitastor.io/debian buster main`
|
||
- Для Debian 10 (Buster) также включите репозиторий backports:
|
||
`deb http://deb.debian.org/debian buster-backports main`
|
||
- Установите пакеты: `apt update; apt install vitastor lp-solve etcd linux-image-amd64 qemu`
|
||
|
||
### CentOS
|
||
|
||
- Добавьте в систему репозиторий Vitastor:
|
||
- CentOS 7: `yum install https://vitastor.io/rpms/centos/7/vitastor-release-1.0-1.el7.noarch.rpm`
|
||
- CentOS 8: `dnf install https://vitastor.io/rpms/centos/8/vitastor-release-1.0-1.el8.noarch.rpm`
|
||
- Включите EPEL: `yum/dnf install epel-release`
|
||
- Включите дополнительные репозитории CentOS:
|
||
- CentOS 7: `yum install centos-release-scl`
|
||
- CentOS 8: `dnf install centos-release-advanced-virtualization`
|
||
- Включите elrepo-kernel:
|
||
- CentOS 7: `yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm`
|
||
- CentOS 8: `dnf install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm`
|
||
- Установите пакеты: `yum/dnf install vitastor lpsolve etcd kernel-ml qemu-kvm`
|
||
|
||
### Установка из исходников
|
||
|
||
- Установите ядро 5.4 или более новое, для поддержки io_uring. Желательно 5.8 или даже новее,
|
||
так как в 5.4 есть как минимум 1 известный баг, ведущий к зависанию с io_uring и контроллером HP SmartArray.
|
||
- Установите liburing 0.4 или более новый и его заголовки.
|
||
- Установите lp_solve.
|
||
- Установите etcd, версии не ниже 3.4.15. Более ранние версии работать не будут из-за различных багов,
|
||
например [#12402](https://github.com/etcd-io/etcd/pull/12402). Также вы можете взять версию 3.4.13 с
|
||
этим конкретным исправлением из ветки release-3.4 репозитория https://github.com/vitalif/etcd/.
|
||
- Установите node.js 10 или новее.
|
||
- Установите gcc и g++ 8.x или новее.
|
||
- Склонируйте данный репозиторий с подмодулями: `git clone https://yourcmc.ru/git/vitalif/vitastor/`.
|
||
- Желательно пересобрать QEMU с патчем, который делает необязательным запуск через LD_PRELOAD.
|
||
См `patches/qemu-*.*-vitastor.patch` - выберите версию, наиболее близкую вашей версии QEMU.
|
||
- Установите QEMU 3.0 или новее, возьмите исходные коды установленного пакета, начните его пересборку,
|
||
через некоторое время остановите её и скопируйте следующие заголовки:
|
||
- `<qemu>/include` → `<vitastor>/qemu/include`
|
||
- Debian:
|
||
* Берите qemu из основного репозитория
|
||
* `<qemu>/b/qemu/config-host.h` → `<vitastor>/qemu/b/qemu/config-host.h`
|
||
* `<qemu>/b/qemu/qapi` → `<vitastor>/qemu/b/qemu/qapi`
|
||
- CentOS 8:
|
||
* Берите qemu из репозитория Advanced-Virtualization. Чтобы включить его, запустите
|
||
`yum install centos-release-advanced-virtualization.noarch` и далее `yum install qemu`
|
||
* `<qemu>/config-host.h` → `<vitastor>/qemu/b/qemu/config-host.h`
|
||
* Для QEMU 3.0+: `<qemu>/qapi` → `<vitastor>/qemu/b/qemu/qapi`
|
||
* Для QEMU 2.0+: `<qemu>/qapi-types.h` → `<vitastor>/qemu/b/qemu/qapi-types.h`
|
||
- `config-host.h` и `qapi` нужны, т.к. в них содержатся автогенерируемые заголовки
|
||
- Установите fio 3.7 или новее, возьмите исходники пакета и сделайте на них симлинк с `<vitastor>/fio`.
|
||
- Соберите и установите Vitastor командой `mkdir build && cd build && cmake .. && make -j8 && make install`.
|
||
Обратите внимание на переменную cmake `QEMU_PLUGINDIR` - под RHEL её нужно установить равной `qemu-kvm`.
|
||
|
||
## Запуск
|
||
|
||
Внимание: процедура пока что достаточно нетривиальная, задавать конфигурацию и смещения
|
||
на диске нужно почти вручную. Это будет исправлено в ближайшем будущем.
|
||
|
||
- Желательны SATA SSD или NVMe диски с конденсаторами (серверные SSD). Можно использовать и
|
||
десктопные SSD, включив режим отложенного fsync, но производительность однопоточной записи
|
||
в этом случае пострадает.
|
||
- Быстрая сеть, минимум 10 гбит/с
|
||
- Для наилучшей производительности нужно отключить энергосбережение CPU: `cpupower idle-set -D 0 && cpupower frequency-set -g performance`.
|
||
- Пропишите нужные вам значения вверху файлов `/usr/lib/vitastor/mon/make-units.sh` и `/usr/lib/vitastor/mon/make-osd.sh`.
|
||
- Создайте юниты systemd для etcd и мониторов: `/usr/lib/vitastor/mon/make-units.sh`
|
||
- Создайте юниты для OSD: `/usr/lib/vitastor/mon/make-osd.sh /dev/disk/by-partuuid/XXX [/dev/disk/by-partuuid/YYY ...]`
|
||
- Вы можете поменять параметры OSD в юнитах systemd. Смысл некоторых параметров:
|
||
- `disable_data_fsync 1` - отключает fsync, используется с SSD с конденсаторами.
|
||
- `immediate_commit all` - используется с SSD с конденсаторами.
|
||
- `disable_device_lock 1` - отключает блокировку файла устройства, нужно, только если вы запускаете
|
||
несколько OSD на одном блочном устройстве.
|
||
- `flusher_count 256` - "flusher" - микропоток, удаляющий старые данные из журнала.
|
||
Не волнуйтесь об этой настройке, 256 теперь достаточно практически всегда.
|
||
- `disk_alignment`, `journal_block_size`, `meta_block_size` следует установить равными размеру
|
||
внутреннего блока SSD. Это почти всегда 4096.
|
||
- `journal_no_same_sector_overwrites true` запрещает перезапись одного и того же сектора журнала подряд
|
||
много раз в процессе записи. Большинство (99%) SSD не нуждаются в данной опции. Однако выяснилось, что
|
||
диски, используемые на одном из тестовых стендов - Intel D3-S4510 - очень сильно не любят такую
|
||
перезапись, и для них была добавлена эта опция. Когда данный режим включён, также нужно поднимать
|
||
значение `journal_sector_buffer_count`, так как иначе Vitastor не хватит буферов для записи в журнал.
|
||
- Запустите все etcd: `systemctl start etcd`
|
||
- Создайте глобальную конфигурацию в etcd: `etcdctl --endpoints=... put /vitastor/config/global '{"immediate_commit":"all"}'`
|
||
(если все ваши диски - серверные с конденсаторами).
|
||
- Создайте пулы: `etcdctl --endpoints=... put /vitastor/config/pools '{"1":{"name":"testpool","scheme":"replicated","pg_size":2,"pg_minsize":1,"pg_count":256,"failure_domain":"host"}}'`.
|
||
Для jerasure EC-пулов конфигурация должна выглядеть так: `2:{"name":"ecpool","scheme":"jerasure","pg_size":4,"parity_chunks":2,"pg_minsize":2,"pg_count":256,"failure_domain":"host"}`.
|
||
- Запустите все OSD: `systemctl start vitastor.target`
|
||
- Ваш кластер должен быть готов - один из мониторов должен уже сконфигурировать PG, а OSD должны запустить их.
|
||
- Вы можете проверить состояние PG прямо в etcd: `etcdctl --endpoints=... get --prefix /vitastor/pg/state`. Все PG должны быть 'active'.
|
||
|
||
### Задать имя образу
|
||
|
||
```
|
||
etcdctl --endpoints=<etcd> put /vitastor/config/inode/<pool>/<inode> '{"name":"<name>","size":<size>[,"parent_id":<parent_inode_number>][,"readonly":true]}'
|
||
```
|
||
|
||
Например:
|
||
|
||
```
|
||
etcdctl --endpoints=http://10.115.0.10:2379/v3 put /vitastor/config/inode/1/1 '{"name":"testimg","size":2147483648}'
|
||
```
|
||
|
||
Если вы зададите parent_id, то образ станет CoW-клоном, т.е. все новые запросы записи пойдут в новый инод, а запросы
|
||
чтения будут проверять сначала его, а потом родительские слои по цепочке вверх. Чтобы случайно не перезаписать данные
|
||
в родительском слое, вы можете переключить его в режим "только чтение", добавив флаг `"readonly":true` в его запись
|
||
метаданных. В таком случае родительский образ становится просто снапшотом.
|
||
|
||
Таким образом, для создания снапшота вам нужно просто переименовать предыдущий inode (например, из testimg в testimg@0),
|
||
сделать его readonly и создать новый слой с исходным именем образа (testimg), ссылающийся на только что переименованный
|
||
в качестве родительского.
|
||
|
||
### Запуск тестов с fio
|
||
|
||
Пример команды для запуска тестов:
|
||
|
||
```
|
||
fio -thread -ioengine=libfio_vitastor.so -name=test -bs=4M -direct=1 -iodepth=16 -rw=write -etcd=10.115.0.10:2379/v3 -image=testimg
|
||
```
|
||
|
||
Если вы не хотите обращаться к образу по имени, вместо `-image=testimg` можно указать номер пула, номер инода и размер:
|
||
`-pool=1 -inode=1 -size=400G`.
|
||
|
||
### Загрузить образ диска ВМ в/из Vitastor
|
||
|
||
Используйте qemu-img и строку `vitastor:etcd_host=<HOST>:image=<IMAGE>` в качестве имени файла диска. Например:
|
||
|
||
```
|
||
qemu-img convert -f qcow2 debian10.qcow2 -p -O raw 'vitastor:etcd_host=10.115.0.10\:2379/v3:image=testimg'
|
||
```
|
||
|
||
Обратите внимание, что если вы используете немодифицированный QEMU, потребуется установить переменную окружения
|
||
`LD_PRELOAD=/usr/lib/x86_64-linux-gnu/qemu/block-vitastor.so`.
|
||
|
||
Если вы не хотите обращаться к образу по имени, вместо `:image=<IMAGE>` можно указать номер пула, номер инода и размер:
|
||
`:pool=<POOL>:inode=<INODE>:size=<SIZE>`.
|
||
|
||
### Запустить ВМ
|
||
|
||
Для запуска QEMU используйте опцию `-drive file=vitastor:etcd_host=<HOST>:image=<IMAGE>` (аналогично qemu-img)
|
||
и физический размер блока 4 KB.
|
||
|
||
Например:
|
||
|
||
```
|
||
qemu-system-x86_64 -enable-kvm -m 1024
|
||
-drive 'file=vitastor:etcd_host=10.115.0.10\:2379/v3:image=testimg',format=raw,if=none,id=drive-virtio-disk0,cache=none
|
||
-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1,write-cache=off,physical_block_size=4096,logical_block_size=512
|
||
-vnc 0.0.0.0:0
|
||
```
|
||
|
||
Обращение по номерам (`:pool=<POOL>:inode=<INODE>:size=<SIZE>` вместо `:image=<IMAGE>`) работает аналогично qemu-img.
|
||
|
||
### Удалить образ
|
||
|
||
Используйте утилиту vitastor-cli rm-data. Например:
|
||
|
||
```
|
||
vitastor-cli rm-data --etcd_address 10.115.0.10:2379/v3 --pool 1 --inode 1 --parallel_osds 16 --iodepth 32
|
||
```
|
||
|
||
### NBD
|
||
|
||
Чтобы создать локальное блочное устройство, используйте NBD. Например:
|
||
|
||
```
|
||
vitastor-nbd map --etcd_address 10.115.0.10:2379/v3 --image testimg
|
||
```
|
||
|
||
Команда напечатает название устройства вида /dev/nbd0, которое потом можно будет форматировать
|
||
и использовать как обычное блочное устройство.
|
||
|
||
Для обращения по номеру инода, аналогично другим командам, можно использовать опции
|
||
`--pool <POOL> --inode <INODE> --size <SIZE>` вместо `--image testimg`.
|
||
|
||
### Kubernetes
|
||
|
||
У Vitastor есть CSI-плагин для Kubernetes, поддерживающий RWO-тома.
|
||
|
||
Для установки возьмите манифесты из директории [csi/deploy/](csi/deploy/), поместите
|
||
вашу конфигурацию подключения к Vitastor в [csi/deploy/001-csi-config-map.yaml](001-csi-config-map.yaml),
|
||
настройте StorageClass в [csi/deploy/009-storage-class.yaml](009-storage-class.yaml)
|
||
и примените все `NNN-*.yaml` к вашей инсталляции Kubernetes.
|
||
|
||
```
|
||
for i in ./???-*.yaml; do kubectl apply -f $i; done
|
||
```
|
||
|
||
После этого вы сможете создавать PersistentVolume. Пример смотрите в файле [csi/deploy/example-pvc.yaml](csi/deploy/example-pvc.yaml).
|
||
|
||
## Известные проблемы
|
||
|
||
- Запросы удаления объектов могут в данный момент приводить к "неполным" объектам в EC-пулах,
|
||
если в процессе удаления произойдут отказы OSD или серверов, потому что правильная обработка
|
||
запросов удаления в кластере должна быть "трёхфазной", а это пока не реализовано. Если вы
|
||
столкнётесь с такой ситуацией, просто повторите запрос удаления.
|
||
|
||
## Принципы реализации
|
||
|
||
- Я люблю архитектурно простые решения. Vitastor проектируется именно так и я намерен
|
||
и далее следовать данному принципу.
|
||
- Если вы пришли сюда за идеальным кодом на C++, вы, вероятно, не по адресу. "Общепринятые"
|
||
практики написания C++ кода меня не очень волнуют, так как зачастую, опять-таки, ведут к
|
||
излишним усложнениям и код получается красивый... но медленный.
|
||
- По той же причине в коде иногда можно встретить велосипеды типа собственного упрощённого
|
||
HTTP-клиента для работы с etcd. Зато эти велосипеды маленькие и компактные и не требуют
|
||
использования десятка внешних библиотек.
|
||
- node.js для монитора - не случайный выбор. Он очень быстрый, имеет встроенную событийную
|
||
машину, приятный нейтральный C-подобный язык программирования и развитую инфраструктуру.
|
||
|
||
## Автор и лицензия
|
||
|
||
Автор: Виталий Филиппов (vitalif [at] yourcmc.ru), 2019+
|
||
|
||
Заходите в Telegram-чат Vitastor: https://t.me/vitastor
|
||
|
||
Лицензия: VNPL 1.1 на серверный код и двойная VNPL 1.1 + GPL 2.0+ на клиентский.
|
||
|
||
VNPL - "сетевой копилефт", собственная свободная копилефт-лицензия
|
||
Vitastor Network Public License 1.1, основанная на GNU GPL 3.0 с дополнительным
|
||
условием "Сетевого взаимодействия", требующим распространять все программы,
|
||
специально разработанные для использования вместе с Vitastor и взаимодействующие
|
||
с ним по сети, под лицензией VNPL или под любой другой свободной лицензией.
|
||
|
||
Идея VNPL - расширение действия копилефта не только на модули, явным образом
|
||
связываемые с кодом Vitastor, но также на модули, оформленные в виде микросервисов
|
||
и взаимодействующие с ним по сети.
|
||
|
||
Таким образом, если вы хотите построить на основе Vitastor сервис, содержаший
|
||
компоненты с закрытым кодом, взаимодействующие с Vitastor, вам нужна коммерческая
|
||
лицензия от автора 😀.
|
||
|
||
На Windows и любое другое ПО, не разработанное *специально* для использования
|
||
вместе с Vitastor, никакие ограничения не накладываются.
|
||
|
||
Клиентские библиотеки распространяются на условиях двойной лицензии VNPL 1.0
|
||
и также на условиях GNU GPL 2.0 или более поздней версии. Так сделано в целях
|
||
совместимости с таким ПО, как QEMU и fio.
|
||
|
||
Вы можете найти полный текст VNPL 1.1 в файле [VNPL-1.1.txt](VNPL-1.1.txt),
|
||
а GPL 2.0 в файле [GPL-2.0.txt](GPL-2.0.txt).
|