TCP 혼잡 제어(congestion control)는 네트워크가 감당할 수 있는 만큼만 데이터를 보내도록 전송 속도를 스스로 조절하는 알고리즘이다. 리눅스의 기본값인 CUBIC은 패킷 손실을 혼잡 신호로 삼고, 구글이 만든 BBR은 실제 대역폭과 왕복 지연을 측정해 속도를 정한다. 같은 회선인데도 어느 걸 쓰느냐로 처리량이 몇 배 갈리기도 한다.
나는 오랫동안 이걸 "커널이 알아서 하는 것"으로 두고 신경을 안 썼다. 그러다 대륙 간 전송이 이상하게 느린 문제를 파다가, 혼잡 제어 알고리즘 한 줄 바꾸고 처리량이 3배가 된 걸 보고 나서야 제대로 공부했다.
왜 속도를 스스로 줄여야 하나
보내는 쪽이 무작정 빠르게 쏘면 중간 라우터의 큐가 넘쳐 패킷이 버려진다. 그러면 재전송이 폭증하고 전체가 무너진다. 1980년대 인터넷이 실제로 이렇게 붕괴(congestion collapse)한 적이 있다. 그 후로 TCP는 "천천히 시작해서, 문제 없으면 조금씩 올리고, 신호가 오면 확 줄이는" 규칙을 갖게 됐다.
핵심 변수는 혼잡 윈도우(cwnd)다. 아직 확인(ACK)받지 못한 채 보낼 수 있는 데이터 양이다. 연결이 시작되면 작게 출발해(slow start) 지수적으로 늘리다가, 어느 지점부터는 선형으로 조심스럽게 올린다. 문제는 "무엇을 혼잡 신호로 볼 것인가"이고, 여기서 알고리즘이 갈린다.
CUBIC: 손실을 신호로
CUBIC은 패킷 손실이 곧 혼잡이라고 본다. 손실이 나면 cwnd를 확 줄였다가, 3차 함수 곡선을 그리며 이전 최고점 근처까지 빠르게 되올린다. 손실 기반 알고리즘의 대표주자이고 대부분의 리눅스에서 기본값이다.
문제는 요즘 라우터의 버퍼가 지나치게 크다는 점이다(bufferbloat). 버퍼가 크면 패킷은 안 버려지고 큐에 쌓이기만 한다. CUBIC은 손실이 안 나니 계속 속도를 올리고, 그 결과 큐가 꽉 차 지연(latency)이 눈덩이처럼 불어난다. 처리량은 나오는데 반응성이 죽는 상황이다.
BBR: 대역폭과 지연을 직접 재기
BBR(Bottleneck Bandwidth and Round-trip propagation time)은 접근이 다르다. 손실을 기다리지 않고, 실제 병목 대역폭과 최소 왕복 지연(RTT)을 지속적으로 측정한다. 그리고 "대역폭 × 최소 RTT" 만큼만 파이프에 채운다. 큐를 채우지 않으면서 링크를 꽉 쓰는 지점을 노리는 것이다.
비유하면 CUBIC은 벽에 부딪혀야 멈추는 방식이고, BBR은 벽까지의 거리를 자로 재서 딱 앞에 서는 방식이다. 그래서 손실이 있어도 성능이 잘 안 꺾이고, 지연도 낮게 유지된다.
| 구분 | CUBIC | BBR |
|---|---|---|
| 혼잡 판단 | 패킷 손실 | 대역폭·RTT 측정 |
| 손실 많은 회선 | 성능 급락 | 비교적 견고 |
| 지연(latency) | 버퍼 채워 높아짐 | 낮게 유지 |
| 공정성 논란 | 적음 | CUBIC과 섞이면 이슈 |
바꿔보기
리눅스에서는 커널 모듈만 있으면 한 줄로 바꾼다. 현재 값과 사용 가능한 목록부터 확인하자.
# 현재 알고리즘 확인
sysctl net.ipv4.tcp_congestion_control
# 커널이 지원하는 목록
sysctl net.ipv4.tcp_available_congestion_control
# BBR로 전환 (영구 적용)
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
BBR은 페이싱(pacing)을 위해 fq 큐 규칙과 함께 쓰는 걸 권장한다. 위 설정에 default_qdisc=fq를 같이 넣은 이유다. 참고로 이 설정은 보내는 쪽에만 의미가 있다. 다운로드가 느리면 내 서버가 아니라 상대 서버의 혼잡 제어가 문제일 수 있다.
언제 무엇을 쓸까
- 대륙 간·고지연·손실 있는 경로(CDN 오리진, 원격 백업) — BBR이 대체로 유리하다.
- 데이터센터 내부·저지연·저손실 — 둘 다 잘 나온다. 굳이 안 바꿔도 무방하다.
- 여러 흐름이 한 링크를 공유 — BBR과 CUBIC이 섞이면 BBR이 대역폭을 더 가져가는 공정성 이슈가 있으니 벤치를 보고 결정하라. BBRv2/v3에서 개선되고 있다.
자주 묻는 질문
BBR로 바꾸면 항상 빨라지나요?
손실이나 지연이 큰 경로에서는 눈에 띄게 빨라지는 경우가 많습니다. 하지만 저손실 로컬 네트워크에서는 차이가 미미하고, 다른 CUBIC 흐름과 공유하는 링크에서는 공정성 문제가 생길 수 있으니 반드시 실제 트래픽으로 측정하세요.
클라이언트도 BBR을 켜야 하나요?
혼잡 제어는 데이터를 보내는 쪽에 적용됩니다. 서버가 응답을 많이 보내므로 서버에 설정하는 게 일반적입니다. 업로드가 많은 워크로드라면 클라이언트 설정도 의미가 있습니다.
bufferbloat가 뭔가요?
라우터·모뎀의 버퍼가 과도하게 커서, 패킷이 버려지지 않고 큐에 계속 쌓이며 지연이 폭증하는 현상입니다. 손실 기반인 CUBIC은 이 상황을 감지하지 못해 지연을 악화시키고, BBR과 fq 큐잉이 완화에 도움이 됩니다.
설정을 바꾸면 재부팅해야 하나요?
아닙니다. sysctl -p로 즉시 적용되고 새로 맺는 연결부터 반영됩니다. 다만 이미 열려 있는 연결은 기존 알고리즘을 유지합니다.

댓글 0