ゲームラグ白書 › 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オプションの除去」) 確認手段 インフラのツールで確認(ゲームコード不要)
出典 RFC 6298: Computing TCP's Retransmission Timer IETF RTO = SRTT + max(G, 4·RTTVAR)、最小1秒を推奨、失敗するたびに2倍、最大値を設けるなら60秒以上 include/net/tcp.h Linux kernel LinuxのTCP_RTO_MINは200ms、TCP_RTO_MAXは120秒 net/ipv4/tcp_input.c Linux kernel LinuxのRTOはSRTT + rttvarで、rttvarはRTOの最小値(デフォルト200ms)を下回らない tcp: add the ability to control max RTO Linux kernel TCP_RTO_MAX_MSソケットオプションを追加(1〜120秒)、Linux 6.15から tcp: add sysctl_tcp_rto_min_us Linux kernel サーバー全体のデフォルトのRTO最小値tcp_rto_min_usを追加、Linux 6.11から tcp: support TCP_RTO_MIN_US for set/getsockopt use Linux kernel ソケットごとにRTOの最小値を決めるTCP_RTO_MIN_USソケットオプションを追加、Linux 6.15から 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 ip-route(8) — Linux manual page iproute2 経路ごとのrto_minオプション:その宛先と通信するときのRTOの最小値 Thin-streams and TCP Linux kernel TCP_THIN_LINEAR_TIMEOUTSで、thin streamの接続だけ指数バックオフを無効にできる tcp(7) — Linux manual page Linux man-pages TCP_USER_TIMEOUT:確認応答のないデータを待ち続け、接続を閉じるまでの時間 ss(8) — Linux manual page iproute2 ss -iのrto(ms)とrtt SNMP counter Linux kernel TcpExtTCPSpuriousRTOs:F-RTOが検知した不要なRTO
あわせて読みたい原因
同じ層:TCP再送の根本原因
同じ症状(フリーズ)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る