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

ゲームラグ白書 › TCP再送の根本原因

RTOの設定が環境に合っていない RTO min too low or too high

原因ID rt-rto-setting · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発

図と実験のあるメインページでこのカードを開く →

RTOの最小値を下げすぎると少し遅れただけで不要な再送が起き、デフォルト値(200ms)はゲームにとっては長すぎて、1回失うたびに長く止まります。

なぜ データセンター向けにRTOの最小値を大きく下げた、またはインターネット区間でデフォルト値のまま使用 → すると 低いと瞬間的な遅延でも再送が殺到、高いとパケットロスのたびに長く待つ → 画面では デフォルト値ならパケットロス1回で数百ms止まった後に早送り、下げすぎると止まる時間は減るが不要な再送が急増して回線を浪費

症状
フリーズ, 早送り, 入力遅延
要因
遅延
誰に起きるか
サーバー全体
いつ
常に
担当
主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応
Linux 6.15以降なら、ゲームの接続にTCP_RTO_MAX_MSでRTOの上限を下げることを検討(あきらめるまでの時間も短くなるため、TCP_USER_TIMEOUTで切断と判定する時間も一緒に決める)、サーバー間の内部接続だけソケットオプションTCP_RTO_MIN_US(6.15以降)でRTOの最小値を下げる、ソケットオプションTCP_THIN_LINEAR_TIMEOUTSでゲームの接続だけ連続したRTOが2倍に延びないようにすることを検討。
インフラチームの対応
サーバー間の内部接続だけ経路ごとにrto_minを下げる、インターネット区間はデフォルト値を維持しつつRACK-TLP・thin streamの設定(tcp_thin_linear_timeouts)で補う。
数値の目安
LinuxのRTO = 往復時間 + max(200ms, RTTの偏差×4)。失敗するたびに2倍になり、最大120秒です。Linux 6.15以降は、TCP_RTO_MAX_MSでこの上限を1秒まで下げられます。
グラフでは
最初から常に高い · 接続ごとのRTO、不要なRTOの数
確認箇所
サーバーのRTO最小値の設定(ip route showのrto_min、Linux 6.11以降はsysctl net.ipv4.tcp_rto_min_us)とss -tiのrto・rttを確認し、nstatのTcpExtTCPSpuriousRTOsの増分を確認
該当する場合
最小値を下げたサーバーで、インターネット接続のrtoがrttにぴったり張り付いており、TcpExtTCPSpuriousRTOsが大きく増える。デフォルト値のままなら、ゲームの接続のrtoがrttより200ms以上大きく、パケットロス1回ごとにその分止まる
該当しない場合
rtoがデフォルトの計算どおり(rtt + 200ms前後)で不要なRTOも少ないのに、止まる時間が際立って長いなら、連続したパケットロスか回復方式側の問題(「thin streamの遅い回復」「中間機器によるTCPオプションの除去」)
確認手段
インフラのツールで確認(ゲームコード不要)

出典

  1. RFC 6298: Computing TCP's Retransmission Timer IETF
    RTO = SRTT + max(G, 4·RTTVAR)、最小1秒を推奨、失敗するたびに2倍、最大値を設けるなら60秒以上
  2. include/net/tcp.h Linux kernel
    LinuxのTCP_RTO_MINは200ms、TCP_RTO_MAXは120秒
  3. net/ipv4/tcp_input.c Linux kernel
    LinuxのRTOはSRTT + rttvarで、rttvarはRTOの最小値(デフォルト200ms)を下回らない
  4. tcp: add the ability to control max RTO Linux kernel
    TCP_RTO_MAX_MSソケットオプションを追加(1〜120秒)、Linux 6.15から
  5. tcp: add sysctl_tcp_rto_min_us Linux kernel
    サーバー全体のデフォルトのRTO最小値tcp_rto_min_usを追加、Linux 6.11から
  6. tcp: support TCP_RTO_MIN_US for set/getsockopt use Linux kernel
    ソケットごとにRTOの最小値を決めるTCP_RTO_MIN_USソケットオプションを追加、Linux 6.15から
  7. IP Sysctl Linux kernel
    tcp_rto_min_usのデフォルト値は200000(経路オプションrto_min、ソケットオプションTCP_RTO_MIN_USが優先)、tcp_rto_max_msは1,000〜120,000(デフォルト値120,000)、tcp_thin_linear_timeouts
  8. ip-route(8) — Linux manual page iproute2
    経路ごとのrto_minオプション:その宛先と通信するときのRTOの最小値
  9. Thin-streams and TCP Linux kernel
    TCP_THIN_LINEAR_TIMEOUTSで、thin streamの接続だけ指数バックオフを無効にできる
  10. tcp(7) — Linux manual page Linux man-pages
    TCP_USER_TIMEOUT:確認応答のないデータを待ち続け、接続を閉じるまでの時間
  11. ss(8) — Linux manual page iproute2
    ss -iのrto(ms)とrtt
  12. SNMP counter Linux kernel
    TcpExtTCPSpuriousRTOs:F-RTOが検知した不要なRTO

あわせて読みたい原因

同じ層:TCP再送の根本原因

同じ症状(フリーズ)を起こすほかの層の原因

図と実験のあるメインページでこのカードを見る