NVMe начинался как способ выжать максимум из локальных SSD по PCIe, но в реальной инфраструктуре быстро упираешься в физику серверов: диски «привязаны» к узлам, а быстрый пул хочется делить между хостами, мигрировать нагрузки без перекоммутации железа и при этом не скатываться в медленный или непредсказуемый storage-слой.
NVMe over Fabrics (NVMe-oF) решает именно эту задачу: переносит NVMe-команды через сетевой fabric, позволяя обращаться к NVMe-накопителям и подсистемам удалённо. В конце статьи — матрица выбора транспорта и чек-лист готовности, чтобы можно было принять решение без гаданий и «дотюнинга вслепую». Базовые определения и список транспортов хорошо собраны у SNIA в материале что такое NVMe-oF и в спецификации NVMe-oF 1.1a.
NVMe-oF простыми словами: что это и как работает
NVMe-oF — это расширение NVMe, которое позволяет выполнять те же операции чтения/записи и управления очередями, но не через PCIe, а поверх сети(Ethernet/InfiniBand/FC) такую выделенную сеть иногда называют фабрикой (fabric). В терминах архитектуры вы получаете тот же «блочный» интерфейс, только удалённый: на хосте появляются NVMe-контроллеры и namespace’ы, за которыми физически стоят диски/пулы на стороне таргета. Можно провести аналогию с более привычной технологией iSCSI, которая по сути делает тоже самое только для SCSI-устройств.
Ключевые сущности:
- Host (инициатор) — сервер, который потребляет блочные устройства. Здесь важны драйвер, стек NVMe-oF и политика путей (multipath/ANA).
- Target (таргет) — сторона, которая «выдаёт» блочные устройства по сети. Это может быть готовая storage-платформа, Linux-таргет или user-space таргет.
- Subsystem — логическая единица экспорта: набор контроллеров и namespace’ов, который видит хост.
- Namespace — то, что в итоге воспринимается как диск/том.
- Controller и очереди (queues) — механика параллелизма: много очередей, много команд, высокая глубина (queue depth) при корректной настройке.
Отдельная тема — discovery. Вместо того чтобы вручную держать список целей, хост обращается к discovery-контроллеру, получает записи (discovery records) и создаёт подключения к нужным подсистемам. На Linux это хорошо видно в утилите nvme-cli: смысл команды connect-all описан в соответствующей документации man-pages — она делает discovery-запросы и поднимает контроллеры по возвращённым записям.
Важно зафиксировать ожидания: NVMe-oF — не «ускоритель магии». Это удалённый доступ к NVMe со своим latency budget, зависимостью от сети, настройкой путей и эксплуатацией. Его сила — в архитектурной гибкости и близкой к NVMe модели команд/очередей, а не в гарантии «как локально».
Когда NVMe-oF действительно нужен
NVMe-oF нужен, если…
- Нужно разделить быстрый NVMe-пул между многими хостами и при этом сохранить низкую добавочную задержку относительно классических сетевых протоколов.
- Требуется высокая плотность NVMe (JBOF/JBOD-подход), но управлять этим хочется централизованно, без «дисков в каждом хосте».
- Есть требования к предсказуемости задержек и важны хвосты (p99/p99.9), а также QoS в рамках storage-fabric.
- Платформа виртуализации или контейнеров (VMware/KVM/OpenStack/Kubernetes) нуждается в быстрых блочных томах без привязки к локальным дискам на узлах.
- Нужна быстрая «перекоммутация» storage: перекинуть ресурсы между кластерами/зонами без физического доступа и ручной работы с простоями.
- Нужно сократить простой при обслуживании: менять узлы, не трогая storage-пул, и наоборот.
- Есть дисциплина эксплуатации сети: отдельный сегмент под storage, измерения, мониторинг, понятные SLO и обученные сотрудники.
Скорее не нужен, если…
- Только 10GbE без запаса, сеть общая и перегруженная, а выделять отдельный fabric нельзя.
- Команда не готова поддерживать RDMA/FC и сложную диагностику, а времени на обучение и пилот нет.
- Нужна файловая семантика (NFS/SMB), а не блочная: NVMe-oF решает задачу блочного хранилища, файловый слой придётся строить отдельно.
- Хранение «холодное» и latency не важна: проще SAS/SATA, обычный SAN/NAS или объектное хранилище.
- Нужна распределённая отказоустойчивость на уровне данных (репликация/erasure coding), которую вы ожидаете «из коробки» от транспортного протокола.
- Сейчас узкое место не в storage: CPU приложения, блокировки БД, сеть east-west, дисковый кеш — NVMe-oF не лечит архитектурные причины.
- Нельзя обеспечить предсказуемый fabric: периодические микроперегрузки, нестабильные MTU, отсутствуют базовые метрики потерь/задержек.
NVMe-oF ≠ Ceph
NVMe-oF — это транспорт и модель доступа к блочным устройствам: как доставить NVMe-команды к удалённому носителю. Ceph/RBD (и другие SDS) — это распределённое хранилище, где отказоустойчивость обеспечивается на уровне данных и протоколов репликации/EC. Их можно комбинировать, но назначение разное: NVMe-oF отвечает за «как подключиться», SDS — за «как хранить и переживать отказы».
Транспорты NVMe-oF: TCP, RDMA, Fibre Channel — что выбрать и почему
В NVMe-oF определены транспортные привязки (bindings) как минимум для TCP и RDMA; NVMe/FC развивается в рамках FC-экосистемы. Это фиксируется и в NVMe-oF 1.1a: спецификация описывает расширения NVMe для работы поверх fabric и упоминает transport bindings.
Сравнение транспортов NVMe-oF
| Транспорт | Где уместен | Плюсы | Минусы/риски | Требования к сети/железу | Типичный профиль задержки/нагрузки CPU |
|---|---|---|---|---|---|
| NVMe/TCP | Универсальный вариант для Ethernet; быстро стартовать, проще масштабировать | Простая интеграция в IP-сети; понятные инструменты; ниже порог входа | Может быть заметнее нагрузка на CPU и стек сети; чувствителен к IRQ/NUMA/настройкам; хвосты растут от congestion | Ethernet 25/50/100GbE желательно; отдельный VLAN/VRF; дисциплина MTU и QoS | Задержка выше RDMA при прочих равных; CPU-нагрузка часто выше, особенно на высоких IOPS |
| NVMe/RDMA (RoCE/IB/iWARP) | OLTP, latency-чувствительные нагрузки, максимально низкая добавочная задержка | Низкие задержки и хорошие хвосты при правильном fabric; меньше CPU на передачу данных | Сложнее сеть и эксплуатация; требования к lossless/ECN и диагностике; цена ошибки выше | RDMA-совместимые NIC, настроенный fabric, контроль congestion; навыки команды | Потенциально лучший p99/p99.9; CPU-нагрузка обычно ниже TCP при правильной настройке |
| NVMe/FC | Там, где уже есть зрелый FC-SAN и процессы | Предсказуемая SAN-операционная модель; привычные практики зондинга/эксплуатации | Другая экосистема и стоимость; не всегда рационально без существующего FC | FC-инфраструктура, HBА, SAN-процессы | Хорошая предсказуемость при зрелом FC-SAN, но зависит от дизайна |
NVMe/TCP часто становится «разумным дефолтом» для Ethernet-инфраструктуры: проще провести пилот, проще масштабировать, проще объяснить эксплуатацию. Практическая сторона NVMe/TCP на Linux описана в документации Red Hat — полезно хотя бы как ориентир по шагам и ограничениям поддержки: настройка NVMe/TCP.
RDMA — это путь к минимальным задержкам, но цена — сложность fabric и необходимость управлять congestion. Если у команды нет опыта и нет готовности инвестировать в эксплуатацию, RDMA легко превращается в «проект ради цифр», где выигрыши съедаются хвостами из-за микроперегрузок и ошибок конфигурации.
NVMe/FC логичен, когда FC-SAN уже есть и он хорошо управляется. Если FC нет, начинать «с нуля» ради NVMe/FC чаще всего сложно оправдать, если только это не корпоративная среда с уже принятыми SAN-процессами.
Типовая ошибка выбора
- Берём RDMA ради минимальной задержки, а потом выясняется, что fabric не отделён от общей сети, congestion не измеряется, потери лечат «настройками джамбо-фреймов и надеждой», а p99 в проде хуже, чем на TCP в хорошем IP-сегменте.
- Берём TCP “потому что проще”, а потом упираемся в CPU, IRQ и NUMA: сеть быстрая, а хосты не подготовлены, и вместо хранения оптимизируем softirq.
Из каких компонентов состоит NVMe-oF решение
У NVMe-oF почти всегда одна и та же базовая схема, разница — в реализации таргета и требованиях к fabric.
- Хосты (инициаторы)
ОС (чаще Linux), NVMe-oF стек, nvme-cli, настройка путей и политика failover. Здесь критичны: NUMA-локальность, IRQ affinity, сетевые очереди, правильная модель multipath. - Таргет (target/subsystem)
Варианты: - storage-платформа (аппаратная или программная);
- Linux-таргет (kernel-подход);
- user-space таргет на базе SPDK, который часто выбирают ради производительности и контроля над datapath. SPDK прямо описывает, что их NVMe-oF target — user space приложение, поддерживающее RDMA и TCP.
- Fabric
Коммутаторы, выделенный сегмент (VLAN/VRF), границы L2/L3, правила маршрутизации, QoS/ECN (если используется). Важно не путать «есть отдельный VLAN» и «есть отдельный fabric»: иногда трафик всё равно встречается в общих uplink’ах и начинает жить по законам oversubscription. - Discovery и жизненный цикл подключения
Discovery-контроллер позволяет хостам автоматически получать актуальные endpoints и подключаться по правилам. На Linux это отражается в workflow nvme-cli: сначала discovery, потом подключение контроллеров и namespace’ов — ровно в том смысле, как описано в connect-all.
Минимальный набор терминов, который стоит зафиксировать в команде до внедрения:
- NQN (NVMe Qualified Name) — идентификатор подсистемы/хоста.
- Namespace — то, что вы «монтируете» как блочный девайс.
- ANA/механизмы путей — как система понимает, какие пути активные/предпочтительные и как переключаться при отказах. Важно не называть это «магическим multipath»: поведение зависит от реализации и настройки, поэтому всегда нужен тест failover в пилоте.
Как считать latency budget и узкие места
Чтобы NVMe-oF не превратился в «вроде быстро, но непонятно почему иногда плохо», важно считать задержку как бюджет и сразу работать с хвостами.
Из чего складывается задержка
- Носитель и контроллер NVMe: медиум и FTL, внутренние очереди, фоновые процессы.
- Стек таргета: kernel- или user-space datapath, планирование CPU, блокировки.
- NIC/PCIe/NUMA: локальность к сокету, пропускная способность шин, распределение очередей.
- Сеть: сериализация пакетов, буферизация, микроперегрузки, congestion, потери/ретрансляции.
- Стек хоста: обработка прерываний, softirq, драйверы, планировщик и влияние приложений.
Latency budget и быстрые признаки узких мест
| Компонент | Как проверить / симптом / типичная причина |
|---|---|
| CPU на хосте | p99 растёт с ростом IOPS, CPU занято softirq: IRQ affinity не настроен, очереди NIC не распределены, NUMA-не локально |
| NUMA/PCIe | «Всё быстро на одном узле, медленно на другом»: сетевой адаптер и CPU в разных сокетах, данные ездят через межсокетную связь |
| Сеть | Вроде хватает полосы, но хвосты скачут: microburst, общий uplink, неучтённый oversubscription, потери и ретрансляции |
| MTU | Интермиттирующие проблемы и странные таймауты: MTU не совпадает end-to-end, где-то фрагментация/дроп |
| Таргет | При росте нагрузки плывёт p99/p99.9: нехватка ядер, конкуренция потоков, неоптимальный datapath |
| Очереди/queue depth | Низкая утилизация полосы при «вроде бы быстрых дисках»: слишком маленький QD, неправильные параметры I/O, приложение не умеет параллелизм |
Почти во всех прод-инцидентах важнее не «средняя» задержка, а хвосты. p99 и p99.9 показывают, насколько система предсказуема под нагрузкой. Средняя может выглядеть хорошо даже тогда, когда каждую секунду есть «плохие» запросы, которые ломают SLO приложения.
Практический подход: зафиксировать baseline на локальном NVMe (если сравниваете), затем измерить NVMe-oF на чистом fabric, затем добавить реальный профиль I/O приложения. Если хвосты растут — сначала искать причину в CPU/NUMA/сети, и только потом менять транспорт.
Практика выбора
- Определите workload
Блок или файл, read/write, sync-записи, размер IO, типичные burst’ы, требуемая глубина очереди. Важно понять, что именно чувствительно: latency или throughput. - Сформулируйте цели
SLO по p99 (и p99.9, если критично), IOPS/MBps, требования к отказоустойчивости, ограничения по бюджету. - Проверьте ограничения
Какая сеть реально доступна (25/50/100GbE), можно ли выделить отдельный fabric, какие компетенции есть у команды, насколько критична простота day-2. - Выберите транспорт
- Нужна минимизация рисков, привычная эксплуатация в IP-сети — NVMe/TCP.
- Нужны минимальные задержки и есть готовность поддерживать RDMA-fabric — NVMe/RDMA.
- Уже есть зрелый FC-SAN и процессы — NVMe/FC.
- Выберите реализацию таргета
Готовая storage-платформа, Linux-таргет или user-space. Если важны гибкость datapath и производительность, часто смотрят на SPDK. - Спроектируйте HA и multipath
Сколько путей, как будет происходить failover, что считается отказом, какие таймауты приемлемы для приложений. - Сделайте пилот с критериями “успех/провал”
Не «попробовали — вроде быстро», а чётко: p99 на профиле I/O, поведение при отказе пути, деградация при перегрузке сети, наблюдаемость метрик.
Требования, которые чаще всего недооценивают
Отдельный storage fabric — главный фактор предсказуемости. Это не обязательно отдельные коммутаторы, но как минимум — отдельный сегмент с понятной маршрутизацией и отсутствием «случайных» соседей по uplink’ам. В больших системах часто выигрывает разделение на VRF/отдельные L3-домены, чтобы исключить неожиданную взаимную деградацию.
MTU и jumbo frames работают, если соблюдены end-to-end. Если где-то по пути MTU меньше, вы можете получить фрагментацию, дропы и странные таймауты. Jumbo не лечит congestion и не заменяет правильный дизайн uplink’ов.
NUMA и IRQ affinity — классическая причина «вдруг медленно» на двухсокетных серверах. Если NIC «сидит» в одном сокете, а прерывания и обработка уходят в другой, хвосты растут без видимых причин. В NVMe-oF это особенно заметно, потому что datapath чувствителен к распределению CPU и очередей.
Oversubscription — когда «по паспорту 100GbE», а реально fabric делит аплинк между множеством потоков. NVMe-oF может выглядеть отлично на стенде и резко хуже в проде, если storage-трафик встречается с east-west или бэкапом.
Мини-чек-лист перед пилотом:
- Проверить MTU по всей трассе, а не только на хосте и свитче.
- Проверить потери, ретрансляции и признаки congestion на storage-сегменте.
- Развести трафик: storage vs management vs east-west (хотя бы логически).
- Зафиксировать baseline latency на локальном NVMe и целевые p99/p99.9 под нагрузкой.
Безопасность NVMe-oF: изоляция, аутентификация, минимизация риска
Базовый принцип простой: storage fabric не должен быть общедоступным. NVMe-oF — это доступ к блочным устройствам; ошибка сегментации превращается в максимально неприятный инцидент.
Практические меры:
- Изоляция: отдельный VLAN/VRF/подсеть, запрет маршрутизации «везде и всюду», ограничение источников.
- Контроль доступа по идентичности: хосты и подсистемы идентифицируются NQN, доступ строится через правила на таргете. Это не «просто IP-фильтр», а модель «кто имеет право видеть какие namespace’ы».
- Аутентификация для NVMe/TCP: используйте механики, поддерживаемые стеком и tooling’ом, и обязательно вводите процедуры ротации. Ориентироваться по шагам можно на документацию NVMe/TCP на Linux, но конкретная политика всегда определяется вашим окружением.
- Логи и аудит: подключения, изменения конфигурации, отказоустойчивость, ошибки путей.
- Минимизация blast radius: сегментирование по зонам, отдельные подсистемы для разных классов нагрузок, ограничения доступа «по умолчанию запрещено».
Эксплуатация (Day-2): мониторинг, алерты, тестирование отказов
NVMe-oF живёт или умирает в эксплуатации. Без мониторинга хвостов и сети его легко принять за «нестабильную технологию», хотя проблема будет в fabric или хостах.
Что мониторить на хостах:
- p99/p99.9 latency на уровне блочного устройства и приложения;
- глубину очередей, долю ожидания I/O;
- CPU softirq, распределение IRQ, утилизацию по NUMA;
- сетевые дропы, ретрансляции, ошибки интерфейсов.
Что мониторить на таргете:
- CPU и очереди обработки, насыщение NIC;
- рост latency и корреляцию с нагрузкой;
- ошибки путей, события disconnect/reconnect.
Регулярные проверки:
- discovery и корректность подключений (автоматизация через nvme-cli и конфиги);
- тест failover: отключение порта/линка, перезапуск сервиса, деградация uplink;
- тест «шумный сосед»: как система ведёт себя при микроперегрузке сети.
План обновлений:
- kernel, nvme-cli, firmware NIC и компоненты таргета обновляются только с проверкой совместимости и обязательным повтором тестов p99/p99.9 на эталонном профиле I/O.
Что ломается чаще всего: несоответствие MTU, congestion, NUMA/IRQ, случайный запуск storage-трафика по общей сети, неверная карта путей и неоттестированный failover.
Быстрый старт на Linux
На Linux пользовательский путь почти всегда один: есть endpoint discovery или конкретный таргет, есть подсистема (NQN), подключаемся и проверяем, что появился блочный девайс.
Логика шагов:
- Получить адрес discovery/таргета и параметры транспорта.
- Выполнить discovery, получить список доступных подсистем и endpoints.
- Подключить нужную подсистему/namespace.
- Проверить, что устройство появилось, и измерить базовую задержку.
- Включить и проверить multipath/политику путей, затем провести тест отказов.
Если нужно посмотреть, как это выглядит на уровне tooling, удобно ориентироваться на nvme-cli: различие между ручным подключением и discovery-подходом хорошо видно в описании connect-all. Для NVMe/TCP полезны практические шаги в документации RHEL — даже если вы не на RHEL, структура действий и типовые ограничения помогают не пропустить базовые проверки.
Типовые сценарии и рекомендации
1) Кластер гипервизоров (виртуализация)
Требования: предсказуемость, быстрые блочные тома, простая эксплуатация, обязательный failover.
Рекомендация: NVMe/TCP как базовый выбор для Ethernet.
Риски/проверки: multipath и тест отказа линка; контроль congestion на uplink; NUMA/IRQ на хостах, иначе CPU станет узким местом.
2) OLTP и latency-чувствительные базы
Требования: низкий p99/p99.9, стабильность под нагрузкой, дисциплина по сети.
Рекомендация: NVMe/RDMA при готовности поддерживать RDMA-fabric.
Риски/проверки: настройка congestion и диагностика; пилот с реальным профилем I/O; тест «бурстов» и микроперегрузок.
3) Уже есть FC-SAN и процессы эксплуатации
Требования: управляемость, предсказуемость, соответствие корпоративным практикам.
Рекомендация: NVMe/FC как эволюция существующей SAN-модели.
Риски/проверки: корректный дизайн зон и путей; тест failover; соответствие SLO для хвостов.
4) Kubernetes-платформа с блочными PV
Требования: масштабируемость, понятная модель томов, наблюдаемость, стабильность в мульти-тенант среде.
Рекомендация: NVMe/TCP как практичный выбор, особенно если важно быстрее прийти к работающей эксплуатации.
Риски/проверки: шумные соседи и oversubscription; алерты по p99; корректная сегментация сети.
5) AI/ETL и потоковые задачи
Требования: throughput часто важнее микро-латентности, большие последовательные чтения/записи.
Рекомендация: NVMe/TCP нередко достаточно, если сеть и хосты готовы.
Риски/проверки: считать CPU и NUMA, иначе «полоса есть, а не едет»; проверить, что uplink не общий с интенсивным east-west.
Ошибки внедрения и как их избежать
- Latency скачет → congestion/oversubscription → выделить fabric, измерять потери и хвосты, убрать общие uplink’и.
- В тесте быстро, в проде плохо → другой IO pattern, sync-записи, burst’ы → тестировать реальным профилем, фиксировать p99/p99.9.
- CPU внезапно 100% на хосте → IRQ/softirq/NUMA, сетевые очереди → настроить affinity, проверить NUMA-локальность, распределить очереди.
- Низкая утилизация сети → маленький queue depth, приложение не параллелит → настроить QD, проверить параметры I/O и параллелизм.
- Периодически отваливается путь → MTU mismatch, ACL, маршрутизация → проверка end-to-end MTU, упрощение трассы, чёткие правила доступа.
- Сложно диагностировать деградацию → нет метрик по хвостам и сети → мониторинг p99/p99.9, дропов, ретрансляций, событий путей.
- Multipath «вроде есть», но не работает → не тестировали failover → обязательный тест отключения порта/линка и проверка времени восстановления.
- RDMA не даёт обещанных хвостов → fabric настроен «как обычный Ethernet» → измерять congestion, внедрить дисциплину управления RDMA-сетью.
- Таргет становится узким местом → нехватка CPU/очередей → capacity planning по ядрам, нагрузочное тестирование, оптимизация datapath.
- Случайно смешали storage и management → непредсказуемые пики → сегментация, отдельные политики QoS, запрет лишней маршрутизации.
- Непонятно, кто имеет доступ к томам → нет дисциплины NQN/ACL → явные правила доступа, аудит подключений, принцип наименьших привилегий.
- Обновления ломают производительность → нет регрессионных тестов → фиксированный набор тестов p99/p99.9 и throughput перед внедрением обновлений.
Вывод
Матрица выбора транспорта
- NVMe/TCP — лучший старт и самый частый выбор для Ethernet, если нужен баланс простоты и производительности.
- NVMe/RDMA — если критичны хвосты задержек и команда готова поддерживать RDMA-fabric как продукт.
- NVMe/FC — если у вас уже есть зрелый FC-SAN и вы хотите сохранить операционную модель, не переучивая всё на IP-fabric.
Выбирайте NVMe-oF, если…
- важна гибкость: общий NVMe-пул для многих хостов и быстрые миграции ресурсов;
- нужно снизить привязку данных к конкретным узлам;
- есть SLO по latency и вы готовы мерить p99/p99.9, а не «среднюю»;
- можно выделить storage-fabric и обеспечить дисциплину сети;
- вы готовы тестировать failover и держать наблюдаемость как обязательное требование.
Не выбирайте, если…
- сеть общая и перегруженная, выделить сегмент нельзя;
- нет компетенций и времени на пилот и эксплуатацию;
- нужна файловая семантика, а не блок;
- требуются встроенные механизмы распределённой отказоустойчивости данных;
- узкое место сейчас не storage, и NVMe-oF не изменит картину.
Чек-лист
- Есть выбранный профиль I/O и критерии успеха (p99/p99.9, IOPS/MBps).
- Storage-трафик отделён логически и проверен на отсутствие общих bottleneck uplink.
- MTU проверен end-to-end, зафиксированы параметры сети.
- Настроены базовые метрики: latency хвостов, дропы, ретрансляции, CPU softirq.
- Хосты проверены по NUMA/IRQ и распределению очередей NIC.
- Понимание путей: сколько, какие, как переключаются; multipath/политики определены.
- Сценарии отказов описаны и будут протестированы (линк/порт/таргет/коммутатор).
- Правила доступа сформулированы: кто к чему подключается, какой NQN/ACL.
- План отката и регрессионные тесты на производительность подготовлены.
- Зафиксирована «карта» ответственности: кто отвечает за сеть, кто за хосты, кто за таргет, кто принимает решение по итогам пилота.
Если подходить к NVMe-oF как к системному продукту — с отдельным fabric, измерениями хвостов, тестом отказов и дисциплиной в хостах — он даёт именно то, ради чего его выбирают: гибкий и быстрый доступ к NVMe-ресурсам без привязки к конкретным серверам.
Нажимая кнопку «Отправить», я даю согласие на обработку и хранение персональных данных и принимаю соглашение