iBetter Books
수정

혼잡이란 무엇인가

서울 출퇴근 시간, 고속도로에 차가 몰립니다. 각 차는 최대한 빨리 가려 하지만 결국 모두 느려집니다. 더 많은 차가 좁은 도로에 진입할수록 흐름이 나빠집니다. 어느 순간부터는 차가 한 대 더 진입할 때마다 전체 속도가 오히려 줄어듭니다. 인터넷의 혼잡도 이와 다르지 않습니다.

라우터의 버퍼가 넘칠 때

패킷이 라우터를 통과할 때 라우터 안에 짧게 대기합니다. 링크 용량보다 빠르게 패킷이 밀려들면 대기 줄이 길어집니다. 결국 버퍼가 꽉 차면 라우터는 새로 들어오는 패킷을 버리기 시작합니다.

패킷이 사라지면 TCP 송신 측은 재전송을 합니다. 재전송 패킷은 네트워크에 패킷을 더 추가합니다. 이미 혼잡한 도로에 차를 더 집어넣는 것입니다. 악순환입니다. 혼잡 제어가 없다면 네트워크는 이 악순환 속에서 완전히 멈추거나(혼잡 붕괴, Congestion Collapse) 모든 참여자의 처리량이 극도로 낮아집니다.

혼잡은 보이지 않는다

흐름 제어와 혼잡 제어가 헷갈릴 수 있습니다. 흐름 제어는 수신자가 "나 더 이상 못 받아"라고 직접 알려주는 것입니다. 수신 측 버퍼를 보호하는 메커니즘입니다.

혼잡 제어는 네트워크 중간에서 일어나는 문제를 다룹니다. 라우터가 "나 지금 힘들어"라고 TCP 송신 측에 직접 알려주지 않습니다. 패킷을 그냥 버릴 뿐입니다. TCP는 패킷 손실을 혼잡의 신호로 간접 추론합니다.

이 간접성이 혼잡 제어를 어렵게 만들고 흥미롭게 만듭니다. 패킷이 사라졌다는 것만 알고, 그게 링크 오류 때문인지 혼잡 때문인지 확실히 알 수 없습니다. 알고리즘이 확률적으로 판단합니다.

혼잡 제어는 신사 협정

중요한 점은 TCP 혼잡 제어가 강제가 아니라는 것입니다. 인터넷의 라우터는 패킷을 버릴 뿐, TCP에게 "속도 줄여"라고 명령하지 못합니다. TCP 스택이 스스로 판단해서 줄여야 합니다.

만약 모든 참여자가 이 신사 협정을 지키면 네트워크는 적절히 공유됩니다. 그러나 혼잡 제어를 무시하고 마구 보내는 참여자가 있으면 다른 참여자들이 피해를 봅니다. 이것이 UDP 기반 애플리케이션을 설계할 때 혼잡 제어를 직접 구현해야 하는 이유이기도 합니다.

다음 절에서는 TCP가 이 혼잡 문제를 구체적으로 어떻게 다루는지 알고리즘 이야기로 들어갑니다.