awesome-everything EN
↑ Обратно к восхождению

Сети и протоколы

Управление потоком и перегрузкой

Суть Скользящие окна позволяют получателю управлять темпом отправителя; slow start и CUBIC позволяют TCP обнаружить пропускную способность сети, не перегружая её.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 16 min

Свежее TCP-соединение между Лондоном и Сиднеем не знает, насколько быстра линия. Оно начинает осторожно, удваивая скорость отправки каждый round-trip, пока не достигнет предела — затем отступает и пробует снова. Этот танец между отправителем и сетью позволяет TCP заполнить 10-гигабитный канал или вежливо разделить мегабитный.

Скользящее окно и управление потоком

После установки соединения каждый TCP-сегмент несёт размер окна — количество байтов, которые получатель готов принять сверх последнего подтверждённого байта. Отправитель поддерживает скользящее окно неподтверждённых байт в пути, ограниченное минимумом из рекламируемого окна получателя и собственного окна перегрузки. По мере прихода ACK окно скользит вперёд, позволяя отправлять новые байты. Если приложение получателя медленно опустошает буфер сокета, окно уменьшается; при полном заполнении буфера получатель рекламирует window=0 и отправитель делает паузу. Это сквозное управление потоком: получатель диктует темп, отправитель подчиняется.

MSS, масштабирование окна и SACK

Три опции, согласуемые при обмене SYN/SYN-ACK, существенно влияют на пропускную способность:

Maximum Segment Size (MSS): максимальный TCP-payload, который стек может обработать без IP-фрагментации. Типично: 1460 байт на Ethernet (MTU 1500 минус 20 IP + 20 TCP заголовки), 1220 байт на туннельных сетях.

Window Scaling (RFC 7323): 16-битное поле окна умножается на 2^scale, допуская окна до 1 ГиБ. Без этого ограничение 64 КиБ на линке 100 мс RTT ограничивает пропускную способность примерно 5 Мбит/с независимо от реальной скорости линка (bandwidth-delay product = 64 КиБ / 0,1 с ≈ 640 КиБ/с). Необходимо для высокополосных путей с большой задержкой.

Selective Acknowledgements (SACK, RFC 2018): получатель перечисляет точные диапазоны байт, полученных за пропуском, чтобы отправитель повторно передал только недостающие части, а не всё после пробела. На потерянном пути с большим RTT SACK может удвоить эффективную пропускную способность.

Окно и числа пропускной способности
MSS на Ethernet
1460 байт (MTU 1500)
Максимум 16-битного окна
64 КиБ (без масштабирования)
Максимум с масштабированием
1 ГиБ (2^30)
Начальное окно Linux (IW)
10 MSS (~14,6 КБ)
Bandwidth × RTT (BDP)
100 Мбит/с × 100 мс = 1,25 МБ
BDP — минимальное нужное окно
чтобы заполнить путь с большим BDP

Математика таймера повторной передачи (RFC 6298)

Если сегмент не подтверждён в течение retransmission timeout (RTO), отправитель пересылает его. RFC 6298 задаёт:

SRTT ← (1 − 1/8)·SRTT + (1/8)·new_RTT
RTTVAR ← (1 − 1/4)·RTTVAR + (1/4)·|SRTT − new_RTT|
RTO = SRTT + max(G, 4·RTTVAR)

SRTT — сглаженный RTT, RTTVAR — дисперсия RTT (экспоненциально взвешенные скользящие средние). Первый RTO по умолчанию 1 с; после таймаута удваивается (экспоненциальный откат) до прихода сегмента или разрыва соединения. Алгоритм Карна запрещает измерять RTT по повторно переданным сегментам, так как ответный ACK неоднозначен.

Современный Linux использует RACK-TLP (RFC 8985) для более быстрого обнаружения потерь: RACK объявляет сегмент потерянным, когда позже отправленный сегмент подтверждён и истёк интервал переупорядочивания — без ожидания таймера RTO. TLP (Tail Loss Probe) повторно отправляет последний неподтверждённый сегмент через один RTT после последней отправки, чтобы избежать зависания на последнем пакете отправки.

Викторина

