Выберите продукт

Linux tc qdisc на VDS: fq_codel vs cake vs fq — борьба с bufferbloat и latency spikes

Разбираем очереди tc qdisc в Linux на VDS: fq_codel, cake и fq. Покажу, как измерять bufferbloat и latency spikes, а затем настроить shaping на egress и ingress через ifb, policing и полезные команды iproute2.
Linux tc qdisc на VDS: fq_codel vs cake vs fq — борьба с bufferbloat и latency spikes

Если на VDS «всё быстро» по bandwidth, но SSH/VoIP/игровой трафик и веб-админка периодически замирают, а графики показывают latency spikes во время загрузок, почти всегда виноват bufferbloat: слишком глубокие очереди в стеке или у провайдера, которые набиваются пакетами и превращают задержку в «резину».

В Linux это лечится дисциплинами очередей (tc qdisc) и аккуратным shaping: мы намеренно делаем «узкое место» на своей стороне и включаем умное управление очередью, чтобы очередь была короткой, а задержка — стабильной. Ниже — практичный разбор трёх популярных вариантов: fq, fq_codel и cake, плюс рабочие схемы для egress/ingress на сервере.

Ключевые понятия: qdisc, egress/ingress и почему на VDS это важно

qdisc — это алгоритм очереди на сетевом интерфейсе Linux. Он решает, в каком порядке отправлять пакеты, сколько держать их в буфере и как делить полосу между потоками (flows).

  • egress — исходящий трафик (из вашей VDS наружу). Его шейпить проще всего: вы контролируете отправку.
  • ingress — входящий трафик (в вашу VDS). Шейпить «в лоб» нельзя, потому что пакеты уже приехали. Поэтому используют обходные техники: ifb (перенаправление входящего в виртуальный интерфейс и shaping там) или ingress policing (жёсткое ограничение с дропом).

На VDS bufferbloat часто проявляется так:

  • качаете бэкап/образы — и SSH начинает «думать» по 1–3 секунды;
  • параллельные запросы к API дают всплески задержки;
  • пакетная обработка (CI, apt/yum, docker pull) ломает интерактивность;
  • в пике очереди растут либо в гостевой ОС, либо «где-то до вас» (виртуальный свитч/аплинк).

Что выбрать: fq vs fq_codel vs cake (коротко и по делу)

Важно разделять две задачи: (1) «справедливость» между потоками (fair queueing), (2) активное управление очередью (AQM), чтобы очередь не раздувалась и не превращалась в задержку.

fq (Fair Queueing): «дёшево и сердито»

fq — честная очередность по потокам: много маленьких очередей вместо одной большой. Это уже помогает против сценария «один жирный поток забил трубу». Но у fq нет полноценного механизма удержания задержки на целевом уровне — поэтому против классического bufferbloat он помогает ограниченно.

Когда уместно:

  • нужна максимальная простота и минимальная стоимость по CPU;
  • как быстрый апгрейд поверх дефолтной очереди;
  • когда shaping вы делаете другим способом, а qdisc нужна в основном для fairness.

fq_codel: хороший дефолт для многих серверов

fq_codel = fair queueing + CoDel (Controlled Delay). CoDel следит за sojourn time (временем пакета в очереди) и начинает дропать или ECN-маркировать пакеты, когда очередь «раздувается».

Плюсы:

  • часто отлично гасит bufferbloat без тонкой настройки;
  • предсказуемо работает на egress;
  • обычно «просто работает» как безопасный универсальный выбор.

Минусы:

  • сам по себе не является шейпером: если вы хотите гарантированно держать скорость ниже аплинка, нужен отдельный shaping (HTB/TBF) или использовать cake;
  • на ingress всё равно потребуется схема с ifb или policing.

cake: «комбайн» для shaping и борьбы с задержкой

cake (Common Applications Kept Enhanced) совмещает shaping и AQM: умеет ограничивать скорость, управлять очередями и обеспечивать справедливость. В анти-bufferbloat задачах это часто самый короткий путь к «ровной» задержке, потому что сущностей меньше: одна qdisc вместо связки шейпера и AQM.

Плюсы:

  • простой и сильный shaping на egress;
  • хорошая стабилизация задержек при нагрузке;
  • встроенная справедливость между потоками без отдельной сборки «HTB + ...».

Нюансы:

  • может быть тяжелее по CPU на очень больших скоростях;
  • серверные сценарии не всегда выигрывают от «продвинутых» режимов (например, diffserv), если трафик не размечен;
  • виртуализация и offload’ы могут менять поведение (ниже покажу, где смотреть).
FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Как понять, что у вас bufferbloat, и где он сидит

Перед настройкой полезно понять, где именно растёт очередь:

  • в вашей VDS (qdisc на vNIC);
  • у провайдера до вас (аплинк/виртуальный коммутатор/физический порт);
  • не сеть вообще, а CPU/IO-перегруз, который выглядит как «сетевые лаги».

Быстрый тест на latency spikes под нагрузкой

