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

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-серверах – доступный и действенный вариант производительного хранения данных. Знаешь природу своих данных, можешь разобраться в настройках – получишь хорошие результаты малой кровью.
