12. 소켓 버퍼와 대역폭-지연 곱(BDP), TCP 윈도우 스케일링, 처리량 튜닝
난이도 상모범답안 — 소켓 버퍼와 대역폭-지연 곱(BDP), TCP 윈도우 스케일링, 처리량 튜닝
난이도: 상
1. 송신/수신 버퍼와 흐름 제어
- 송신 버퍼(SO_SNDBUF): 앱이
send()한 데이터를 커널이 보관하는 곳. ACK 가 와서 "확실히 전달됨"이 확인되기 전까지의 미확인(in-flight) 데이터 + 아직 못 보낸 데이터를 담는다. 송신 버퍼가 작으면 비행 중 데이터를 충분히 못 띄워 처리량이 깎인다. - 수신 버퍼(SO_RCVBUF): 도착했지만 앱이 아직
recv()하지 않은 데이터를 보관. 이 여유 공간이 곧 TCP가 상대에게 광고하는 수신 윈도우(rwnd) 의 근거다. - 흐름 제어(flow control): 수신자가 "지금 rwnd 바이트까지 더 받을 수 있다"를 ACK에 실어 광고한다. 송신자는
min(혼잡 윈도우 cwnd, rwnd)만큼만 비행시킨다. 즉 수신 버퍼가 작으면 rwnd 가 작아져 송신자가 적게 보낸다. (흐름 제어 = 수신자 보호, 혼잡 제어 = 네트워크 보호로 구분.)
2. 대역폭-지연 곱(BDP)
BDP = 대역폭 × RTT. "파이프(링크)에 동시에 떠 있을 수 있는 데이터량"이다. TCP는 "보내고 ACK를 기다리는" 구조라, 한 RTT 동안 비행시킬 수 있는 데이터가 윈도우 크기로 제한된다. 처리량 ≈ 윈도우 / RTT. 그래서 링크를 가득 채우려면 윈도우(그리고 그것을 뒷받침하는 송·수신 버퍼)가 최소 BDP 이상이어야 한다. 작으면 한 RTT마다 윈도우만큼 보내고 멈춰 ACK를 기다리느라 대역폭을 못 쓴다.
예) 100Mbps, RTT 200ms:
- BDP = 100,000,000 bit/s × 0.2 s = 20,000,000 bit = 2.5 MB.
- 윈도우가 64KB(65,536B)면: 처리량 ≈ 65,536 × 8 / 0.2 ≈ 2.62 Mbps. 즉 100Mbps 회선에서 ~2.6Mbps 밖에 못 낸다. 링크를 채우려면 윈도우/버퍼가 2.5MB 이상 필요.
3. 16비트 윈도우와 윈도우 스케일링
원래 TCP 헤더의 수신 윈도우 필드는 16비트라 최대 65,535바이트(64KB) 다. 위 예처럼 BDP가 64KB를 크게 넘는 long fat network(LFN, 고대역폭×고지연) 에서는 이 64KB가 처리량 상한이 되어 회선을 못 채운다. 윈도우 스케일링(RFC 1323/7323) 은 3-way handshake의 SYN에서 "윈도우 스케일 팩터(shift)"를 교환해, 광고 윈도우를 값 << shift 로 해석하게 한다(최대 1GB까지). 이를 통해 BDP가 큰 링크에서도 충분한 윈도우를 광고할 수 있다. 핸드셰이크 때만 협상되므로 연결 시작 시 양쪽이 지원·활성화되어 있어야 한다(방화벽이 옵션을 지우면 무력화).
4. 진단과 튜닝
의심 원인: 송·수신 버퍼(또는 윈도우)가 BDP보다 작아 윈도우 한계로 묶임. 윈도우 스케일링 비활성/방화벽 제거, 손실로 인한 cwnd 위축도 후보.
진단: 패킷 캡처로 광고 윈도우·스케일 옵션·재전송 여부 확인(ss -i, tcpdump). 처리량이 윈도우/RTT 근처에서 막히면 윈도우 병목, 손실·재전송이 많으면 혼잡/회선 품질 문제.
튜닝:
- 커널 버퍼 자동 튜닝(auto-tuning) 을 켜고 최대치를 BDP 이상으로(예: Linux
tcp_rmem/tcp_wmem상한 상향). 대부분 수동 SO_RCVBUF 설정보다 자동 튜닝이 낫다(수동 설정은 자동 튜닝을 꺼버릴 수 있음). - 윈도우 스케일링 활성 확인.
부작용 — bufferbloat: 버퍼(특히 중간 장비 큐)를 무작정 키우면 패킷이 큐에 오래 쌓여 지연(latency)·지터가 폭증한다. 처리량은 늘어도 실시간성은 망가진다.
실시간 + 대용량 공존:
- 트래픽 성격이 정반대다: 실시간 게임은 작은 패킷·저지연(작은 버퍼,
TCP_NODELAY로 Nagle 비활성, 종종 UDP), 패치 다운로드는 대용량·고처리량(큰 버퍼/윈도우). - 그래서 연결별로 다르게 설정하거나, 대용량 전송은 별도 포트/서비스로 분리. 실시간 채널의 버퍼를 키워 bufferbloat로 지연을 키우지 않는다.
- 혼잡 제어 알고리즘 선택(예: BBR vs CUBIC)도 고지연·손실 환경의 처리량/지연 균형에 영향. 실시간 트래픽은 애초에 신뢰성 UDP(RUDP)로 빼는 설계가 흔하다.
핵심 요약
처리량 ≈ 윈도우/RTT, 윈도우는 송·수신 버퍼와 rwnd로 결정되며, 링크를 채우려면 버퍼/윈도우 ≥ BDP. 16비트 윈도우 한계는 윈도우 스케일링으로 푼다. 단, 버퍼를 키우면 bufferbloat로 지연이 늘 수 있어, 실시간 게임 트래픽과 대용량 전송은 분리·차등 설정한다.