Делайте две вещи параллельно: (1) грузите канал, (2) меряете RTT до стабильной точки (например, до шлюза в той же сети). Логика простая: если при насыщении канала RTT растёт на порядок — очередь где-то на пути слишком глубокая.

Если при полной загрузке канала RTT растёт с условных 1–3 мс до 100–2000 мс — это почти наверняка bufferbloat или очереди без AQM.

Смотреть очереди и статистику tc

Сначала найдите имя интерфейса (на VDS это может быть eth0, ens3, VLAN-интерфейс и т. п.) и посмотрите текущие qdisc:

ip -br link

tc -s qdisc show dev eth0

tc -s class show dev eth0

Подсказки:

  • если растут backlog и задержка, но дропов нет — скорее всего очередь просто «распухает»;
  • если есть дропы на вашей qdisc при корректном rate — это нормально (AQM «пилит» очередь), но дропов не должно быть «лавиной» на ровном месте;
  • на ingress проблема может быть «до» вашей машины, поэтому статистика eth0 не всегда отражает реальность.

Если хотите глубже копнуть мониторинг shaping/очередей на сервере, пригодится отдельный материал про практический контроль трафика: мониторинг и шейпинг трафика на VDS.

Вывод tc -s qdisc: статистика очередей и дропов на сетевом интерфейсе

Базовый рецепт: ограничьте egress чуть ниже реального аплинка

Ключевая идея anti-bufferbloat shaping: сделать так, чтобы очередь формировалась у вас (в управляемой qdisc), а не в неизвестном буфере по пути. Поэтому скорость обычно задают на 1–5% ниже устойчивой (реально наблюдаемой) скорости.

Нюанс VDS: «реальная» скорость может плавать из‑за соседей и политики провайдера. Практика такая: измеряете устойчивую скорость длинным тестом, берёте консервативное значение и проверяете RTT под нагрузкой.

Вариант 1: cake на egress (простой и часто достаточный)

Ставим cake прямо в root qdisc и задаём bandwidth:

tc qdisc replace dev eth0 root cake bandwidth 900mbit besteffort

Где 900mbit — пример для линка «около 1 Гбит/с». Проверка:

tc -s qdisc show dev eth0

Если под нагрузкой RTT перестал «взлетать», а интерактивность вернулась — вы попали в правильную точку rate.

Вариант 2: HTB (или TBF) + fq_codel (классическая связка)

Если вам нужен явный shaping через классы (или вы привыкли к HTB), делайте так: HTB ограничивает скорость, а fq_codel держит очередь короткой внутри класса.

tc qdisc replace dev eth0 root handle 1: htb default 10

tc class replace dev eth0 parent 1: classid 1:10 htb rate 900mbit ceil 900mbit

tc qdisc replace dev eth0 parent 1:10 handle 10: fq_codel

Плюс — расширяемость (классы/приоритеты). Минус — больше сущностей и больше шансов ошибиться в handle/classid.

Ingress: ifb vs ingress policing — что выбрать на VDS

С входящим трафиком сложнее: пакеты уже пришли на интерфейс. Поэтому «нормальный» shaping входа достигается через перенаправление в ifb (и далее — shaping как на egress), либо через policing (дропаем лишнее на входе).

Почему policing часто даёт хуже задержку и throughput

Policing не «укладывает» пакеты в очередь — он просто отбрасывает при превышении. Для TCP это означает потери, ретрансляции и иногда «пилу» по скорости. В реальности policing подходит как быстрый и грубый ограничитель, но обычно проигрывает ifb по качеству для интерактивного трафика.

Ingress shaping через ifb (практическая схема)

Схема: включаем ifb, поднимаем ifb0, вешаем ingress qdisc на eth0 и зеркалим трафик в ifb0, где уже ставим cake или HTB+fq_codel.

modprobe ifb numifbs=1

ip link add ifb0 type ifb
ip link set dev ifb0 up

tc qdisc replace dev eth0 handle ffff: ingress

tc filter replace dev eth0 parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev ifb0

Теперь шейпим «входящий» на ifb0. Пример с cake:

tc qdisc replace dev ifb0 root cake bandwidth 900mbit besteffort

Или вариант «классикой» через HTB+fq_codel:

tc qdisc replace dev ifb0 root handle 1: htb default 10

tc class replace dev ifb0 parent 1: classid 1:10 htb rate 900mbit ceil 900mbit

tc qdisc replace dev ifb0 parent 1:10 handle 10: fq_codel

Критично: ingress rate почти всегда ставят чуть ниже реального входящего лимита, иначе очередь снова «уедет» в провайдера.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Что насчёт netem: когда он нужен и как не навредить

netem — qdisc для эмуляции задержки, джиттера, потерь и дубликатов. Это полезно на стенде, чтобы проверить поведение приложения в «плохой сети». Но для борьбы с bufferbloat netem не нужен и может запутать диагностику, если вы случайно оставите его включённым.

Пример стендовой эмуляции:

tc qdisc replace dev eth0 root netem delay 40ms 10ms loss 0.5%

