네트워크 전체가 막히지 않도록 송신량을 조절하는 것. 보호 대상은 중간 라우터들이다.
왜 필요한가
라우터는 처리 못 한 패킷을 큐에 쌓아 둔다. 모두가 마음껏 보내면 큐가 넘쳐 패킷을 버리고, 그러면 다들 재전송하고, 그래서 더 막히는 혼잡 붕괴가 일어난다.
문제는 송신자가 네트워크 상태를 직접 볼 수 없다는 것이다. 그래서 패킷 손실을 혼잡의 신호로 추론한다.
cwnd — 송신자가 스스로 정하는 창
송신자는 cwnd(congestion window)라는 값을 들고 있고, 이만큼만 보낸다.
이 값을 상황에 따라 키우고 줄이는 것이 혼잡 제어다.
단계별 동작
① Slow Start — cwnd를 1부터 시작해 ACK를 받을 때마다 1씩 올린다.
한 RTT에 받는 ACK 수만큼 늘어나므로 결과적으로 매 왕복마다 2배가 된다.
이름이 "느린 시작"이지 느리게 증가한다는 뜻이 아니다. 시작이 작다는 뜻이고 증가는 지수적이다. 면접에서 자주 뒤집어 답하는 지점이다.
② Congestion Avoidance — 임계치(ssthresh)를 넘으면 지수 증가를 멈추고
한 왕복에 1씩 선형으로 올린다. 한계 근처에서 조심스럽게 접근하는 것이다.
③ 손실 감지
- 중복 ACK 3회 — 특정 패킷만 빠졌고 뒤의 것들은 도착했다는 뜻. 네트워크가 아주 나쁘진 않다고 보고 cwnd를 절반으로만 줄인다(빠른 회복).
- 타임아웃 — 아예 응답이 없다. 심각하다고 보고 cwnd를 1로 되돌린다.
AIMD
늘릴 땐 조금씩 더하고(Additive Increase), 줄일 땐 절반으로 곱해서 줄인다 (Multiplicative Decrease). 이 비대칭이 여러 연결이 대역폭을 공평하게 나눠 갖도록 수렴시킨다.
요즘 알고리즘
| 알고리즘 | 신호 | 특징 |
|---|---|---|
| Reno / CUBIC | 손실 | 리눅스 기본은 CUBIC |
| BBR | 대역폭·지연 측정 | 손실을 기다리지 않아 버퍼 블로트에 강함 |
손실 기반은 라우터 버퍼가 클 때 큐가 가득 찰 때까지 계속 늘리는 문제 (bufferbloat)가 있어, 구글이 BBR을 만들었다.