virtio_net: rx queue full — Потери пакетов в виртуальных машинах KVM
Архитектура ошибки и симптомы сбоя
Сообщение «virtio_net: rx queue full, packets dropped on guest interface» регистрируется драйвером паравиртуальной сети virtio_net внутри гостевой ОС Linux (KVM / QEMU / Proxmox / OpenStack). Ошибка означает, что виртуальное кольцо дескрипторов приема пакетов (Virtqueue RX Ring) заполнено, и гостевое ядро не успевает считывать входящий трафик из очередей vhost-net хоста. Сетевой стек ВМ начинает массово сбрасывать пакеты, приводя к падению TCP throughput и росту задержек (Latency Jitter).
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| Virtqueue (RX/TX) | Circular Ring Buffer | Кольцевой буфер обмена сетевыми пакетами между гипервизором QEMU и ВМ. |
| vhost-net | In-Kernel Accelerator | Ядерный модуль хоста KVM для прямой передачи пакетов в обход QEMU user space. |
| Multiqueue (MQ) | Parallel Queues | Распределение очередей сетевой карты по нескольким vCPU виртуальной машины. |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Проверка сброшенных пакетов внутри виртуальной машины
# Просмотр статистики ошибок и переполнения очередей virtio_net:
ethtool -S eth0 | grep -E "(rx_drop|rx_no_buf|rx_missed|rx_queue_full)"
# Проверка текущего и максимального размера буферов:
sudo ethtool -g eth0Сценарий 2: Увеличение размера кольцевого буфера RX дескрипторов (до 1024 / 2048)
# Увеличение размера очереди приема внутри гостевой ОС:
sudo ethtool -G eth0 rx 1024 tx 1024
# Для постоянного применения создайте dispatcher-скрипт в networkd или NetworkManager:
# /etc/network/interfaces: pre-up ethtool -G eth0 rx 1024Сценарий 3: Активация VirtIO Multiqueue в конфигурации KVM / Proxmox
Одноочередной интерфейс virtio_net упирается в производительность одного ядра vCPU. Включите многоочередность:
# В конфигурации libvirt (virsh edit VM_NAME) в секции <interface>:
<model type='virtio'/>
<driver name='vhost' queues='4' rx_queue_size='1024' tx_queue_size='1024'/>
# В Proxmox VE:
# Параметры оборудования -> Сетевая карта -> Multiqueue: 4 (по числу vCPU).Сценарий 4: Привязка очередей прерываний RPS / XPS внутри гостя
# Распределение входящего трафика по всем vCPU виртуальной машины (для интерфейса eth0):
for f in /sys/class/net/eth0/queues/rx-*/rps_cpus; do echo "f" | sudo tee $f; doneITSTM выполнит оптимизацию vhost-net, тонкую настройку virtio multiqueue, SR-IOV и сетевых политик OVS/DPDK.
Частые вопросы (FAQ)
Сколько очередей (queues) нужно задавать для VirtIO Multiqueue?
Количество очередей должно быть равно количеству vCPU виртуальной машины (но обычно не более 8-16), чтобы каждая очередь сетевой карты обрабатывалась выделенным ядром процессора без межъядерных блокировок.
Что дает опция rx_queue_size='1024' в QEMU/libvirt?
По умолчанию QEMU выделяет буфер размером всего в 256 дескрипторов. Увеличение до 1024 или 2048 предотвращает сброс пакетов во время кратковременных пиков трафика (Microbursts).
Как проверить, используется ли модуль vhost-net на хосте?
Выполните команду lsmod | grep vhost. Наличие модуля vhost_net подтверждает прямую высокоскоростную обработку трафика в ядре хоста.
Влияет ли CPU Pinning хоста на сетевые потери в virtio_net?
Да. Если vCPU виртуальной машины конкурируют за физические ядра с другими задачами хоста, поток virtio_net вовремя не получает процессорное время, вызывая переполнение буфера RX.