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

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

遅延の急上昇による不要な再送 Spurious RTO from delay spikes

原因ID rt-spurious-delay · 主担当 外部・外部 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発

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

パケットは消えておらず、一時的にとても遅れて届いただけなのに、その遅延がRTOより長いと、送信側はパケットロスと判断して再送します。

なぜ バッファブロート、Wi-Fiの省電力、モバイルの無線状態の切り替え、仮想マシンの一時停止で、瞬間的な遅延が数百ms → すると RTOが先に満了して再送、元のパケットもすぐに到着(受信側は重複して受け取る) → 画面では フリーズ・早送りは遅延の急上昇そのものが原因。不要な再送は止まる時間をほとんど延ばさず、再送のメトリクスだけを押し上げるため、パケットロスと誤解される

症状
フリーズ, 早送り, 入力遅延
要因
遅延, ジッター
誰に起きるか
自分だけ, サーバー全体
いつ
ときどきランダムに, しばらく放置した後
担当
主担当 外部・外部 · 副担当 インフラチーム・サーバーインフラ, ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応
Android 10以上のクライアントは、ゲーム中に低遅延Wi-Fiモード(WIFI_MODE_FULL_LOW_LATENCYのWi-Fiロック、画面がオンでゲームがフォアグラウンドにあるときだけ適用)を要求し、省電力による遅延の急上昇を減らす。
インフラチームの対応
バースト可能インスタンスを避ける、RTOの最小値を下げすぎない、F-RTO・タイムスタンプを維持(tcp_frto、tcp_timestamps)、再送のメトリクスはnstatのTCPSpuriousRTOs・TCPDSACKRecvとあわせて確認し、パケットロスと誤解しない。
外部の対応
遅延の急上昇そのものを減らすため、ユーザーにルーターのSQMの利用、Wi-Fiの省電力の無効化を案内。
数値の目安
LinuxはF-RTOで不要なRTOを検知し、送信量の絞り込みを元に戻すこともあります。nstatのTCPSpuriousRTOs(不要なRTOと判定した回数)とTCPDSACKRecv(受信側が「もう受け取った」と知らせてきた回数)で確認します。
グラフでは
不定期なスパイク · RTT(Ping)、不要なRTOの数
確認箇所
nstatを1分間隔で実行し、TcpExtTCPTimeouts(RTOの満了)、TcpExtTCPSpuriousRTOs、TcpExtTCPDSACKRecv、TcpExtTCPLostRetransmitの増分をあわせて確認。パケットキャプチャがあれば、Wiresharkのフィルターtcp.analysis.spurious_retransmissionを使う
該当する場合
RTOが増えるときにTcpExtTCPSpuriousRTOsやTcpExtTCPDSACKRecvもそろって増え、同じ時刻にRTTが数百msに跳ねる。受信側のキャプチャに、元のパケットと再送の両方が届いている
該当しない場合
TcpExtTCPSpuriousRTOs・DSACKは変わらないのにTcpExtTCPLostRetransmit(送り直したものまでまた失う)が増えるなら実際のパケットロス。RTTは跳ねないのにDSACKだけが継続的に多いなら「順序の入れ替わりによる不要な高速再送」
確認手段
インフラのツールで確認(ゲームコード不要)

出典

  1. RFC 5682: Forward RTO-Recovery (F-RTO): An Algorithm for Detecting Spurious Retransmission Timeouts with TCP IETF
    F-RTO:RTOの後に届いたACKで、不要なRTOだったかを見分ける
  2. RFC 3481: TCP over Second (2.5G) and Third (3G) Generation Wireless Networks IETF
    モバイル回線の遅延の急上昇(ハンドオーバー、リンクの回復など)が、不要なTCPタイムアウト・再送と輻輳ウィンドウの縮小を引き起こす
  3. RFC 2883: An Extension to the Selective Acknowledgement (SACK) Option for TCP IETF
    DSACK:受信側が重複受信を知らせることで、送信側が不要な再送に気づける
  4. SNMP counter Linux kernel
    TcpExtTCPSpuriousRTOs(F-RTOが検知した不要なRTO)、TcpExtTCPDSACKRecv(受信したDSACKの数)、TcpExtTCPLostRetransmit(送り直したパケットをまた失ったとSACKが知らせてきた数)
  5. IP Sysctl Linux kernel
    tcp_frtoはデフォルトで有効(RTTが揺れる無線ネットワークで有利)、tcp_timestampsのデフォルト値は1
  6. RFC 6298: Computing TCP's Retransmission Timer IETF
    不要な再送を防ぐには大きな最小RTOが必要だという根拠(最小1秒を推奨)
  7. WifiManager Android (Google)
    WIFI_MODE_FULL_LOW_LATENCY(API 29、Android 10):APに接続していて、画面がオンで、アプリがフォアグラウンドにあるときだけ適用される低遅延Wi-Fiロック
  8. net/ipv4/proc.c Linux kernel
    nstatに表示されるカウンター名TCPTimeouts・TCPSpuriousRTOs・TCPDSACKRecv・TCPLostRetransmit
  9. net/ipv4/tcp_timer.c Linux kernel
    TCPTimeoutsは再送タイマー(RTO)が満了したときに増加
  10. nstat(8) — Linux manual page iproute2
    nstatはデフォルトで、前回の実行以降の増分を表示
  11. Display Filter Reference: Transmission Control Protocol Wireshark
    tcp.analysis.spurious_retransmissionの表示フィルター

あわせて読みたい原因

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

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

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