Строим NVMe-хранилища Storage Spaces

27.03.2024 | Хранилища

Storage Spaces – технология Microsoft для управления пространствами хранения данных, основа виртуализации хранилищ ее ОС. Абстрагирование охватывает три основных объекта: физические носители, пулы хранения, виртуальные диски – которые, собственно, и являются пространствами хранения (storage spaces).

Накопители собирают в пулы. Те обеспечивают агрегацию хранилищ, эластичное расширение емкости и делегированное администрирование. Из пулов создают пространства хранения. Для Windows пространство хранения выглядит как обычный диск, которому назначается размер и тип отказоустойчивости.

Создают хранилища с помощью графического интерфейса GUI или из командной строки PowerShell - что дает ощущение свободы настроек и понимание их влияния на производительность хранения данных.

 

Типы пространств хранения

Сначала формируют пул из набора физических носителей. Поддерживаются накопители и хранилища всех изветных интерфейсов: SATA, SAS, NVME, iSCSI, FC. Творческие люди могут собрать пул даже с USB-флешек или замиксовать в одном пуле диски разной производительности.

PowerShell – посмотреть доступные для создания пула диски:

Get-StoragePool -IsPrimordial $true | Get-PhysicalDisk -CanPool $Tru

PowerShell – создать пул с именем EntryPool1 из всех доступных дисков :

New-StoragePool –FriendlyName EntryPool1 –StorageSubsystemFriendlyName "Windows Storage*" –PhysicalDisks (Get-PhysicalDisk –CanPool $True)

 

Как только пул создан, вопрос «а на каком именно диске размещен мой файл?» становится неуместным – абстракция пула поглотила и размыла в себе физические носители. Доступную емкость пула делят между виртуальными дисками (пространствами хранения). Данные хранилищ хранятся в соответствии с назначенным типом защиты. Пространство хранения не является томом RAID и не размещается на отдельном диске. По носителям распределяются нарезанные по 256 мегабайт фрагменты данных, так называемые «плитки» ( slabs ).

Виртуальные диски бывают трех типов:

  • Simple . Служит повышению производительности, без защиты файлов от сбоя диска. Данные распределяются по дискам пула, скорость последовательных и случайных рабочих нагрузок растет с количеством дисков. Поскольку он не обеспечивает устойчивости к отказам носителей, его удел – обслуживать временные данные и данные, которые можно легко восстановить - например промежуточные файлы рендеринга видео или кэшей.
  • Mirror . Используется для повышения производительности и защиты файлов от сбоя диска путем сохранения нескольких копий. Данные распределяются по физическим дискам. Двойное зеркало (two-way mirror) создает две копии файлов и допускает сбой одного диска, тройное зеркало (three-way mirror) допускает потерю двух дисков. Для двойного зеркала нужно по крайней мере два диска, а для тройного – не менее пяти. Зеркальные виртуальные диски обеспечивают лучшую производительность и устойчивость для рабочих нагрузок Hyper-V.
  • Parity . Этот тип отказоустойчивости сохраняет копии данных вместе с информацией о четности. Данные и четности распределяются по физическим дискам пула. Потребуются по крайней мере три носителя, чтобы защитить данные от отказа одного диска (single parity) и семь – пережить отказ двух дисков (dual parity). Пространства с четностью подходят для последовательных рабочих нагрузок, таких как резервное копирование, архивирование, хранение потокового мультимедиа, например музыки и видео. Не следует пользоваться ими для нагрузок случайного доступа – сильно страдает производительность записи.

Пример создания виртуального диска Simple с PowerShell:

PowerShell – создать simple виртуальный диск объемом 100ГБ с именем VG1Data на пуле   test

New-VirtualDisk -StoragePoolFriendlyName test -FriendlyName VG1Data -ResiliencySettingName Simple -Size 100GB

 

Магия PowerShell

Графический интерфейс GUI позволяет собрать носители в пул и выбрать тип виртуального диска. Остальные параметры назначаются по умолчанию, в режиме «давай сделаем это по-быстрому». PowerShell дает понимание причинно-следственной связи настроек с производительностью. Как работает «параметрическое либертарианство», поясним на примере NumberOfColumns и Interleave .

NumberOfColumns это количество столбцов, физических дисков, по которым распределяется запись, равными полосами (stripes). Interleave или чередование ширина полосы записи данных, хранящихся на каждом диске. Чем больше столбцов предназначено для пространства хранения, тем выше производительность последовательной записи/воспроизведения.

Очевидно, что NumberOfColumns не может быть больше количества дисков в пуле (может быть меньше). "Автопилот" GUI сам масштабирует количество столбцов, после создания виртуального диска его изменить нельзя. Этот параметр настраивается только с помощью PowerShell.

 

Disks

Total Capacity (TB)

Columns

Throughput (MB/s)

Avg. Latency (ms)

4

1:45

2

902.45

8

4

1:45

4

1622.50

4

 

Resiliency type

Minimum number of columns

Column-to-disk correlation

Minimum number of disks

Simple (no resiliency)

1

1:1

1

Two-way mirror

1

1:2

2

Three-way mirror

1

1:3

5

Single Parity