После теста верните «боевую» qdisc (например, cake или fq_codel).

iproute2 и практические мелочи, которые экономят часы

Сбрасываем конфигурацию перед экспериментами

tc qdisc del dev eth0 root

tc qdisc del dev eth0 ingress

tc qdisc del dev ifb0 root

Команды del могут ругаться, если qdisc нет — это нормально. Важно начинать с чистого состояния.

Проверяем, что именно шейпится

Смотрите counters/drops/overlimits:

tc -s qdisc show dev eth0

tc -s qdisc show dev ifb0

Если вы включили ingress через ifb, а счётчики на ifb0 не растут — значит, фильтр mirred не сработал или трафик идёт не через тот интерфейс.

Offload’ы и «почему tc не даёт эффекта»

На некоторых виртуальных/физических NIC offload’ы и особенности vSwitch могут размывать эффект AQM. Иногда помогает отключение части offload’ов (осторожно: CPU может вырасти):

ethtool -k eth0

ethtool -K eth0 tso off gso off gro off

Если после этого задержка стабилизировалась — вы нашли фактор влияния. Но на VDS доступность и эффект зависит от виртуализации и настроек хоста.

Схема ingress shaping через ifb: перенаправление входящего трафика с eth0 в ifb0 и шейпинг qdisc

Рекомендации выбора для типовых сценариев на VDS

1) Нужен быстрый результат и минимум сущностей

Ставьте cake на egress. Если критичен входящий трафик (много входящих запросов и важна отзывчивость) — добавляйте ifb+cake на ingress.

2) Нужна классическая схема и прозрачная эксплуатация

Используйте HTB + fq_codel на egress, и такую же схему на ifb для ingress. Это более многословно, зато очень понятно по статистике и поведению.

3) Нужно просто улучшить fairness без shaping

Можно поставить fq или fq_codel без ограничения скорости. Это иногда помогает от ситуации «один поток съедает всё», но от bufferbloat в аплинке/у провайдера может не спасти.

Частые ошибки, из-за которых bufferbloat остаётся

  • Rate выставлен выше реального: очередь снова формируется не у вас.
  • Шейпится не тот интерфейс: проверьте через ip -br link, что трафик действительно идёт через выбранный dev.
  • Перепутан ingress/egress: egress «лечится» легко, ingress — через ifb или policing.
  • Упираетесь в CPU/диск: задержка растёт из-за нагрузки, а не из-за очередей.
  • Оставили netem после экспериментов и потом ищете «почему всё медленно».

Мини-чеклист: как настроить и проверить за 15 минут

  1. Определите интерфейс: ip -br link.

  2. Снимите текущие qdisc: tc -s qdisc show dev eth0.

  3. Поставьте cake на egress с rate на 1–5% ниже устойчивой скорости.

  4. Запустите нагрузку и параллельно наблюдайте RTT до ближайшей стабильной точки (например, шлюза).

  5. Если входящий трафик тоже создаёт spikes — включите ifb и поставьте cake (или HTB+fq_codel) на ifb0.

  6. Сверьте счётчики: tc -s qdisc show dev ifb0 должен «жить» под входящим трафиком.

Итог

Для большинства задач на VDS борьба с bufferbloat сводится к двум вещам: (1) корректный shaping чуть ниже реальной скорости, (2) современная qdisc, которая держит очередь короткой. fq_codel — крепкий универсальный вариант, cake — часто самый быстрый путь к ровной задержке, а fq — минимальное улучшение, когда shaping не нужен или ресурсы сильно ограничены.

Если вы регулярно видите latency spikes на фоне бэкапов, деплоев и скачиваний, настройка tc — один из самых дешёвых способов улучшить UX и стабильность сервисов без покупки «больше мегабит». А если вы как раз выбираете конфигурацию под сетевые задачи, посмотрите гайд по подбору тарифа: как выбрать VDS по CPU и RAM.

Поделиться статьей

Вам будет интересно

NFS в Linux: v3 и v4.1, async, rsize/wsize и mount options для максимального throughput OpenAI Статья написана AI (GPT 5)

NFS в Linux: v3 и v4.1, async, rsize/wsize и mount options для максимального throughput

Разбираем NFS в Linux на практике: чем v3 отличается от v4.1, как устроены locking и сессии, когда (не) включать async, и как подо ...
Nginx за Cloudflare: как вернуть реальный IP (realip и PROXY protocol) и не сломать безопасность OpenAI Статья написана AI (GPT 5)

Nginx за Cloudflare: как вернуть реальный IP (realip и PROXY protocol) и не сломать безопасность

Когда сайт работает за Cloudflare, Nginx в логах видит IP узлов Cloudflare вместо адреса клиента. В статье разберём realip через з ...
UFW и Docker в 2026: NAT, published ports и безопасный хост OpenAI Статья написана AI (GPT 5)

UFW и Docker в 2026: NAT, published ports и безопасный хост

Практическое руководство по UFW и Docker в 2026: как трафик на published ports уходит в NAT и FORWARD, что меняет iptables-nft/nft ...