포스트

네트워크 성능 — 대역폭은 왜 빠름이 아닌가 (RTT·BDP·처리량의 진실)

대역폭과 지연·RTT의 차이(파이프 굵기 vs 길이), BDP=대역폭×RTT, 윈도우와 처리량의 관계, Mathis 공식, 버퍼블로트, iperf3·traceroute·mtr 측정까지 네트워크 성능을 분석합니다.

네트워크 성능 — 대역폭은 왜 빠름이 아닌가 (RTT·BDP·처리량의 진실)

“기가비트인데 왜 느리죠?”

회선을 1 Gbps로 올렸는데 서울↔프랑크푸르트 파일 전송이 여전히 답답합니다. 대역폭을 더 사도 안 빨라집니다. 이건 버그가 아니라 대역폭과 지연이 서로 다른 축이기 때문입니다. 이 글의 목표는 “느리다”는 막연한 말을 대역폭 / 지연 / RTT / BDP / 손실이라는 측정 가능한 양으로 분해하고, 왜 어떤 경우엔 더 넓은 파이프가 1바이트도 도움이 안 되는지를 끝까지 밝히는 것입니다.

패킷 교환 글에서 본 4가지 지연(전송·전파·처리·큐)이 여기서 성능 공식으로 합쳐집니다.

파이프 비유: 굵기 vs 길이

네트워크 경로를 물 파이프로 생각하면 모든 게 맞아떨어집니다.

  • 대역폭(bandwidth) = 파이프의 굵기. 단위 시간당 밀어 넣을 수 있는 비트(bps).
  • 지연(latency) = 파이프의 길이. 비트 하나가 끝까지 가는 시간. 주로 거리÷광속(전파 지연)이 지배.
  • RTT(왕복 시간) = 보내고 응답이 돌아오기까지 = 대략 2 × 편도 지연.
송신 수신 길이 = 지연(거리÷광속) · 굵기 = 대역폭(bps)

핵심은 이것입니다. 파이프를 굵게 해도 길이는 안 줄어듭니다. 서울↔프랑크푸르트 편도 전파는 광속 한계상 ~120 ms이고, 회선을 10배 넓혀도 첫 바이트 도착 시간은 그대로입니다. “빠르다”가 지연을 뜻하면 대역폭은 답이 아닙니다 — 답은 거리를 줄이는 것(CDN·엣지)입니다(CDN 글).

BDP — 파이프 안에 동시에 떠 있는 비트의 양

여기서 가장 중요한 양이 나옵니다. 대역폭-지연 곱(Bandwidth-Delay Product):

1
BDP (비트) = 대역폭(bps) × RTT(초)

이건 “전송했지만 아직 ACK를 못 받은, 즉 파이프 안에 떠 있을 수 있는 데이터의 최대량”입니다. 파이프의 부피라고 생각하면 됩니다.

예시 — 왜 100 Mbps 회선이 12 Mbps밖에 안 나오나. 대역폭 100 Mbps, RTT 80 ms 경로. BDP = 100 Mbps × 0.08 s = 8 Mbit = 1 MB. 파이프를 가득 채우려면 송신 측이 ACK 없이 1 MB를 앞서 보낼 수 있어야 합니다. 그런데 TCP 윈도우가 64 KB(옛 기본)라면? 64 KB 보내고 ACK를 기다리느라 멈춥니다. 실효 처리량 = 윈도우 ÷ RTT = 64 KB ÷ 0.08 s ≈ 6.4 Mbps. 대역폭의 6%만 씁니다.

이게 LFN(Long Fat Network, 고대역폭·고지연 경로) 의 함정입니다. 대역폭이 아니라 윈도우가 병목입니다.

윈도우가 BDP보다 작으면 — 파이프가 빈다

아래 위쪽은 윈도우가 BDP와 같아 파이프가 꽉 찬 경우, 아래쪽은 윈도우가 작아 보내고 멈추고(ACK 대기) 다시 보내며 파이프에 빈 구간이 생기는 경우입니다. 같은 회선인데 아래는 처리량이 절반 이하입니다.

윈도우 = BDP · 파이프 꽉 참 (최대 처리량) 윈도우 ≪ BDP · 빈 구간 (처리량 ↓) 같은 대역폭·같은 RTT — 차이는 오직 윈도우 크기

그래서 처리량의 근본 공식은 이렇습니다.