3

1:1

3

Dual Parity

7

1:1

7

При расширении пула следует учитывать не только минимально необходимое количество дисков, но и количество столбцов. К примеру, Simple диск с четырьмя столбцами можно расширить минимум четырьмя дисками, а двойное (two-way) зеркало с четырьмя столбцами – восемью дисками (количество столбцов умножается на количество копий данных).

По умолчанию Interleave равняется 256 килобайтам. То есть в каждом столбце Storage Spaces хранит 256K данных. Если, например, у вас есть восемь дисков в пуле хранения и хотите записать 4 мегабайта данных, каждый диск получает две полосы по 256K (4M / 256K (полоса) / 8 столбцов = 2 полосы по 256K на столбец).

 

Подстройка под рабочие нагрузки

Подсистема хранения обрабатывает I/O прикладного ПО со свойственным ему размером блока данных. К примеру, Microsoft SQL Server и Microsoft Exchange используют относительно небольшие блоки (8K-32K). Последовательные рабочие нагрузки (как в медийных программах или в резервировании данных) оперируют блоками значительно больших размеров (512K-1 М). В общем, IOPs, пропускная способность и размер блока данных связаны: малый размер блока дает высокие IOPs с низкой пропускной способностью, в то время как большой размер блока приводит к высокой пропускной способности с низким IOPS.

С точки зрения производительности значение Interleave , используемое пространством хранения, должно быть по крайней мере таким же большим, как типичный I/O рабочей нагрузки. Операции, превышающие этот размер, разбиваются в несколько полос, превращая одну запись в несколько записей. Это снижает производительность.

PowerShell – создать Parity виртуальный с Interleave 128KB и NumberOfColumns 3

New-VirtualDisk -StoragePoolFriendlyName "pool" -ProvisioningType Thin -Interleave 128KB -FriendlyName "TestParity" -Size 4TB -ResiliencySettingName Parity -NumberOfColumns 3

 

Allocation Unit Size

Приведенные соображения справедливы в сферическом вакууме Storage Spaces. В реальной жизни придется работать с разделом NTFS, с его собственными представлениями о прекрасном и о том, на сколько частей и какого размера крошить данные. Ни пространство хранения, ни пул не имеют представления о «физической» природе записи данных. Об этом должен позаботиться поставщик тома, а над томом находится раздел.

Allocation Unit Size (AUS) – это минимальный размер каждой записи в разделе NTFS. AUS по умолчанию устанавливается как 4К для дисков менее 16 ТБ и 8К для дисков 16 ТБ и больше.

Форматирование дисков с размером блока 4К (а не, скажем, 512K) представляет собой компромисс между скоростью и эффективностью хранения. При AUS 512К тысяча микро-файлов размером 1К будут занимать на диске 512 мегабайт – вместо ожидаемого одного мегабайта. С другой стороны, если хранить только мультимедийные файлы, такие как фотографии и видео, размер единицы распределения NTFS повлияет гораздо меньше, чем если у вас есть множество небольших файлов.

При Interleave 256К и AUS 4K каждый запрос на запись должен выделять пространство на разделе кусками по 4K, затем это должно быть преобразовано в фрагменты размером 256K . Понятно, что следует сохранять симметрию между NumberOfColumns , Interleave и AUS . Лучше соблюдать равенство AUS = NumberOfColumns (с данными) * Interleave . Для виртуальных дисков Single Parity формула принимает вид AUS = (NumberOfColumns-1) * Interleave , поскольку в один из столбцов вычисляется и записывается контрольная сумма.

Прояснив природу настроек пространств хранения, перейдем в материалистический мир.

 

NVMe в серверах

Выбор носителей оказывает существенное влияние на производительность сервера. Самый высокий потенциал производительности - у NVMe SSD, благодаря прямому подключению к шине PCIe и центральным процессорам, без контроллеров-посредников. При меньших задержках обращения и более высокой скорости передачи данных технология NVMe еще и масштабируема. Она полагается на линии PCIe, а не интерфейс контроллера, а с каждым поколением PCIe показатели улучшаются. NVMe SSD всегда будут быстрее, чем SATA SSD, несмотря на то что оба используют память NAND для хранения данных.

Серверные платформы с поддержкой одного-двух десятков NVMe SSD становятся обыденностью. Сами накопители сравнялись по цене с SATA SSD. Для искателей производительности выбор носителей очевиден. Исследуем особенности разных типов хранилищ Storage Spaces, построенных на NVMe SSD.

 

Тестовая платформа

Основной корпоративный стандарт NVMe SSD – это U.2/U.3 (2.5” NVMe). В типичную современную платформу 1U вмещается до 12 накопителей с горячей заменой, в 2U – до 24. К каждому должны быть подведены четыре законных линии PCIe. Пространствам хранения Storage Spaces не требуются никакие контроллеры на шине, источники ограничений производительности.

Конфигурация нашего тестового стенда:

ASUS RS700-E10-RS12/2х CPU Intel Xeon Gold 6326/16 x 16ГБ DDR4-3200 RDIMM Micron/480GB M.2 NVMe SSD Micron 7450 Pro/4 x 3.2ТБ U.3 Micron 7450 Max

