한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Анатомия игровых лагов › Первопричины повторных передач TCP

Медленное восстановление потерь в thin stream Thin streams fall back to RTO

ID причины rt-thin · Основной ответственный Команда разработки · Разработка сервера · Совместно Команда инфраструктуры · Серверная инфраструктура, Команда разработки · Разработка клиента

Открыть карточку в основной версии с иллюстрациями и экспериментами →

Когда мелкие пакеты отправляются редко, как в играх, RTO наступает раньше, чем соберутся «3 следующих пакета». От тех же потерь поток стоит намного дольше, чем при больших передачах.

Почему Интервал между пакетами около 100 ms, поэтому неподтверждённых пакетов (in-flight) всего несколько → Следствие Чтобы собрались 3 дублирующих ACK, нужно больше 300 ms, поэтому раньше срабатывает RTO (пинг + 200 ms), при серии потерь он удваивается → На экране От одной потери фриз около 0,3 с, если потеряна и повторная передача, фриз почти на 1 с, потом перемотка

Симптомы
Фриз, Перемотка
Факторы
Потери, Остановка
У кого
Только у меня, Весь сервер
Когда
Изредка, случайно
Ответственные
Основной ответственный Команда разработки · Разработка сервера · Совместно Команда инфраструктуры · Серверная инфраструктура, Команда разработки · Разработка клиента
Команда разработки: задачи
Сервер: включить TCP_NODELAY (при включённом Nagle у RACK нет следующих пакетов, по которым он принимает решение), пакеты реального времени отправлять по UDP со своей схемой повторных передач. Клиент: включить TCP_NODELAY, пакеты реального времени отправлять так же, как сервер (UDP).
Команда инфраструктуры: задачи
Использовать RACK-TLP (по умолчанию в современных Linux), через tcp_thin_linear_timeouts не давать RTO удваиваться при серии таймаутов.
Цифры для ориентира
При интервале пакетов 100 ms и пинге 60 ms до быстрой повторной передачи около 360 ms (пока не придут 3 следующих пакета и не вернётся их подтверждение), а RTO около 260 ms. С RACK пакет отправляется повторно, как только возвращается подтверждение следующего пакета, примерно через 160 ms. Если интервал пакетов больше 200 ms, RACK тоже не быстрее RTO.
На графике
Провал, затем пачка · объём приёма по соединениям, число истечений RTO
Где смотреть
Сравнить прирост TcpExtTCPTimeouts (истечения RTO), TcpExtTCPFastRetrans (быстрые повторные передачи), TcpExtTCPLossProbes и TcpExtTCPLossProbeRecovery (TLP) в nstat и посмотреть rto и backoff игровых соединений в ss -ti. Также проверить значения net.ipv4.tcp_recovery, tcp_early_retrans и tcp_sack на сервере
Подтверждает
Среди повторных передач истечений RTO больше, чем быстрых повторных передач, и у игровых соединений часто backoff больше 0 (соединение переживает RTO). Во время фриза принятый объём равен 0, а после восстановления всё приходит разом
Опровергает
Если большие передачи на том же сервере стоят так же долго, проблема в самих потерях и от формы соединения не зависит. Если проблема сосредоточена на соединениях без SACK и временных меток, это «Удаление опций TCP промежуточным оборудованием»
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)
Подробнее
Раньше в Linux была и опция повторной передачи по одному дублирующему ACK для thin stream (tcp_thin_dupack), но в 2017 году её удалили, и теперь эту роль выполняет RACK. Если Nagle включён (TCP_NODELAY выключен), то, пока отправитель ждёт подтверждения потерянного пакета, новые пакеты тоже не уходят. У RACK не остаётся следующих пакетов для решения, и соединение ждёт RTO.

Источники

  1. Thin-streams and TCP Linux kernel
    У thin stream (редкие потоки вроде игровых) быстрая повторная передача работает плохо, и восстановление зависит от длинного таймаута; критерий: меньше 4 неподтверждённых пакетов (in-flight)
  2. RFC 5681: TCP Congestion Control IETF
    Быстрая повторная передача по третьему дублирующему ACK
  3. RFC 8985: The RACK-TLP Loss Detection Algorithm for TCP IETF
    RACK определяет потерю по тому, что дошёл пакет, отправленный позже; ожидание TLP равно 2·SRTT (если неподтверждённый пакет один, добавляется запас на отложенный ACK)
  4. include/net/tcp.h Linux kernel
    TCP_RTO_MIN 200 ms, критерий thin stream (меньше 4 пакетов in-flight) и 6 линейных повторов
  5. tcp: remove thin_dupack feature Linux kernel
    В январе 2017 года thin_dupack удалён (Linux 4.11), с пояснением, что его роль выполняет RACK
  6. IP Sysctl Linux kernel
    tcp_thin_linear_timeouts: для thin stream до 6 раз RTO не удваивается (по умолчанию выключено)
  7. tcp(7) — Linux manual page Linux man-pages
    TCP_NODELAY отключает алгоритм Нейгла
  8. net/ipv4/proc.c Linux kernel
    Названия счётчиков в выводе nstat: TCPTimeouts, TCPFastRetrans, TCPLossProbes, TCPLossProbeRecovery
  9. net/ipv4/tcp_timer.c Linux kernel
    TCPTimeouts растёт при истечении таймера повторной передачи (RTO)
  10. SNMP counter Linux kernel
    TcpExtTCPFastRetrans (повторные передачи вне состояния Loss), TcpExtTCPLossProbes (отправлен TLP), TcpExtTCPLossProbeRecovery (потеря восстановлена через TLP)
  11. ss(8) — Linux manual page iproute2
    rto (ms) и backoff (сколько раз удвоился RTO) в ss -i

Смотрите также

Тот же слой: Первопричины повторных передач TCP

Причины с тем же симптомом (Фриз) на других слоях

Карточка в основной версии с иллюстрациями и экспериментами