Что означает рекламируемое окно получателя в заголовке TCP?

Slow start и congestion avoidance

Свежее соединение не знает, насколько быстра сеть. Slow start открывает congestion window экспоненциально (1, 2, 4, 8, … MSS за RTT) до тех пор, пока не произойдёт потеря или не достигнет slow-start threshold (ssthresh). После этого congestion avoidance увеличивает окно линейно (~1 MSS за RTT для Reno/CUBIC).

При потере алгоритм зависит от варианта:

  • Reno: уменьшает окно вдвое, затем линейное увеличение.
  • CUBIC (Linux по умолчанию с 2.6.19): уменьшает менее агрессивно, затем зондирует с кубической кривой — быстрее восстанавливает пропускную способность на путях с большим BDP.
  • BBR: полностью игнорирует потери как сигнал перегрузки; использует RTT + измерения доставленных байт (разбирается в уроке о BBR).
Расставь шаги по порядку

Упорядочьте рост congestion window отправителя в TCP slow start:

  1. 1 Начало: cwnd = 10 MSS (IW по умолчанию в Linux)
  2. 2 После 1 RTT и ACK: cwnd удваивается до 20 MSS
  3. 3 После 2 RTT: cwnd удваивается до 40 MSS
  4. 4 Экспоненциальный рост продолжается до ssthresh или потери
  5. 5 При достижении ssthresh: переход в congestion avoidance (линейный +1 MSS/RTT)
  6. 6 При потере пакета: уменьшить cwnd согласно варианту управления перегрузкой
Викторина

Почему для повторных передач используется экспоненциальный откат, а не постоянный таймер?

Проследи
1/3

Проследите эпизод восстановления SACK после потери одного пакета в окне из 10 сегментов.

1
Step 1 of 3
Отправлены сегменты 1–10. Сегмент 5 потерян. Сегменты 6–10 пришли. Что сообщает получатель?
2
Locked
Без SACK что пришлось бы повторно передавать отправителю?
3
Locked
Почему это важно на пути с RTT 200 мс?
Почему это работает

Почему slow start начинается быстро. Название вводит в заблуждение: Linux 3.0+ (RFC 6928) устанавливает начальное congestion window (IW) равным 10 MSS (~14,6 КБ), а не 1 MSS. Это означает, что первый всплеск данных уже составляет 10 сегментов, выбранных под типичный размер HTTP-ответа на небольшой API-запрос. Slow start выглядит медленным только в сравнении с конечной пропускной способностью; по сравнению с классическим IW=1 это 10-кратное улучшение для первого RTT.

Вспомните перед уходом
  1. 01
    Как Window Scaling (RFC 7323) влияет на достижимую пропускную способность на пути RTT 100 мс, 1 Гбит/с?
  2. 02
    Что такое RACK-TLP и почему это улучшение относительно классического обнаружения потерь на основе RTO?
  3. 03
    Почему соединение с высокими случайными потерями работает плохо с CUBIC, но не с BBR?
Итог

Управление потоком TCP использует скользящее окно: получатель рекламирует, сколько байт он может принять, отправитель никогда не превышает это значение. Три опции из SYN/SYN-ACK резко влияют на пропускную способность: MSS (размер сегмента), Window Scaling (расширяет 64 КиБ до 1 ГиБ окна) и SACK (точно определяет недостающие диапазоны, чтобы повторно передавались только потерянные сегменты). Управление перегрузкой начинает свежие соединения в slow start (экспоненциальный рост окна), затем переходит в congestion avoidance (линейный рост) после достижения ssthresh. CUBIC, стандартный с 2006 года, использует кубическую кривую восстановления после потерь. Таймер повторной передачи вычисляется из сглаженного RTT (RFC 6298) с экспоненциальным откатом. RACK-TLP, стандартный с Linux 5.x, обнаруживает потери быстрее, наблюдая за порядком ACK, а не ожидая срабатывания таймера.

Связанные уроки
встречается в162
Продолжить восхождение ↑Опции TCP и типичные патологии
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources5
expand
  1. 01
  2. 02
  3. 03
  4. 04
  5. 05

Trademarks belong to their respective owners. Editorial reference only.