ゲームラグ白書 › TCP再送の根本原因
順序の入れ替わりによる不要な高速再送 Reordering triggers spurious fast retransmit
原因ID rt-reorder · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
図と実験のあるメインページでこのカードを開く →
複数の経路や束ねたリンクを通る間にパケットの順序が入れ替わると、受信側が重複ACKで「抜けたパケットがある」と知らせ、送信側は問題のないパケットを送り直します。
なぜ パケット単位で経路を振り分ける機器、パケット単位で振り分けて送るLAG(リンクアグリゲーション)、経路が切り替わる瞬間が順序を乱す → すると 後のパケットが先に到着して重複ACKが3つたまる → 高速再送 → 画面では まばらにやり取りされるゲームパケットにはほとんど影響なし。人の多い場所での大きな更新やアップデートデータのダウンロードが遅くなり、ときどきカクつく
- 症状
- カクつき, 入力遅延
- 要因
- ジッター
- 誰に起きるか
- 特定の地域・ISP, サーバー全体
- いつ
- 常に, 人が集中したとき
- 担当
- 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
- インフラチームの対応
- ネットワーク:パケット単位の分散の代わりに接続単位の分散(ECMP・LAGをアドレス・ポートのハッシュで)。サーバー機器・OS:RACK(時間に基づくロス判定、順序の入れ替わりに強い。DSACKで不要な再送を検知すると、順序の入れ替わりの許容幅を自動で広げる)を使う、Linuxが接続ごとに自動で推定した順序の入れ替わりの度合いを確認(ss -tiのreordering値、初期値はtcp_reordering=3)。
- グラフでは
- 最初から常に高い · 順序の入れ替わりの検知数、DSACKの受信数
- 確認箇所
- nstatのTcpExtTCPSACKReorder・TcpExtTCPTSReorder(順序の入れ替わりを検知した回数)とTcpExtTCPDSACKRecvを確認し、接続ごとにはss -tiのreordering(3でなければ表示)・reord_seenを確認。パケットキャプチャでは、Wiresharkのフィルターtcp.analysis.out_of_orderを使う
- 該当する場合
- 順序の入れ替わりのカウンターとDSACKが時間帯に関係なく継続的に増え、特定の経路・機器を通る接続のreordering値が3より大きくなっている。受信側のキャプチャで、後のパケットが先に届き、前のパケットもすぐに届いている
- 該当しない場合
- 順序の入れ替わりのカウンターは変わらず、TcpExtTCPLostRetransmitが増えるなら実際のパケットロス。RTTが跳ねる瞬間にだけDSACKが増えるなら「遅延の急上昇による不要な再送」
- 確認手段
- インフラのツールで確認(ゲームコード不要)
出典
- RFC 2991: Multipath Issues in Unicast and Multicast Next-Hop Selection IETF
パケット単位で経路を振り分けると順序が入れ替わり、後のパケットが3つ以上先に届くと、TCPは不要な高速再送を行う - RFC 2992: Analysis of an Equal-Cost Multi-Path Algorithm IETF
フローを識別するヘッダーフィールドのハッシュで経路を選ぶECMP(フロー単位の分散) - RFC 5681: TCP Congestion Control IETF
3つ目の重複ACKで高速再送 - RFC 8985: The RACK-TLP Loss Detection Algorithm for TCP IETF
RACKは時間に基づいてロスを判定するため順序の入れ替わりに強く、DSACKを受け取ると順序の入れ替わりの許容時間(reo_wnd)を延ばす - IP Sysctl Linux kernel
tcp_reorderingの初期値は3(接続ごとにtcp_max_reorderingまで自動調整)、tcp_recoveryのRACK設定 - misc/ss.c iproute2
ss -tiは、接続のreordering値がデフォルト値の3と異なるときにreordering:値を、順序の入れ替わりを経験したことがあればreord_seen:回数を表示 - SNMP counter Linux kernel
TcpExtTCPSACKReorder・TcpExtTCPTSReorder(順序の入れ替わりの検知)、TcpExtTCPDSACKRecv(受信したDSACKの数)、TcpExtTCPLostRetransmit(送り直したパケットをまた失った数) - include/uapi/linux/tcp.h Linux kernel
tcp_infoのtcpi_reord_seen:接続が経験した順序の入れ替わりの回数 - Display Filter Reference: Transmission Control Protocol Wireshark
tcp.analysis.out_of_orderの表示フィルター
あわせて読みたい原因
同じ層:TCP再送の根本原因
同じ症状(カクつき)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る