В распределённой системе при передаче больших файлов по TCP наблюдается низкий throughput при малых пингах между узлами; перечислите возможные причины в уровнях TCP/IP, настройках ОС и приложении (например, окно TCP, Nagle, MTU, копирования, блокировки), опишите методику по шагам для диагностики (tcpdump, ss, iperf, профайлинг) и приведите рекомендации по оптимизации и тестированию
Возможные причины (по слоям) - TCP/IP - Малое передаваемое окно / отсутствие window scaling: TCP не может заполнить канал из‑за малого cwnd/rcv_wnd; BDP = bandwidth × RTT, т.е. нужно окно ≈ BDP. Пример: BDP=10 Gb/s×1 ms=125 kB \text{BDP} = 10\ \text{Gb/s} \times 1\ \text{ms} = 125\ \text{kB}BDP=10Gb/s×1ms=125kB. - Неправильный MSS/MTU / PMTU blackhole: фрагментация или уменьшение MSS ограничивает полезную нагрузку; MTU 150015001500 vs jumbo frames. - Потери/переотправки и дубли ACK: даже небольшая потери сильно падают throughput. - Отсутствие SACK или слабый алгоритм контроля перегрузки (old Reno вместо CUBIC/BBR). - Nagle/Delayed ACK взаимодействие: много маленьких записей замедляют передачу. - ОС/сервер/сеть - Малые буферы сокета (net.core.wmem_max/net.core.rmem_max, tcp_*_wmem). - Offloads (GSO/GRO/LRO, checksum offload) неправильно работают или отключены. - Интеррупт коалесценция, балансировка IRQ, микропакеты/слепление (NIC ring size). - Ошибки NIC (drops, bad CRC) или перегрузка CPU/шины. - Ограничения в switch (flow control, rate limiting, bad firmware). - Приложение - Маленькие write() размеры, синхронный fsync, одно-поточное чтение/запись. - Много копирований (user→kernel→network) вместо zero-copy (sendfile/splice). - Блокировки/синхронизация в коде, шедулинг, криптография в CPU. - Использование TCP_NODELAY/или его отсутствие неправильным образом. Методика диагностики (шаги) - Быстрые измерения канала - Измерьте RTT: ping host (или hping3) — если RTT очень мал, узкий профиль всё равно может быть из‑за BDP. - Протестируйте пропускную способность линка: iperf3 -c server (single stream) и iperf3 -c server -P NNN (много потоков) — сравните. - Просмотр состояний TCP/сокетов - ss -tin и ss -s: смотреть rtt, cwnd, rto, rcv_space, retrans. - netstat -s / proc/net/snmp для общих счетчиков. - Сбор пакетов и анализ - tcpdump -i iface host A and host B -s 0 -w trace.pcap; открыть в Wireshark: смотреть MSS, window scale, SACK, duplicate ACK, retransmissions, RTT per segment, сегментацию. - Использовать tshark для автоматизации поиска retransmissions/zero window: tshark -Y "tcp.analysis.retransmission". - Проверка MTU/PMTU - tracepath / iperf3 --set-mss / ping -M do -s чтобы выявить PMTU блоки. - Проверка NIC/драйвера - ethtool -S iface, ethtool -k iface (offloads), ethtool -c iface (coalesce), dmesg на ошибки, /proc/interrupts на распределение IRQ. - Нагрузочное профилирование сервера/приложения - top/htop для CPU, perf top/record, flamegraphs, strace/ltrace на системные вызовы. - Проверить копирования: use sendfile/splice vs read/write; проверить memcpy в профайлере. - Контрольные тесты - Отключать и включать фичи: disable/enable GSO/GRO, toggle TCP_NODELAY, поменять congestion control (cubic→bbr), менять rmem/wmem и смотреть эффект. - Измерять throughput и CPU при каждом изменении. - Автоматизация диагностики - Скрипты для iperf3/tcpdump/ss + парсинг результатов; bpftrace для real‑time метрик. Конкретные команды/проверки (коротко) - ss -ti dst:port - tcpdump -i iface -s 0 -w /tmp/cap.pcap host A and host B - iperf3 -c server -P 1 (single) и -P 8 (parallel) - ethtool -k iface; ethtool -S iface; ethtool -c iface - cat /proc/net/tcp ; sysctl -a | grep tcp - perf top / flamegraph; strace -c ./app Рекомендации по оптимизации - Подогнать размеры окон под BDP - Включить window scaling: sysctl net.ipv4.tcp_window_scaling=1. - Увеличить буфера: sysctl net.core.rmem_max=167772161677721616777216, net.core.wmem_max=167772161677721616777216, net.ipv4.tcp_rmem="409640964096873808738087380167772161677721616777216", net.ipv4.tcp_wmem="409640964096655366553665536167772161677721616777216" (пример). - Конгестия/алгоритмы - Попробовать congestion control BBR для высоких BW*RTT: sysctl net.ipv4.tcp_congestion_control=bbr (предварительно доступность модуля). - Nagle / Delayed ACK - Если приложение пишет много мелких пакетов — отключить Nagle (setsockopt TCP_NODELAY). - Проверить и при необходимости настроить delayed ACK на стороне получателя. - MTU / MSS - При возможности включить jumbo frames (MTU 900090009000) на обоих концах и на промежуточных коммутаторах. - Включить tcp_mtu_probing=1 при подозрении PMTU blackhole. - NIC/OS tuning - Включить/отключить GSO/GRO/LRO тестово; увеличить NIC ring buffers и настроить interrupt coalescing; включить IRQ affinity. - Включить checksum offload, segmentation offload если поддерживается и корректно работает. - Приложение - Использовать крупные write() буферы, batching, async I/O, multithreading или multiple connections если одно TCP не заполняет канал. - Использовать zero‑copy (sendfile/splice, splice+tee) для файловых передач. - Минимизировать синхронные fsync и блокировки в hot‑path. - Тестирование и валидация - Повторять iperf3: single stream vs multi stream, с изменёнными параметрами offload/Nagle/MSS. - Проверять CPU utilization и пер‑interface counters (drops/errors). - Запускать A/B тесты с включёнными/выключенными изменениями и собирать tcpdump для подтверждения уменьшения retransmissions и увеличения cwnd. Краткая последовательность действий для практического дебага - Измерить базовый RTT/line rate: ping, iperf3 single. - Захватить tcpdump при воспроизведении проблемы, проанализировать MSS, window scale, retrans. - Посмотреть ss для cwnd/rcv_space и ethtool для NIC. - Попробовать изменения: увеличить wmem/rmem, включить window scaling, сменить CC на bbr, отключить Nagle — измерять. - Если CPU‑bound — профилировать приложение, применить zero‑copy или распараллеливание. - Документировать результаты и откатывать некорректные изменения. Если нужно, могу дать конкретный чеклист команд и набор sysctl значений под ваш профиль (RTT, link speed, OS), укажите: скорость канала и RTT.
- TCP/IP
- Малое передаваемое окно / отсутствие window scaling: TCP не может заполнить канал из‑за малого cwnd/rcv_wnd; BDP = bandwidth × RTT, т.е. нужно окно ≈ BDP. Пример: BDP=10 Gb/s×1 ms=125 kB \text{BDP} = 10\ \text{Gb/s} \times 1\ \text{ms} = 125\ \text{kB}BDP=10 Gb/s×1 ms=125 kB.
- Неправильный MSS/MTU / PMTU blackhole: фрагментация или уменьшение MSS ограничивает полезную нагрузку; MTU 150015001500 vs jumbo frames.
- Потери/переотправки и дубли ACK: даже небольшая потери сильно падают throughput.
- Отсутствие SACK или слабый алгоритм контроля перегрузки (old Reno вместо CUBIC/BBR).
- Nagle/Delayed ACK взаимодействие: много маленьких записей замедляют передачу.
- ОС/сервер/сеть
- Малые буферы сокета (net.core.wmem_max/net.core.rmem_max, tcp_*_wmem).
- Offloads (GSO/GRO/LRO, checksum offload) неправильно работают или отключены.
- Интеррупт коалесценция, балансировка IRQ, микропакеты/слепление (NIC ring size).
- Ошибки NIC (drops, bad CRC) или перегрузка CPU/шины.
- Ограничения в switch (flow control, rate limiting, bad firmware).
- Приложение
- Маленькие write() размеры, синхронный fsync, одно-поточное чтение/запись.
- Много копирований (user→kernel→network) вместо zero-copy (sendfile/splice).
- Блокировки/синхронизация в коде, шедулинг, криптография в CPU.
- Использование TCP_NODELAY/или его отсутствие неправильным образом.
Методика диагностики (шаги)
- Быстрые измерения канала
- Измерьте RTT: ping host (или hping3) — если RTT очень мал, узкий профиль всё равно может быть из‑за BDP.
- Протестируйте пропускную способность линка: iperf3 -c server (single stream) и iperf3 -c server -P NNN (много потоков) — сравните.
- Просмотр состояний TCP/сокетов
- ss -tin и ss -s: смотреть rtt, cwnd, rto, rcv_space, retrans.
- netstat -s / proc/net/snmp для общих счетчиков.
- Сбор пакетов и анализ
- tcpdump -i iface host A and host B -s 0 -w trace.pcap; открыть в Wireshark: смотреть MSS, window scale, SACK, duplicate ACK, retransmissions, RTT per segment, сегментацию.
- Использовать tshark для автоматизации поиска retransmissions/zero window: tshark -Y "tcp.analysis.retransmission".
- Проверка MTU/PMTU
- tracepath / iperf3 --set-mss / ping -M do -s чтобы выявить PMTU блоки.
- Проверка NIC/драйвера
- ethtool -S iface, ethtool -k iface (offloads), ethtool -c iface (coalesce), dmesg на ошибки, /proc/interrupts на распределение IRQ.
- Нагрузочное профилирование сервера/приложения
- top/htop для CPU, perf top/record, flamegraphs, strace/ltrace на системные вызовы.
- Проверить копирования: use sendfile/splice vs read/write; проверить memcpy в профайлере.
- Контрольные тесты
- Отключать и включать фичи: disable/enable GSO/GRO, toggle TCP_NODELAY, поменять congestion control (cubic→bbr), менять rmem/wmem и смотреть эффект.
- Измерять throughput и CPU при каждом изменении.
- Автоматизация диагностики
- Скрипты для iperf3/tcpdump/ss + парсинг результатов; bpftrace для real‑time метрик.
Конкретные команды/проверки (коротко)
- ss -ti dst:port
- tcpdump -i iface -s 0 -w /tmp/cap.pcap host A and host B
- iperf3 -c server -P 1 (single) и -P 8 (parallel)
- ethtool -k iface; ethtool -S iface; ethtool -c iface
- cat /proc/net/tcp ; sysctl -a | grep tcp
- perf top / flamegraph; strace -c ./app
Рекомендации по оптимизации
- Подогнать размеры окон под BDP
- Включить window scaling: sysctl net.ipv4.tcp_window_scaling=1.
- Увеличить буфера: sysctl net.core.rmem_max=167772161677721616777216, net.core.wmem_max=167772161677721616777216, net.ipv4.tcp_rmem="409640964096 873808738087380 167772161677721616777216", net.ipv4.tcp_wmem="409640964096 655366553665536 167772161677721616777216" (пример).
- Конгестия/алгоритмы
- Попробовать congestion control BBR для высоких BW*RTT: sysctl net.ipv4.tcp_congestion_control=bbr (предварительно доступность модуля).
- Nagle / Delayed ACK
- Если приложение пишет много мелких пакетов — отключить Nagle (setsockopt TCP_NODELAY).
- Проверить и при необходимости настроить delayed ACK на стороне получателя.
- MTU / MSS
- При возможности включить jumbo frames (MTU 900090009000) на обоих концах и на промежуточных коммутаторах.
- Включить tcp_mtu_probing=1 при подозрении PMTU blackhole.
- NIC/OS tuning
- Включить/отключить GSO/GRO/LRO тестово; увеличить NIC ring buffers и настроить interrupt coalescing; включить IRQ affinity.
- Включить checksum offload, segmentation offload если поддерживается и корректно работает.
- Приложение
- Использовать крупные write() буферы, batching, async I/O, multithreading или multiple connections если одно TCP не заполняет канал.
- Использовать zero‑copy (sendfile/splice, splice+tee) для файловых передач.
- Минимизировать синхронные fsync и блокировки в hot‑path.
- Тестирование и валидация
- Повторять iperf3: single stream vs multi stream, с изменёнными параметрами offload/Nagle/MSS.
- Проверять CPU utilization и пер‑interface counters (drops/errors).
- Запускать A/B тесты с включёнными/выключенными изменениями и собирать tcpdump для подтверждения уменьшения retransmissions и увеличения cwnd.
Краткая последовательность действий для практического дебага
- Измерить базовый RTT/line rate: ping, iperf3 single.
- Захватить tcpdump при воспроизведении проблемы, проанализировать MSS, window scale, retrans.
- Посмотреть ss для cwnd/rcv_space и ethtool для NIC.
- Попробовать изменения: увеличить wmem/rmem, включить window scaling, сменить CC на bbr, отключить Nagle — измерять.
- Если CPU‑bound — профилировать приложение, применить zero‑copy или распараллеливание.
- Документировать результаты и откатывать некорректные изменения.
Если нужно, могу дать конкретный чеклист команд и набор sysctl значений под ваш профиль (RTT, link speed, OS), укажите: скорость канала и RTT.