1
실효 처리량 ≈ 윈도우 크기 / RTT      (윈도우가 병목일 때)

해법은 윈도우를 BDP 이상으로 키우는 것입니다. 리눅스는 tcp_window_scaling(RFC 1323)으로 64 KB 한계를 넘기고, 버퍼 자동 튜닝(tcp_rmem/tcp_wmem의 max)으로 BDP에 맞춰 윈도우를 키웁니다. 송신 윈도우는 혼잡 제어의 cwnd와 수신 윈도우 중 작은 쪽으로 정해지고, 이 버퍼는 소켓 글의 SO_RCVBUF와 같은 것입니다.

손실이 끼면 — Mathis 공식

패킷 손실이 있으면 이야기가 더 나빠집니다. AIMD 기반 TCP의 처리량 상한은 근사적으로:

1
처리량 ≲ (MSS / RTT) × (1 / √p)        (p = 패킷 손실률)

손실률 p가 처리량을 제곱근으로 깎습니다. RTT 100 ms, MSS 1460 B에서 손실 0.01%(p=0.0001)면 상한은 약 117 Mbps지만, 손실이 1%로 오르면 같은 식이 약 12 Mbps로 떨어집니다. 고RTT 경로에서 약간의 손실이 처리량을 붕괴시키는 이유입니다 — 그래서 장거리 전송에선 손실률 0.01%도 큰 문제입니다.

양정의키우면/줄이면측정
대역폭단위시간 비트(bps)처리량 상한↑iperf3 -c
RTT왕복 시간작을수록 처리량↑·반응성↑ping, ss -i(rtt)
BDP대역폭×RTT필요한 윈도우 크기계산
윈도우ACK 없이 보낼 양≥BDP라야 파이프 채움ss -i(cwnd, wscale)
손실률 pdrop 비율√p로 처리량 깎임ss -i(retrans), mtr
지터RTT 변동작을수록 실시간 품질↑ping, iperf3 -u

버퍼블로트 — 큐가 너무 커서 생기는 지연

직관과 반대로, 라우터 버퍼가 너무 크면 성능이 나빠집니다. 큐에 패킷이 잔뜩 쌓여도 drop이 안 나니 TCP가 혼잡을 늦게 알아채고, 그 사이 큐 대기 시간이 수백 ms~초로 폭증합니다 — 버퍼블로트(bufferbloat). 다운로드 중에 화상통화가 끊기는 전형적 원인입니다. 해법은 AQM(CoDel·FQ-CoDel·CAKE)으로, 큐가 오래 머문 패킷을 일찍 떨궈 지연을 낮춥니다.

측정 도구 — 추측 금지

1
2
3
4
5
6
ping -c 20 host                 # RTT 평균/최소/최대 + 지터(mdev)
mtr --report --report-cycles 50 host   # 홉별 손실률·RTT (traceroute+ping)
iperf3 -c host -t 30            # 실효 처리량(TCP), -u로 UDP 지터/손실
iperf3 -c host -P 8             # 병렬 8스트림 — 단일 윈도우 병목 우회 확인
ss -tin dst host                # cwnd, rtt, retrans, wscale 실시간
tcpdump -i eth0 -w cap.pcap     # 재전송·중복 ACK를 패킷 수준에서

진단 사고법: ① iperf3 -P 1 처리량이 낮은데 -P 8이 빠르면 → 윈도우/BDP 병목(버퍼 키워라). ② mtr에서 특정 홉부터 손실 누적 → 그 구간 혼잡/장애. ③ 다운로드 시 ping RTT가 급등 → 버퍼블로트(AQM 적용).

traceroute — RTT가 홉마다 쌓인다

traceroute는 TTL을 1,2,3…으로 늘려 각 홉이 보내는 ICMP Time Exceeded로 경로와 누적 RTT를 그립니다. 아래는 프로브가 한 홉씩 더 멀리 가며 RTT가 누적되는 모습입니다.

출발 홉1 · 2ms 홉2 · 14ms 홉3 · 48ms 목적지 · 92ms

