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

게임 렉 백서 › TCP 재전송의 근본 원인

지연 급등으로 인한 불필요한 재전송 Spurious RTO from delay spikes

원인 ID rt-spurious-delay · 주 담당 외부·외부 · 함께 인프라팀·서버 인프라, 게임개발팀·클라이언트 개발

그림과 실험이 있는 원본 카드로 열기 →

패킷은 사라지지 않고 잠깐 아주 늦게 도착했을 뿐인데, 그 지연이 RTO보다 길면 보내는 쪽이 손실로 판단해 재전송합니다.

왜 버퍼블로트, 와이파이 절전, 모바일 무선 상태 전환, 가상 머신 일시 정지로 순간 지연이 수백 ms → 그러면 RTO가 먼저 만료되어 재전송, 원본도 곧 도착(받는 쪽은 중복으로 받음) → 화면에서는 멈춤·몰아치기는 지연 급등 자체 때문. 불필요한 재전송은 멈춤을 거의 늘리지 않고 재전송 지표만 올려 손실로 오해받음

증상
멈춤, 몰아치기, 입력 지연
요인
지연, 지터
누가 겪나
나만, 서버 전체
언제
가끔 무작위로, 가만히 있다가
담당
주 담당 외부·외부 · 함께 인프라팀·서버 인프라, 게임개발팀·클라이언트 개발
게임개발팀 할 일
안드로이드 10 이상 클라이언트는 게임 중 저지연 와이파이 모드(WIFI_MODE_FULL_LOW_LATENCY 와이파이 잠금, 화면이 켜져 있고 게임이 앞에 있을 때만 적용)를 요청해 절전으로 생기는 지연 급등 줄이기.
인프라팀 할 일
버스트형 인스턴스 피하기, RTO 최소값을 너무 낮추지 않기, F-RTO·타임스탬프 유지(tcp_frto, tcp_timestamps), 재전송 지표는 nstat의 TCPSpuriousRTOs·TCPDSACKRecv와 함께 봐서 손실로 오해하지 않기.
외부 할 일
지연 급등 자체를 줄이도록 유저에게 공유기 SQM 사용, 와이파이 절전 끄기 안내.
수치 감각
리눅스는 F-RTO로 불필요한 RTO를 감지하고 전송량 축소를 되돌리기도 합니다. nstat의 TCPSpuriousRTOs(불필요한 RTO로 판정한 횟수)와 TCPDSACKRecv(받는 쪽이 “이미 받은 것”이라고 알려 온 횟수)로 확인합니다.
그래프에서는
가끔 무작위로 튐 · RTT(핑), 불필요한 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, 안드로이드 10): AP에 연결되어 있고 화면이 켜져 있고 앱이 앞에 있을 때만 적용되는 저지연 와이파이 잠금
  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 재전송의 근본 원인

같은 증상(멈춤)의 다른 층 원인

그림과 실험이 있는 원본 카드 보기