В облачных средах на «голом железе» с ультравысоким IOPS стандартный поиск де��крипторов в Виртуальной файловой системе (VFS) Linux и атомарный подсчет ссылок создают измеримую борьбу за блокировки ядра. Регистрация фиксированных файлов io_uring (IORING_REGISTER_FILES) и предоставленные буферные кольца позволяют обойти атомарное увеличение счетчика ссылок для каждого запроса и переключения контекста системных вызовов, обеспечивая субмикросекундную задержку хранилища NVMe.
Прямая индексация файлов таблицы & Блокировки без ссылок
Каждый традиционный системный вызов read(), write(), или preadv2() заставляет ядро Linux сопоставлять целочисленный дескриптор файла с таблицей файлов процесса и выполнять атомарные операции подсчета ссылок fget() и fput() . Когда многопоточные движки баз данных или прокси хранилищ выполняют миллионы операций в секунду с общими дескрипторами файлов, «прыжки» строк кэша ЦП на счетчике ссылок struct file становятся главным узким местом пропускной способности.
IORING_REGISTER_FILES Архитектура прямой индексации
Предварительно зарегистрировав массив открытых дескрипторов файлов с помощью io_uring_register(), ядро закрепляет базовые ссылки struct file ��дин раз при инициализации. Последующие элементы очереди отправки (SQE) ссылаются на файлы по прямому целочисленному индексу с флагом IOSQE_FIXED_FILE , исключая атомарные спинлоки fget() и fput() на критическом пути ввода-вывода.
Сравнение интерфейсов хранения ядра
Сравнение накладных расходов системных вызовов на операцию, подсчета ссылок VFS и одноядерной пропускной способности NVMe для различных интерфейсов хранения Linux:
| Архитектура интерфейса ввода-вывода | Стоимость системного вызова на оп. | Подсчет ссылок файлов VFS | Макс. IOPS (одно ядро) |
|---|---|---|---|
Синхронный preadv2() |
1 сис. вызов / операция | fget() / fput() атомарные блокировки |
420,000 IOPS |
Нативный AIO в Linux (io_submit) |
1 сис. вызов / пакет | Атомарные счетчики ссылок при отправке | 850,000 IOPS |
io_uring Фиксированные файлы + SQPOLL |
0 syscalls (опрос кольца ядра) |
Нулевые (предварительно зарегистрированная прямая таблица) | 3,800,000 IOPS |
Инварианты хранилища высокой пропускной способности
Руководство по системной инженерии для развертывания дескрипторов фиксированных файлов и зарегистрированных буферов на узлах NVMe без ОС:
- Предварительное выделение разреженной таблицы фиксированных файлов: Выделяйте таблицы фиксированных дескрипторов с избыточной емкостью с помощью
IORING_REGISTER_FILES_SPARSEи позволяйте ядру устанавливать недавно принятые сокеты или открытые файлы напрямую в зарегистрированную таблицу черезIORING_OP_OPENATсIOSQE_FIXED_FILE. - Интеграция кольца предоставленных буферов: Связывайте фиксированные файлы с
IORING_REGISTER_PBUF_RING, чтобы ядро динамически выбирало предварительно сопоставленные буферы страниц в момент завершения, а не закрепляло буферы памяти в ожидании готовности сокета или блока. - Прямой проброс NVMe (
io_uring_cmd): Для сырых символьных устройств NVMe (/dev/ng0n1) комбинируйте зарегистрированные файлы и буферы с 80-байтными командами проброса SQE для отправки полезных данных NVMe непосредственно в очереди аппаратного контроллера без накладных расходов на выделение bio на уровне блоков.
Исследуйте облачную инфраструктуру нового поколения
Масштабируйте свои корпоративные рабочие нагрузки с производительностью NVMe на выделенных серверах в WinWinHost. Ознакомьтесь с нашими руководствами по проектированию для Linux eBPF & защита от DDoS через XDP, Развертывания Blue/Green без простоев, или свяжитесь с нашей командой облачных инженеров.