회선은 1Gbps라는데 서울-도쿄 간 단일 파일 전송이 100Mbps도 안 나옵니다. 패킷 손실도 없습니다. 이런 "빠른데 느린" 상황의 전형적 원인은 TCP 윈도우가 대역폭을 다 채우지 못하는 것입니다.
개념 — BDP와 윈도우
TCP는 ACK를 받기 전까지 보낼 수 있는 데이터양(윈도우)이 정해져 있습니다. 회선을 가득 채우려면 윈도우가 최소한 **BDP(대역폭 × 왕복지연)**만큼 커야 합니다.
OUTPUT
BDP = 대역폭(bps) × RTT(초) / 8 = 바이트
예) 1Gbps × 0.05s / 8 = 약 6.25 MB
지연이 큰 경로에서는 윈도우가 작으면 ACK를 기다리느라 회선이 비어 처리량이 RTT에 묶입니다. 그래서 고지연 구간일수록 윈도우 스케일링(윈도우를 64KB 너머로 키우는 옵션)이 결정적입니다.
1단계 — 윈도우 스케일링이 켜져 있나
로컬 터미널
sysctl net.ipv4.tcp_window_scaling
# net.ipv4.tcp_window_scaling = 1
1이어야 합니다. 협상은 양쪽 SYN에서 이뤄지므로, 패킷을 직접 보면 확실합니다.
로컬 터미널
sudo tcpdump -n -v 'tcp[tcpflags] & tcp-syn != 0' | grep -i wscale
2단계 — 실제 연결의 윈도우 확인 (ss)
로컬 터미널
ss -tin
출력의 wscale, cwnd(혼잡 윈도우), rtt 값을 봅니다. cwnd가 작은 채로 멈춰 있거나 wscale이 0이면 윈도우가 처리량을 제한하고 있을 가능성이 큽니다.
| 지표 | 의미 | 해석 |
|---|---|---|
wscale | 송수신 윈도우 스케일 지수 | 0이면 스케일링 미적용 |
cwnd | 혼잡 윈도우(세그먼트 수) | 작으면 전송이 묶임 |
rtt | 왕복 지연 | BDP 계산 입력값 |
3단계 — 처리량 측정 (iperf3)
로컬 터미널
# 수신 측
iperf3 -s
# 송신 측
iperf3 -c <서버IP> -t 20
단일 스트림 처리량이 회선보다 한참 낮은데 병렬(-P 8)로 늘리면 합산 처리량이 확 오른다면, 단일 연결의 윈도우가 병목이라는 강한 증거입니다. 커널 버퍼 상한도 함께 확인합니다.
로컬 터미널
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem # 최대값이 BDP보다 커야 함
체크리스트
로컬 터미널
sysctl net.ipv4.tcp_window_scaling # 스케일링 on(=1)
ss -tin # wscale·cwnd·rtt 확인
iperf3 -c <IP> -t 20 # 단일 스트림 처리량
iperf3 -c <IP> -P 8 # 병렬로 늘면 윈도우 병목
sysctl net.ipv4.tcp_rmem # 수신 버퍼 상한 점검
손실이 없는데 처리량이 안 나오면 가장 먼저 의심할 것은 회선이 아니라 윈도우 대 BDP의 관계입니다.
TCP 윈도우·혼잡제어가 처리량을 어떻게 좌우하는지 직접 측정해보는 실습은 네트워크 트랙에서 회원가입 없이 무료로 할 수 있습니다.