면접/리뷰 단골 질문

  • Q. 대역폭을 늘렸는데 안 빨라진다. 왜? → “빠름”이 지연이면 대역폭 무관(거리÷광속). “빠름”이 처리량인데 안 오르면 윈도우<BDP 병목이거나 손실이다.
  • Q. BDP를 한 줄로? → 대역폭×RTT. 파이프에 떠 있을 수 있는 비트량. 윈도우가 이보다 작으면 파이프를 못 채운다.
  • Q. 처리량 공식은? → 윈도우 병목 시 윈도우/RTT. 손실 있으면 Mathis로 (MSS/RTT)·(1/√p) 상한. RTT와 손실이 같이 처리량을 누른다.
  • Q. 버퍼가 큰데 왜 느려지나? → 버퍼블로트. 큰 큐가 drop을 늦춰 혼잡 신호가 늦고 큐 지연이 폭증. AQM(CoDel)으로 해결.
  • Q. 단일 스트림은 느린데 병렬은 빠르다. 진단은? → 윈도우/BDP 병목. 윈도우 스케일링·버퍼 자동튜닝으로 단일 스트림 윈도우를 키운다.

정리

  • 대역폭(굵기) ≠ 지연(길이) ≠ 처리량(실제 흐른 양). 셋을 분리 못 하면 원인을 못 찾는다.
  • BDP = 대역폭 × RTT. 윈도우가 BDP보다 작으면 파이프가 비어 처리량 = 윈도우/RTT로 묶인다(LFN 함정).
  • 손실은 √p로 처리량을 깎는다(Mathis). 고RTT에선 작은 손실도 치명적.
  • 버퍼는 작아도(채움 부족) 커도(버퍼블로트) 문제다 → 윈도우는 BDP에 맞추고, 큐는 AQM으로.
  • 추측 말고 ping/mtr/iperf3/ss -i로 측정하라.

이 성능 원리는 패킷 교환의 4지연에서 출발해, TCP 혼잡 제어의 cwnd, 소켓 버퍼, 거리를 줄이는 CDN과 한 몸으로 묶입니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

시리즈 · 네트워크 A-Z (20편)

  1. 네트워크란 무엇인가 — 회선 교환 vs 패킷 교환, 왜 인터넷은 패킷을 선택했나
  2. OSI 7계층과 TCP/IP — 왜 네트워크를 굳이 층으로 쪼갰나
  3. 이더넷·MAC·스위치 — 스위치는 어떻게 "어느 포트로 보낼지" 스스로 배우나
  4. IP 주소와 서브넷팅 — /24를 /26으로 쪼갠다는 게 비트 단위로 무슨 뜻인가
  5. 라우팅은 어떻게 길을 찾나 — 라우팅 테이블, Longest Prefix Match, 그리고 BGP
  6. ARP와 L2/L3 경계 — IP는 아는데 왜 MAC을 또 묻나
  7. TCP는 어떻게 신뢰를 만드나 — 3-way handshake, 상태 머신, 그리고 TIME_WAIT
  8. TCP는 얼마나 빨리 보낼까 — 흐름 제어 vs 혼잡 제어, 그리고 톱니파의 비밀
  9. UDP와 QUIC — TCP를 버려야 더 빨라지는 순간
  10. DNS는 어떻게 이름을 주소로 바꾸나 — 루트부터 권한 서버까지, 그리고 캐시의 마법
  11. HTTP의 진화 — 1.1의 줄 서기에서 HTTP/2 멀티플렉싱, HTTP/3까지
  12. TLS/HTTPS는 어떻게 도청 불가능한 채널을 만드나 — 핸드셰이크부터 인증서 체인까지
  13. NAT와 사설망 — 주소 하나로 수백 대가 인터넷을 쓰는 법, 그리고 P2P가 막히는 이유
  14. 로드 밸런싱 — L4와 L7은 무엇이 다르며, 왜 헬스체크가 서비스를 살리고 죽이나
  15. 프록시·리버스 프록시·CDN — 콘텐츠를 사용자 코앞으로 옮기는 기술
  16. 방화벽·보안그룹·네트워크 ACL — stateful과 stateless가 가르는 모든 것
  17. VPC & 클라우드 네트워킹 — 라우팅 테이블 한 줄이 퍼블릭과 프라이빗을 가른다
  18. 소켓과 커널 네트워크 스택 — accept 한 줄 뒤에서 벌어지는 일
  19. 네트워크 성능 — 대역폭은 왜 빠름이 아닌가 (RTT·BDP·처리량의 진실) 지금 보는 글
  20. 현대 네트워킹 — 사이드카, eBPF, 그리고 경계가 사라진 신뢰