Быстрая оптимизация Linux серверов под высокие нагрузки

Andrey Nikishaev
4 min readJun 3, 2023

1. Netfilter connection tracking

Если просто — это огромная хеш таблица которая хранит в себе инфу о стейте всех подключений в разрезе девайса(сервера). Это необходимо для разного рода фильтров, фаерволов и подобного.

В определенных случаях когда сервер защищен другим девайсом перед ним, и требует доп ресурсов этот трекинг можно отключить.

sudo modprobe -r nf_conntrack

echo “blacklist nf_conntrack” | sudo tee /etc/modprobe.d/nf_conntrack.conf

Зачем увеличивать net.netfilter.nf_conntrack_max?

Если все же отключить трекинг не вариант, но при этом сервер обрабатывает большое количество одновременных подключений то малое значение данной настройки может привести к невозможности создания новых подключний, что как вы понимаете не ок.

Не забываем что помимо увеличения данного параметра, нада так же увеличить саму хеш таблицу где храняться данные о подключениях:

echo num > /sys/module/nf_conntrack/parameters/hashsize

2. Файловые дескрипторы

Линукс аллоцирует определенное количество файловых хендлеров и система не даст вам открыть файлов больше чем кол-во этих хендлеров.

Данная настройка fs.file-max устанавливает максимальное их число. Но не стоит так же забывать и о настройках для каждого процесса с помощью ulimit.

Тут важно не забыть что в линукс все есть файл и сокеты в том числе, а посему это настройка влияет и на них.

3. Переиспользование подключение в состоянии TIME_WAIT

Когда соединение закрывается, есть опеделенное время которое проходит до закрытия, которое нужно что бы дождаться отстающие пакеты. В это время соединение находиться в состоянии TIME_WAIT. И если опция net.ipv4.tcp_tw_reuse не включена, то при большом количестве подключений, за счет этих таймаутов, есть большой шанс исчерпать все доступные подключения.

Но это не следует использовать для NAT, прокси или лоад-балансеров, так как может быть нарушен роутинг.

4. Ограничение сокетов в состоянии TIME_WAIT

Параметр net.ipv4.tcp_max_tw_buckets релулирует сколько сокетов может быть в данном стейте. В случае если лимит привышен, то система начинает активно закрывать сокеты в этом стейте и блокировать возможность открытия новых.

Сами понимаете при большом количестве соединений этот параметр не должен быть маленьким.

5. Порты для исходящих подключений.

Как вам может быть известно, в линукс кол-во портов ограничено значением 65 535. Настройка net.ipv4.ip_local_port_range устанавливает диапазон портов которые могут быть использованы для внешних соединений. Зачастую 32768–60999 что дает нам 28232 портов. Если же нам нужно больше то эту шкалу можно расширить.

Но помним что 0–1024 зарезервировано под системные сервисы.

6. Настройка swap системы

Swap используется для сброса части кеша с памяти на диск, что полезно когда памяти мало, но крайне не полезно когда ее много, так как диск куда медленнее.

Установка vm.swappiness = 0 заставит свапать кеш только в случае когда места в памяти физически не хватает.

7. Память для кернела системы

Система резервирует определенное количество памяти которое используется только кернелом. Низкий показатель может вызвать необходимость кернела конкурировать с процессами пользователей, как следствие система станет очень тормозной.

Настраивается параметром vm.min_free_kbytes

Помним что кернел активно участвует обработке соединений и прогоне трафика. При высоких сетевых нагрузках его лучше увеличить.

8. Беклог пакетов

Когда пакет приходит в система он записывается в очередь для последующей обработки. Но если пакеты приходят быстрее чем обрабатываются тогда очередь растет до установленного предела, после чего новые пакеты дропаются.

Параметр net.core.netdev_max_backlog устанавливает предел для данной очереди. Увеличение параметра нужно для того что бы в случае например спайковых нагрузок сервер мог, хоть и с задержкой, но обработать все пакеты без дропов.

9. Беклог SYN пакетов

Похоже на предыдущее но контролирует именно запросы на подключние.

И устанавливается параметром net.core.somaxconn

10. Ограничние памяти TCP стека

Глобальный лимит памяти TCP стека

Устанавливается параметром net.ipv4.tcp_mem и имеет 3 значение: низкий, под давлением и высокий. Данный параметр устанавливается в страницах кеша. Что бы глянуть сколько этов памяти юзайте getconf PAGE_SIZE (зачастую около 4кб).

До низкого значения память выделяеться на все по первому требованию. При значении под нагрузкой, система пытается регулировать память и стараться уменьшить потребление. Больше чем высокое значение система не может выделить памяти, и тут приходит наш приятель OOM Killer.

Лимит буферов для каждого сокета

Устанавливается параметрами net.ipv4.tcp_wmem и net.ipv4.tcp_rmem для записи и чтения соответсвенно. Так же имеет три значения: минимальный, стандартный и максимальный.

Стандартный — тот с которым создается сокет. Минимальный и максимальный — и так ясно.

Так же не забывает что есть еще и глобальный максимальный лимит на тоже самое. Параметры net.core.rmem_max и net.core.wmem_max

11. Контроль метрик подключения

Система по дефолту сохраняет метрики подключения к одному и тому же хосту.

При условии что у вас крайне много коротких подключений имеет смысл отключить данное поведение с помощью параметра net.ipv4.tcp_no_metrics_save

12. Алгоритм контроля перегрузки TCP.

Данный параметр net.ipv4.tcp_congestion_control устанавливает алгоритм который будет использован что бы отправитель не отправил данных больше чем сеть может обработать.

Разные алгоритмы могут подходить лучше под спечицические нагрузки.

Этут тему сам не тестил но ребята рекомендовали.

13. Настройка селективного подтверждения пакетов (SACK)

По дефолту подтверждение доставки идет последним пакетом. Но в случае если сеть не стабильна, такой вариант может привести к крайней нестабильности работы.

Зачастую такое бывает при вай-фай и подбных подключения которые могут подвергаться сильным физическим помехам.

Котнролируется параметрами net.ipv4.tcp_sack, net.ipv4.tcp_dsack,

net.ipv4.tcp_fack

Сам эту тему никогда не юзал, так как особо не было нужды.

Надеюсь было полезно. И помните — вся сила в man)

--

--