parent
2612d3198a
commit
e50f703e1d
@ -0,0 +1,493 @@ |
||||
## 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-rm) |
||||
- Пакеты для Debian и CentOS |
||||
- Статистика операций ввода/вывода и занятого места в разрезе инодов |
||||
- Именование инодов через хранение их метаданных в etcd |
||||
- Снапшоты и copy-on-write клоны |
||||
|
||||
## Планы разработки |
||||
|
||||
- Утилита инициализации OSD (пока что диски под OSD нужно размечать вручную) |
||||
- Другие инструменты администрирования |
||||
- Плагины для OpenStack, Kubernetes, OpenNebula, Proxmox и других облачных систем |
||||
- iSCSI-прокси |
||||
- Таймауты операций и более быстрое выявление отказов |
||||
- Фоновая проверка целостности без контрольных сумм (сверка реплик) |
||||
- Контрольные суммы |
||||
- Оптимизации для гибридных SSD+HDD хранилищ |
||||
- Поддержка RDMA и 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 - на данный момент единственный способ монтировать Vitastor ядром Linux, но он |
||||
приводит к дополнительным копированиям данных, поэтому немного ухудшает производительность, |
||||
правда, в основном - линейную, а случайная затрагивается слабо. |
||||
|
||||
NBD расшифровывается как "сетевое блочное устройство", но на самом деле оно также |
||||
работает просто как аналог FUSE для блочных устройств, то есть, представляет собой |
||||
"блочное устройство в пространстве пользователя". |
||||
|
||||
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. Внимание: вам нужна версия с исправлением отсюда: https://github.com/vitalif/etcd/, |
||||
из ветки release-3.4, так как в etcd есть баг, который [будет](https://github.com/etcd-io/etcd/pull/12402) |
||||
исправлен только в 3.4.15. Баг приводит к неспособности Vitastor запустить PG, когда их хотя бы 500 штук. |
||||
- Установите node.js 10 или новее. |
||||
- Установите gcc и g++ 8.x или новее. |
||||
- Склонируйте данный репозиторий с подмодулями: `git clone https://yourcmc.ru/git/vitalif/vitastor/`. |
||||
- Желательно пересобрать QEMU с патчем, который делает необязательным запуск через LD_PRELOAD. |
||||
См `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 через `make -j8`. |
||||
- Запустить `make install`. Обратите внимание на опции LIBDIR и QEMU_PLUGINDIR, по умолчанию они |
||||
прописаны для Debian. Если у вас RPM-дистрибутив - правильные значения, скорее всего, |
||||
`LIBDIR=/usr/lib64 QEMU_PLUGINDIR=/usr/lib64/qemu-kvm`. |
||||
|
||||
## Запуск |
||||
|
||||
Внимание: процедура пока что достаточно нетривиальная, задавать конфигурацию и смещения |
||||
на диске нужно почти вручную. Это будет исправлено в ближайшем будущем. |
||||
|
||||
- Желательны SATA SSD или NVMe диски с конденсаторами (серверные SSD). Можно использовать и |
||||
десктопные SSD, включив режим отложенного fsync, но производительность однопоточной записи |
||||
в этом случае пострадает. |
||||
- Быстрая сеть, минимум 10 гбит/с |
||||
- Для наилучшей производительности нужно отключить энергосбережение CPU: `cpupower idle-set -D 0 && cpupower frequency-set -g performance`. |
||||
- Запустите etcd с параметрами `--max-txn-ops=100000 --auto-compaction-retention=10 --auto-compaction-mode=revision`. |
||||
- Создайте глобальную конфигурацию в 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"}`. |
||||
- Рассчитайте смещения для дисков с помощью утилиты `node /usr/lib/vitastor/mon/simple-offsets.js --device /dev/sdX`. |
||||
- Создайте systemd unit-ы для сервисов OSD. Для примера рассмотрите `/usr/lib/vitastor/mon/make-units.sh`. |
||||
Смысл некоторых опций из этого файла: |
||||
- `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 не хватит буферов для записи в журнал. |
||||
- Запустите все OSD: `systemctl start vitastor.target` |
||||
- Запустите мониторы (любое количество): `node /usr/lib/vitastor/mon/mon-main.js --etcd_url 'http://10.115.0.10:2379,http://10.115.0.11:2379,http://10.115.0.12:2379,http://10.115.0.13:2379' --etcd_prefix '/vitastor' --etcd_start_timeout 5`. |
||||
- Ваш кластер должен быть готов - один из мониторов должен уже сконфигурировать PG, а OSD должны запустить их. |
||||
- Вы можете проверить состояние PG прямо в etcd: `etcdctl --endpoints=... get --prefix /vitastor/pg/state`. Все PG должны быть 'active'. |
||||
- Пример команды для запуска тестов: `fio -thread -ioengine=/usr/lib/x86_64-linux-gnu/vitastor/libfio_cluster.so -name=test -bs=4M -direct=1 -iodepth=16 -rw=write -etcd=10.115.0.10:2379/v3 -pool=1 -inode=1 -size=400G`. |
||||
- Пример команды для заливки образа ВМ в vitastor через qemu-img: |
||||
``` |
||||
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/qemu/block-vitastor.so qemu-img convert -f qcow2 debian10.qcow2 -p |
||||
-O raw 'vitastor:etcd_host=10.115.0.10\:2379/v3:pool=1:inode=1:size=2147483648' |
||||
``` |
||||
- Пример команды запуска QEMU: |
||||
``` |
||||
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/qemu/block-vitastor.so qemu-system-x86_64 -enable-kvm -m 1024 |
||||
-drive 'file=vitastor:etcd_host=10.115.0.10\:2379/v3:pool=1:inode=1:size=2147483648',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 |
||||
``` |
||||
- Пример команды удаления образа (инода) из Vitastor: |
||||
``` |
||||
vitastor-rm --etcd_address 10.115.0.10:2379/v3 --pool 1 --inode 1 --parallel_osds 16 --iodepth 32 |
||||
``` |
||||
|
||||
## Известные проблемы |
||||
|
||||
- Запросы удаления объектов могут в данный момент приводить к "неполным" объектам в EC-пулах, |
||||
если в процессе удаления произойдут отказы OSD или серверов, потому что правильная обработка |
||||
запросов удаления в кластере должна быть "трёхфазной", а это пока не реализовано. Если вы |
||||
столкнётесь с такой ситуацией, просто повторите запрос удаления. |
||||
|
||||
## Принципы реализации |
||||
|
||||
- Я люблю архитектурно простые решения. Vitastor проектируется именно так и я намерен |
||||
и далее следовать данному принципу. |
||||
- Если вы пришли сюда за идеальным кодом на C++, вы, вероятно, не по адресу. "Общепринятые" |
||||
практики написания C++ кода меня не очень волнуют, так как зачастую, опять-таки, ведут к |
||||
излишним усложнениям и код получается красивый... но медленный. |
||||
- По той же причине в коде иногда можно встретить велосипеды типа собственного упрощённого |
||||
HTTP-клиента для работы с etcd. Зато эти велосипеды маленькие и компактные и не требуют |
||||
использования десятка внешних библиотек. |
||||
- node.js для монитора - не случайный выбор. Он очень быстрый, имеет встроенную событийную |
||||
машину, приятный нейтральный C-подобный язык программирования и развитую инфраструктуру. |
||||
|
||||
## Автор и лицензия |
||||
|
||||
Автор: Виталий Филиппов (vitalif [at] yourcmc.ru), 2019+ |
||||
|
||||
Кроме почты меня легко найти в цефочате в Telegram: https://t.me/ceph_ru |
||||
|
||||
Лицензия: 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). |
Loading…
Reference in new issue