Использовалась FIO (версия fio-3.36-x64) – эталонная утилита измерения производительности дискового ввода-вывода, генерирующая множество вариантов профилей запросов и опций для точной настройки параметров.

Чтение/запись с произвольным доступом тестировались с размером блока 4K, последовательные – с блоком 1M. Диски NVMe могут обрабатывать большое количество операций I/O, мы запускали 32 задачи (потока) – в соответствии с числом физических ядер в тестовом сервере. Устанавливалась глубина очереди QD=64 для тестов с произвольным доступом и QD=32 для последовательных операций.

Что тестировали

Исследовалась производительность таких пространств хранения:

  • Два NVMe SSD в двойном зеркале (two-way mirror)
  • Четыре NVMe SSD в двойном зеркале (two-way mirror)
  • Четыре NVMe SSD в пространстве с четностью (parity) с настройками GUI по умолчанию - они отмечены как default parity на диаграммах ниже
  • Четыре NVMe SSD в пространстве с четностью (parity) с настройками вручную («оптимальными») – с оптимизацией взаимосвязи AUS, NumberOfColumns и Interleave, отмечены как optimal parity на диаграммах.

Измерялись IOPs и Latency со следующими настройками FIO

IOPS

  • FIO: 4k block size 100% random reads

fio --name=4krandomreads --rw=randread --direct=1 --ioengine=windowsaio --bs=4k --numjobs=32 --iodepth= 64 --size=4G --runtime=600 --group_reporting > > 4krandomreads.txt

  • FIO: 4k block size 100% random writes

fio --name=4krandomwrites --rw=randwrite --direct=1 --ioengine=windowsaio --bs=4k --numjobs=32 --iodepth= 64 --size=4G --runtime=600 --group_reporting > > 4krandomwrites.txt

  • FIO: 1M block size 100% sequential reads

fio --name=1Mseqreads --rw=read --direct=1 --ioengine=windowsaio --bs=1M --numjobs=32 --iodepth=32 --size=4G --runtime=600 --group_reporting > > 1Mseqreads.txt

  • FIO: 1M block size 100% sequential writes

fio --name=1Mseqwrites --rw=write --direct=1 --ioengine=windowsaio --bs=1M --numjobs=32 --iodepth= 32 --size=4G --runtime=600 --group_reporting > > 1Mseqwrites.txt

Latency

  • FIO: 4k block size 100% random reads

fio --name=4krandomreads --rw=randread --direct=1 --ioengine=windowsaio --bs=4k --numjobs=32 --iodepth= 1 --size=4G --runtime=600 --group_reporting > > 4kLrandomreads.txt

  • FIO: 4k block size 100% random writes

fio --name=4krandomwrites --rw=randwrite --direct=1 --ioengine=windowsaio --bs=4k --numjobs=32 --iodepth= 1 --size=4G --runtime=600 --group_reporting > > 4kLrandomwrites.txt

  • FIO: 1M block size 100% sequential reads

fio --name=1Mseqreads --rw=read --direct=1 --ioengine=windowsaio --bs=1M --numjobs=32 --iodepth=1 --size=4G --runtime=600 --group_reporting > > 1MLseqreads.txt

  • FIO: 1M block size 100% sequential writes

fio --name=1Mseqwrites --rw=write --direct=1 --ioengine=windowsaio --bs=1M --numjobs=32 --iodepth= 1 --size=4G --runtime=600 --group_reporting > > 1MLseqwrites.txt

 

Результаты

Для начала мы протестировали одиночный диск – убедиться, что показатели коррелируют с паспортными параметрами Micron 7450. Проверка корректности инструмента и параметров тестирования не помешает.

Проверили, что производительность пространства хранения Simple растет с добавлением накопителей:

Производительность в произвольном доступе коротким блоком 4К на четырех типах пространств хранения:

Производительность последовательных операций блоком 1М на тех же типах пространств хранения

Задержки обращения коротким блоком 4К:

Задержки обращения в последовательном доступе блоком 1М:

Тестирование зеркала c NumberOfColumns=2 (аналог RAID10) по сравнению с NumberOfColumns=1 (аналогом RAID1) не показало существенного прироста скорости:

Краткие выводы

  • Очевидна высокая эффективность и практическая целесообразность зеркальных логических дисков Storage Space;
  • При увеличении количества дисков в пуле растет показатель IOPS и уменьшаются задержки;
  • Логические диски Single Parity имеют катастрофически низкие показатели произвольной записи;
  • Оптимизация взаимосвязи AUS, NumberOfColumns и Interleave (optimal parity на диаграммах)  повышает производительность Single Parity по умолчанию (default parity на диаграммах) разве что в задачах линейной записи;
  • Если линейную скорость записи правильным подбором параметров можно спасти, то случайной записи ничего не поможет. Потому Single Parity от Storage Space на практике не применяется.

Жизнеспособное сочетание

NVMe-хранилища под управлением Storage Spaces в автономных Windows-серверах – доступный и действенный вариант производительного хранения данных. Знаешь природу своих данных, можешь разобраться в настройках – получишь хорошие результаты малой кровью.