이번 포스팅에서는 혼잡 제어(Congestion Control)에 대해 알아보겠습니다.
TCP는 네트워크 상황에 따라 패킷을 보내는 속도를 조절해야만 합니다. 만약 네트워크가 복잡해지며, 한 라우터 버퍼에 데이터가 몰릴 경우에 송신자들은 다시 재전송을 하게 되고, 이것은 혼잡을 가중시켜 결국 오버플로우나 데이터 손실을 발생시키게 됩니다.
이렇게 네트워크가 막힌다면 네트워크에 접속한 모두가 패킷을 전송할 수 없으므로, 이를 파악하고 방지하기 위해 데이터 전송을 제어하는 것을 혼잡 제어(Congestion Control)라고 합니다.
네트워크 상황을 어떻게 확인할 것인가
네트워크 상황을 유추하기 위해서는 네트워크에서 직접 데이터를 보내줄 수는 있지만, 그렇게 하기 위해서는 라우터가 처리를 해주어야하는데, 라우터는 이미 많은 일을 하기 때문에 부담이 큽니다. 그래서 네트워크로부터 직접적인 피드백 대신, 상대 리시버로부터의 피드백을 통해 네트워크 상황을 유추할 수 있습니다.
유추하는 방법은, ACK 피드백이 돌아오는 데에 걸리는 시간인 RTT(Round trip time)를 파악하는 것입니다. RTT가 예상보다 짧다면 네트워크 상황이 좋은 것이고, RTT가 길거나 유실이 일어났다면 네트워크 상황이 좋지 않은 것이라 볼 수 있습니다. 이렇게 네트워크 상황을 확인해 Send 버퍼에서 Window Size를 조절하여 속도를 정할 수 있습니다.
이처럼 TCP는네트워크로부터 직접적인 피드백을 받는 것이 아니라, 네트워크의 상황을 유추해서 전송할 패킷의 양을 조절합니다.
TCP Congestion Control
쉬운 이해를 위해 먼저, 수로로 물을 흘려보낸다고 생각해보겠습니다.
이상적인 상황은 보내는 물을 전부 Receiver가 받는 것입니다. 하지만 현실은, 물을 너무 많이 보내면 파이프가 터지는 문제가 발생합니다.
그리고 파이프가 수용가능한 용량을 알 수 없다는 문제가 있습니다. 게다가 파이프의 용량은 물이 이동하는 경로에 따라 다 달라서 더욱 알기 어렵습니다. 그래서 송신자가 보낸 물이 모두 가지 못하고 혼잡이 생기는 문제가 발생합니다.
이런 문제를 방지하기 위해 물을 조금씩 흘려 보내며 정보를 주고 받을 수 있습니다. 그러다가 가장 얇은 파이프가 터지는 문제가 발생하면, 그것을 해결하기 위해 내가 보내는 물을 받는 쪽과 계속 정보를 교신하며 내부를 유추해나가야합니다.
여기서 파이프가 네트워크 상황, 보내는 물이 보내는 패킷, 이를 조절하는 방식이 TCP의 혼잡 제어라고 할 수 있습니다.
TCP 혼잡 제어 과정은 Slow Start, Congestion avoidance, Fast Recovery 의 세 번의 Phases로 구성됩니다. 각각의 단계에 대해 살펴보겠습니다.
(1) Slow Start
처음부터 물을 쏟아부으면 파이프가 터져버릴 수 있습니다. 그래서 TCP는 조심스럽게 패킷을 보내기 시작합니다. 이것이 Slow Start 단계입니다.
TCP 연결이 시작되면, cwnd (congestion window)의 값은 1MSS로 초기화 됩니다. 여기서 MSS는 Maximum Segment Size의 약자입니다.
다만, 적은 양을 계속해서 보낸다면 통신을 마치는 데에 너무 많은 시간이 소요될 수 있습니다. 따라서 Slow Start 는 비축 포인트를 증가시켜 2배씩 그 양을 늘려나갑니다. 시작하는 용량이 매우 작아 Slow Start 라는 이름이 붙었지만, 용량을 올려나가는 정도는 매우 기하급수적으로 빠릅니다. 이 과정이 반복되면서 cwnd의 크기는 2^n씩 증가하게 됩니다. (1 -> 2 -> 4 -> 8 -> 16 .. )
정리하자면 Slow Start 방식은 패킷을 하나씩 보내면서 시작하고, 패킷이 문제없이 도착하면 각각의 ACK 패킷마다 window size를 1씩 늘려줍니다. 즉, 한 주기가 지나면 window size가 2배로 증가합니다.
(2) Additive increase ( Congestion avoidance )
네트워크에는 임계점(threshold)가 존재해서 그 이상의 데이터를 전송할 때에는 주의해야합니다.
Slow Start 방식으로 데이터 양을 늘려나가다 보면 Threshold 지점에 도달하게 됩니다. 그러면 Additive increase 단계로 전환되어 Linear하게 증가합니다. (16 -> 17 -> 18 -> 19...)
(3) Multiplicative decrease ( Congestion avoidance )
병목 현상이 발생하면 전송량을 반으로 줄이는 것입니다.
계속해서 Window Size를 Linear하게 증가시켜나가다보면, 패킷 유실이 생기게 됩니다. 그러면, Threshold를 절반 이하로 줄이고 Window Size도 절반 이하로 줄이게 됩니다.
전송량을 대폭 줄여 네트워크 정체를 해결하는 것입니다. 한 번에 전송량을 확 줄이는 이유는, 네트워크가 공유자원이므로 패킷 하나 두 개를 줄이는 것으로는 혼잡 상태를 해소하기 어렵기 때문입니다.
Threshold와 윈도우 사이즈를 줄인 다음에는, 다시 2번 Additive increase 단계로 돌아가서 linear하게 전송량을 증가시킵니다.
그래서 TCP에서의 데이터 전송량을 그래프로 나타내면 위처럼 톱날 모양으로 변화하는 것을 볼 수 있습니다.
정리하자면, TCP의 혼잡 제어는 처음엔 아주 느린 속도로 보내되 굉장히 빠르게 Window Size를 증가시키다가(Slow Start), 어느 지점에 도달하면 증가 속도를 Linear 하게 증가 시키고(Additive increase), 패킷 유실이 발생하면 Window Size를 줄인 후 다시 Linear하게 전송하는 것입니다.
+ 패킷 유실의 두 가지 상황
TCP가 패킷 유실은 두 가지 상황이 있을 수 있습니다.
Time Out
만약 timeout에 의한 패킷 손실 이벤트가 발생한 경우는 네트워크 정체가 심한 상황으로 볼 수 있습니다.
그래서 cwnd의 값을 다시 1로 줄이고 Slow Start를 다시 처음부터 시작하게 됩니다. 이때 다시 시작하는 Slow Start의 Threshold 값은 timeout이 발생했을때의 cwnd/2로 정해집니다.
Duplicate ACK
반면 ACK가 중복으로 도착한 경우는 다른 패킷들은 잘 도착했으나 특정 한 패킷에서 문제가 발생한 상황을 의미합니다. 그래서 3 Duplicate ACK (3개의 중복 ACK 검출)이 검출되면 Slow Start를 종료하고, Fast Recovery 단계로 진입합니다.
(4) Fast Retransmit
3 Duplicated ACK를 통해 패킷 유실이 감지되면 타임아웃이 되기 전에도 패킷을 재전송하는 것입니다.
(5) Fast Recovery
3 Duplicate ACK 가 감지되었때 윈도우 크기를 줄이는 것입니다.
Fast Recovery 은 크게 2가지가 존재합니다.
1. TCP Tahoe
초기버전으로 timeout이 되거나 3개의 중복 ACK에 의한 손실이 발생한다면, 무조건 cwnd를 1MSS로 줄이고, Slow Start단계로 들어갑니다.
2. TCP Reno
Tahoe 이후에 등장했으며, 3개의 중복 ACK에 의한 손실이 발생하면, cwnd의 크기를 1MSS로 줄이는게 아니라, 현재 cwnd 크기의 절반으로 줄인 다음 1MSS 씩 증가를 시킵니다. 만약 timeout이라면, cwnd를 1MSS로 초기화하고 Slow Start를 진행합니다.
참고자료
[컴퓨터 네트워크 - 한양대학교 이석복 교수님]
http://www.kocw.net/home/cview.do?cid=6166c077e545b736
https://the-square-of-y.tistory.com/216
https://blog.naver.com/ds4ouj/222302723767
https://dev-nicitis.tistory.com/31
Computer Networking _ A Top Down Approach, 7th
'CS > Network' 카테고리의 다른 글
[네트워크] NAT(Network Address Translation) (0) | 2024.02.20 |
---|---|
[네트워크] 네트워크 계층 : Internet Protocol(IP) (0) | 2024.02.19 |
[네트워크] TCP의 Flow control, 3 / 4 - Way Handshake (0) | 2024.02.16 |
[네트워크] 전송 계층 : TCP (0) | 2024.02.15 |
[네트워크] Pipelined Protocol (0) | 2024.02.12 |