Эксплуатация нод

Тюнинг VPN-ноды: sysctl + RPS, минус 60–70% LoadAvg

RPS размазывает softirq по ядрам, BBR и большие буферы разгоняют канал. И главная грабля: BBR молча слетает в cubic, если модуль не закреплён.

9 мин чтения

Зачем трогать ядро

Дефолтные параметры ядра Linux рассчитаны на типовой web-сервер: мало коннектов, небольшие буферы. На VPN-ноде с 1000+ ESTABLISHED-соединений эти дефолты становятся горлом: softirq не успевает, TCP-буферы малы, очереди переполняются, CPU тратится впустую. Тюнинг ниже применялся на бюджетных 2-ядерных VPS и снижал LoadAvg на 58–69% без смены железа и без правки xray-конфигурации.

Корневые проблемы:

Шаг 1. RPS: размазать softirq по ядрам

Receive Packet Steering распределяет обработку входящих пакетов по нескольким CPU. Применимо, когда ядер больше одного, а у сетевухи одна RX-очередь:

# проверить: 0 = RPS не настроен
cat /sys/class/net/<iface>/queues/rx-0/rps_cpus
# маска битовая по числу ядер: 2 ядра → 3, 4 ядра → f
echo 3 > /sys/class/net/<iface>/queues/rx-0/rps_cpus
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
echo 32768 > /sys/class/net/<iface>/queues/rx-0/rps_flow_cnt

sysctl не умеет писать в /sys/class/net/*, поэтому за персистентность отвечает oneshot systemd-unit (RemainAfterExit=yes), который повторяет эти echo после network.target.

Шаг 2. Sysctl-профиль

/etc/sysctl.d/99-vpn-tuning.conf:

net.core.netdev_budget = 600
net.core.netdev_budget_usecs = 8000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_fastopen = 3
net.netfilter.nf_conntrack_max = 524288
net.core.somaxconn = 8192
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15

Замеры на 2-ядерном VPS: LoadAvg за минуту упал с 3.80 до 1.16 (−69%), rmem_max вырос в 80 раз, нагрузка ksoftirqd распределилась между ядрами.

Кроме буферов и BBR профиль закрывает лимиты, в которые прокси упирается раньше, чем в CPU: conntrack (таблица netfilter переполняется на всплеске — в разобранной утечке рост с 12k до 37k записей, дальше новые соединения отбрасываются), backlog очереди и nofile — лимит файловых дескрипторов процесса задаётся отдельно через LimitNOFILE в unit-файле; референс здорового потолка — порядка миллиона на процесс. Упор в любой из этих лимитов снаружи выглядит как «медленная сеть».

BBR молча слетает в cubic

Самая коварная деталь всего тюнинга. В конфигурации явно прописан tcp_congestion_control = bbr, а рантайм показывает cubic:

sysctl -n net.ipv4.tcp_congestion_control net.core.default_qdisc

Причина — порядок инициализации при загрузке. Если модуль tcp_bbr не добавлен в /etc/modules-load.d/, то при буте systemd-sysctl применяет настройки раньше, чем модуль подгрузится. Запись значения bbr молча проваливается — алгоритм ещё не зарегистрирован в ядре — и сервер остаётся на cubic. На части серверов модуль встаёт вовремя, поэтому дефект выборочный и легко теряется среди «здоровых» соседей.

Фикс:

modprobe tcp_bbr
echo tcp_bbr > /etc/modules-load.d/bbr.conf
sysctl --system

Разница cubic против bbr — кратная просадка пропускной на канале с потерями и большим RTT, то есть у типичного мобильного клиента. Синтетика внутри дата-центра этого может не показать: магистраль чистая. Проверяйте рантайм на каждом сервере парка, а не только на «жалобном».

Подводные камни

Вывод. RPS плюс расширенные TCP-буферы плюс BBR/fq снимают львиную долю паразитной softirq-нагрузки и режут LoadAvg вдвое без апгрейда железа. Но тюнинг ядра не лечит overcommit хостера (steal) и не спасает, если tcp_bbr не закреплён в modules-load.d и слетает после обновления ядра. «Настройка записана в конфигурацию» не равно «настройка применилась» — проверяйте фактический рантайм.

Как подключиться за 2 минуты
Частые вопросы

Частые вопросы

Насколько снижает LoadAvg тюнинг sysctl и RPS на VPN-ноде?
Тюнинг применялся на бюджетных 2-ядерных VPS и снижал LoadAvg на 58–69% без смены железа и без правки xray-конфигурации; в одном замере LoadAvg упал с 3.80 до 1.16.
Что делает RPS и когда его стоит настраивать?
Receive Packet Steering распределяет обработку входящих пакетов по нескольким CPU. Он применим, когда ядер больше одного, а у сетевухи одна RX-очередь — типичная ситуация на бюджетных VPS, где ksoftirqd забит на 100% при свободных остальных ядрах.
Почему BBR может не работать, даже если прописан в sysctl.conf?
Если модуль tcp_bbr не добавлен в /etc/modules-load.d/, то при загрузке systemd-sysctl применяет настройки раньше, чем модуль подгрузится — запись bbr молча проваливается, и сервер остаётся на cubic. Дефект выборочный: на части серверов модуль встаёт вовремя.
Как проверить, что congestion control реально работает как BBR, а не cubic?
Проверка делается командой sysctl -n net.ipv4.tcp_congestion_control net.core.default_qdisc — конфигурация может это показывать, но рантайм нужно проверять отдельно на каждом сервере парка.
Можно ли тюнингом sysctl решить проблему steal time от хостера?
Нет, steal time — это overcommit виртуалки у хостера, когда соседи воруют CPU. Тюнингом ядра это не лечится, решается только сменой тарифа или хостера.
Похожее

Ещё в базе знаний

Подключите рабочий VPN

Инструкции базы знаний написаны под ключи VPN PRO: ключ выдаёт Telegram-бот за минуту, работоспособность гарантируем. Промокод VPN10 — 10 дней бесплатно, без карты.

Промокод VPN10 — 10 дней бесплатно · до 31 августа · передавайте друзьям