Работа на таких скоростях как 10 Гбит/с в связи с ростом сетевого трафика все больше становится обыденностью и даже необходимостью, нежели чем привилегией производительных платформ на базе топовых процессоров семейства Intel Xeon.
Достигается это во многом путем оптимизации процедуры обработки пакетов: лимитирующий скорость ряда процессов сетевой стек Linux можно обойти разными способами. Одним из таких эффективных и опенсорсных решений остается разработанная еще в 2010 году компанией Intel технология DPDK, которая по-прежнему продолжает развиваться сообществом разработчиков.
Data Plane Development Kit или DPDK - это в первую очередь набор библиотек и драйверов, способствующий ускорению обработки пакетов за счет взаимодействия сетевого оборудования напрямую с приложениями, минуя тем самым ядро Linux.
Непосредственно сама архитектура сетевого устройства состоит из трех компонентов или так называемых плоскостей, осуществляющих перемещение пакетов от интерфейса A к интерфейсу B: управляющий уровень или Control Plane, модуль наблюдения или Management Plane, передающий уровень или Data Plane.
Модуль наблюдения. Абстрактная плоскость, в чьи задачи входит отслеживание состояния устройства. Уровень отвечает за мониторинг ряда параметров, а также за конфигурацию узла.
Управляющий уровень. Плоскость Control Plane определяет, куда должен идти пакет, фактически его путь. Обычно он включает в себя несколько протоколов, таких как RIP, OSPF и EIGRP.
Передающий уровень. Data Plane используется для быстрой пересылки пакетов. Как правило, используется кэширование инструкций по пересылке пакетов: в случае попадания в кэш пакет будет перенаправлен либо же будет отдана команда плоскости управления для определения дальнейшего пути пакета.
В задачи современных серверов входят не только ресурсоемкие локальные вычисления, но и интенсивная работа с сетью. Растущие нагрузки накладывают все больше требований к параллелизму и скорости отклика. Чтобы удовлетворить этим запросам разрабатываются более скоростные сетевые адаптеры, открывающие возможность для обеспечения пропускной способности 40Gb, 50Gb и даже 100Gb.
Несмотря на такой прогресс «железа», узким местом по-прежнему остается традиционный метод обработки пакетов в UNIX-системах. По этой причине для функционирования DPDK настройка Linux видится единственным выходом.
Для загрузки пакетов ядро должно запустить обработчик прерываний, обработать пакет в сетевом стеке ядра и при необходимости передать нужные пакеты соответствующим приложениям пользовательского пространства, после чего приложение уже может их скопировать и обработать.
В случае высокоскоростных интерфейсов и высоких рабочих нагрузок ядру приходится обрабатывать миллионы прерываний из-за большого объема пакетов, что в любой момент может привести к перегрузке системы и сокращению времени отклика. Кроме того, сетевой стек Linux должен удовлетворять различным потребностям приложений и пользователей, что в свою очередь приводит к понижению эффективности сети и невозможности обеспечить быструю обработку пакетов. Если приложение собирается обработать пакет, оно должно скопировать его из пространства ядра, что приводит к многократным обращениям к ЦП и, соответственно, большим задержкам из-за переключения между пространством ядра и пространством пользователя.
В то же время процессоры на архитектуре x86 существенно выиграли по производительности за счет интеграции большего количества ядер в один сокет. Поэтому для использования преимуществ многоядерных процессоров ядро и ОС должны быть соответствующим образом оптимизированы. DPDK как раз таки с этой целью и был представлен Intel для обработки сетевых пакетов и впоследствии перерос в отдельный проект с открытым исходным кодом.
Для максимального увеличения производительности сети DPDK использует сразу целый набор методов.
По сравнению с драйвером режима IRQ, драйвер режима опроса или PMD использует выделенный процесс либо поток для опроса очереди сетевого адаптера. После загрузки пакетов PMD сможет получать их в непрерывном режиме. Если же пакеты отсутствуют, PMD продолжит их опрашивать на наличие, оставаясь в непрерывном цикле.
Как правило, для потока режима опроса выделяется по меньшей мере два ядра и при этом изолируется выделенный ЦП, что позволяет избежать переключения контекста и снизить частоту кэш-промахов.
В задачи драйвера пользовательского режима входит устранение излишних копий памяти между ядром и пользовательским пространством, а также предотвращение переключения контекста.
После снятия ограничений структуры данных ядра драйвер пользовательского режима может использовать оптимизированные функции mbuf для повышения производительности. Кроме того, приложение может использовать этот драйвер для тонкой настройки и оптимизации.
Выполнение задач приложения и драйвера в пользовательском режиме планируются ядром - такой подход приводит к высокой частоте кэш-промахов и низкой производительности, и при некоторых рабочих нагрузках такая ситуация неприемлема.
При использовании DPDK загрузка процессора снижается на порядок: набор технологий использует функцию сходства потоков ядра Linux для привязки потока к определенному ядру. Для удаления конкретных ядер из планировщика рекомендуется использовать параметры isocpu.
Таким образом, драйвер приложения и драйвер режима опроса будут привязаны к определенному процессору, недоступному для планирования других задач.
DPDK использует методы, позволяющие сократить издержки, связанные с доступом к памяти, тем самым обеспечивая заметный выигрыш в производительности:
Конкуренция за память - распространенная проблема многоядерных систем, которая приводит к высокой нагрузке на ЦП и низкой эффективности. DPDK пытается избежать этой ситуации, используя структуры mallocing и объекты, выделяемые для локального ядра.
Кроме того, чтобы использовать неблокирующий код, DPDK применяет инструкцию Intel Atomic CMPXCHG и использует кольцевой буфер для оптимизации очередей пакетов и синхронизации между ядрами.
В исходном коде DPDK можно увидеть и множество других незаметных приемов, приводящих в конечном счете к значительному повышению производительности. Среди таковых:
Основные компоненты DPDK включают драйверы PMD, ускорители, компоненты классификации, QOS, расширения и структуры пакетов.
Ядро. Основные функции, включая EAL (уровень абстракции контекста), и четыре основных компонента: диспетчер кольца (librte_ring), диспетчер пула памяти (librte_mempool), управление буфером сетевых пакетов (librte_mbuf) и диспетчер таймера (librte_timer).
PMD. Драйверы режима опроса для всех поддерживаемых сетевых адаптеров.
Ускорители. Аппаратные ускорители, такие как QAT и CRYPTO.
Компоненты классификации. Упрощают поиск входящих пакетов в таблице потоков.
Расширения. Различные дополнения для разных сценариев использования.
QoS. Оценка качества обслуживания.
PKT Framework. Предназначен для обработки и пересылки пакетов.
Несмотря на широкие возможности Data Plane Development Kit, рассмотрим два основных сценария, демонстрирующих использование DPDK с обработкой сетевых данных.
Поскольку DPDK - это прежде всего набор утилит для разработки серверного программного обеспечения, его основной сферой применения является виртуализация центров обработки данных.
На схеме ниже один сервер имеет два физических сетевых адаптера с пропускной способностью 10 GbE и 40 GbE и поддержкой высоких рабочих нагрузок. Эти сетевые карты управляются PMD в пользовательском пространстве и образуют интерфейс DPDK. Виртуальные свитчи, подключенные к физическим портам и другим портам виртуальной машины, эмулируются vhost на основе DPDK.
Рабочая нагрузка поступает с физического порта и распределяется виртуальным свитчем по разным виртуальным машинам в соответствии с настроенными правилами потока.
Благодаря ускорению DPDK критически важное приложение в каждой виртуальной машине будет соответствовать целевым показателям производительности и уровням задержки. Между тем, использование технологии ускоренной виртуализации Intel DPDK снизит затраты на оборудование.
DPDK - это низкоуровневый компонент, который обычно рассматривается как точка входа для расширенной обработки пакетов данных. Многие службы (например, функция виртуальной сети, VNF) будут получать и отправлять пакеты от и в DPDK. DPDK в свою очередь передает пакет виртуальному коммутатору на высокой скорости. Затем VNF в разных виртуальных машинах сможет использовать драйвер режима опроса пользователя DPDK для приема и передачи пакетов между различными VNF и виртуальными коммутаторами.
Таким образом:
Рассмотрим теперь два приложения DPDK, на примере которых можно разобрать общую последовательность при разворачивании среды разработки DPDK: l2fwd и Open vSwitch с ускорением DPDK.
Все, что нам потребуется в качестве среды разработки, - это исходный код.
Приложение L2 Forwarding (l2fwd) работает в реальных и виртуализированных средах и выполняет L2-пересылку для каждого пакета, полученного на RX_PORT.
Порт назначения - это тот порт, который сопряжен с маской порта. Таким образом, если первые четыре порта включены (маска порта 0xf), порты 1 и 2 осуществляют пересылку друг другу, равно как и порты 3 и 4. Кроме того, если включено динамическое обновление MAC-адреса, их значения будут изменены в соответствии с правилами:
В общем случае схема запуска L2fwd сводится к следующим шагам:
Пример с l2fwd, представленный выше, не соотносится с типичными вариантами использования DPDK. Это, скорее, тестовый пример, который не предоставляет клиентам полезных возможностей. Основное назначение DPDK - виртуализация сетевых функций (NFV), поэтому стоит упомянуть еще и об Open vSwitch в качестве примера.
Когда DPDK ускоряет Open vSwitch, на программном уровне происходят три ключевых изменения: