TCP: Out of socket memory — Решение нехватки памяти сетевого стека Linux
Архитектура ошибки и симптомы сбоя
Критический сбой «TCP: Out of socket memory» генерируется сетевой подсистемой ядра Linux. Ошибка означает, что суммарный объем физической оперативной памяти, выделенной под буферы приема и передачи всех активных TCP-сокетов, превысил жесткий лимит (hard limit), заданный параметром net.ipv4.tcp_mem. В результате ядро блокирует открытие новых TCP-сокетов, перестает расширять окна TCP Window и начинает принудительно сбрасывать входящие пакеты.
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| tcp_mem | min, pressure, max (pages) | Глобальные лимиты памяти сетевого стека TCP в системных страницах (по 4KB). |
| Pressure Mode | Memory State Flag | Состояние давления на память: ядро принудительно урезает размеры окон TCP Window. |
| Hard Limit (max) | Socket Drop Threshold | Критический порог: немедленный отказ в выделении памяти сокетам. |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Проверка текущей утилизации страниц сетевой памяти
# Просмотр текущего распределения памяти сокетов:
cat /proc/net/sockstat
# Просмотр системных лимитов tcp_mem (в страницах по 4KB):
cat /proc/sys/net/ipv4/tcp_memВ выводе sockstat обратите внимание на параметр TCP: inuse ... mem <PAGES>. Если значение mem приближается к третьему числу из tcp_mem, наступило исчерпание памяти.
Сценарий 2: Корректировка глобальных лимитов tcp_mem в sysctl
Увеличьте параметры tcp_mem пропорционально установленной RAM (пример для серверов с 32–64GB RAM):
# Внесите настройки в /etc/sysctl.d/99-tcp-memory.conf:
cat <<EOF | sudo tee /etc/sysctl.d/99-tcp-memory.conf
# Лимиты tcp_mem: min (1GB), pressure (2GB), max (4GB) в страницах 4KB:
net.ipv4.tcp_mem = 262144 524288 1048576
# Буферы приема и отправки по умолчанию и максимум (в байтах):
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
EOF
sudo sysctl -p /etc/sysctl.d/99-tcp-memory.confСценарий 3: Поиск утечек сокетов в пользовательских процессах
Проверьте, какие приложения удерживают сотни тысяч незакрытых сокетов (Socket Leak):
# Подсчет сокетов по процессам:
sudo ss -tap | awk '{print $6}' | cut -d',' -f1 | sort | uniq -c | sort -nr | head -n 10ITSTM проведет профилирование распределения памяти ядра (Slabtop / Kmemleak), устранит утечки дескрипторов и оптимизирует сетевой стек под Highload.
Частые вопросы (FAQ)
В каких единицах измеряются значения в net.ipv4.tcp_mem?
В отличие от параметров rmem и wmem, которые задаются в байтах, параметр net.ipv4.tcp_mem задается строго в системных страницах памяти (Architecture Pagesize). В архитектуре x86_64 одна страница равна 4096 байт (4 КБ).
Почему нельзя просто выставить бесконечно большие значения tcp_mem?
Сетевые буферы выделяются из физической невыгружаемой памяти ядра (Low Memory). Чрезмерно завышенный лимит tcp_mem при атаке или утечке приведет к полному исчерпанию RAM и падению всей операционной системы через Kernel Panic (OOM).
Что означает состояние TCP Pressure?
Когда потребление памяти сокетами превышает второе значение (pressure) из tcp_mem, ядро активирует режим подавления: перестает автоматически увеличивать окна TCP (Window Scaling) и заставляет приложения быстрее вычитывать буферы.
Как влияет параметр tcp_moderate_rcvbuf на расход памяти?
При значении 1 (включено по умолчанию) ядро выполняет автотюнинг буфера приема сокета. При возникновении нехватки памяти ядро автоматически сжимает буферы сокетов для экономии ОЗУ.