네트워크 통신과정 도중에는 네트워크 혼잡성 및 receiver의 overload 등의 사유로 데이터가 손실되거나, 전달 순서가 바뀌는 등의 문제가 발생할 수 있습니다. 이런 문제를 해결하고 통신의 신뢰성을 보장하기 위해 TCP/IP에서 사용하는 것이 흐름 제어와 혼잡 제어입니다.
- cf. TCP 버퍼 : 전송 및 수신 전 TCP 세그먼트는 보관하는 곳입니다. 송신 측은 버퍼에 TCP 세그먼트를 보관한 후 순차적으로 전송하고, 수신 측은 도착한 TCP 세그먼트를 애플리케이션이 읽을 때까지 버퍼에 보관합니다. 이 크기에 너무 작으면 당연히 손실되는 데이터가 많아지겠죠?
흐름 제어
수신 측이 송신 측보다 데이터 처리 속도가 느릴 경우 데이터를 손실할 위험이 존재합니다. 흐름 제어는 이런 송신 측과 수신 측의 데이터 처리 속도 차이로 인해 발생하는 문제를 해결하기 위한 기법입니다.
이를 실현하기 위한 방법으로는 Stop and Wait, Sliding Windoew가 있습니다.
- Stop and Wait : 매번 전송한 패킷에 대해 응답(ACK)을 받으면 다음 패킷을 전송하는 기법입니다. 이는 패킷을 하나씩 보내고 확인해야 하기 때문에 비효율적입니다.
- Sliding Window : 수신 측에서 설정한 '윈도우'의 크기만큼 송신 측에서 패킷을 전송하도록 하여 데이터의 흐름을 동적으로 조절하는 기법입니다. 최초 윈도의 크기는 3way-handshaking 과정을 통해 설정되며, 이후 수신측에서 버퍼의 공간에 따라 변경합니다. ('윈도우'값은 TCP header에 존재하고 관리됩니다.) 윈도우에 포함된만큼은 수신 측의 응답(ACK)없이도 보낼 수 있지만, 그 이상은 보낼 수 없습니다. 그 이상의 데이터 패킷을 보내기 위해서는 수신의 응답(ACK)가 확인되어 다시 윈도우의 크기가 갱신되어야 합니다.
혼잡 제어
데이터의 양이 라우터가 처리할 수 있는 양을 초과하면 라우터는 더 이상 데이터를 처리할 수 없습니다. 이런 상황에서 송신 측은 라우터에서 처리하지 못한 데이터를 손실 데이터로 간주하고 계속해서 데이터를 전송하게 됩니다. 이는 네트워크를 혼잡하게 만듭니다. 혼잡 제어는 이런 네트워크의 혼잡성 문제를 해결하기 위한 기법입니다.
흐름제어가 송 수신측의 패킷 수를 제어하는 기법이라면, 혼잡제어는 네트워크 내의 패킷 수를 제어하는 기법이라고 할 수 있겠네요.
이를 실현하기 위한 방법으로는 AMD, Slow Start가 있습니다.
- AIMD : Additive Increase & Multicative Decrease의 약자로, 합 증가 & 곱 감소라는 의미입니다. 처음에 패킷을 하나씩만 보내고 문제없이 해당 패킷이 도착하면 윈도의 크기를 증가시켜 전송합니다. 만약 전송 실패가 발생할 경우 윈도우의 크기를 반으로 줄입니다. 윈도우의 크기를 너무 조금씩 늘리기 때문에 네트워크의 대역을 제대로 활용하여 속도를 내기엔 시간이 걸린다는 단점이 있습니다.
- Slow Start : 윈도우의 크기를 지수적으로 증가하다가 혼잡이 감지되면 1로 줄이는 방법입니다. 윈도우의 크기가 처음에는 조금 느리게 증가하지만, 시간이 지날수록 윈도우의 크기가 빠르게 증가한다는 장점이 있습니다.
AIMD, Slow Start를 사용하면서 네트워크의 혼잡이 자주 발생하면 윈도우의 크기가 크게 감소하고 네트워크의 전송률이 매우 떨어집니다. 따라서 TCP에는 패킷을 재전송하는 기법들이 존재합니다. 이들 역시 혼잡제어 기법의 일종입니다.
- Fast Retransmit : 수신 측은 먼저 도착해야하는 패킷이 도착하지 않고 다음 패킷이 도착한 경우에도 응답(ACK)를 보냅니다. 단, 순서대로 도착한 마지막 패킷의 다음 패킷 순번을 응답 패킷에 실어서 보내기 때문에 송신 측은 순번이 중복된 응답 패킷을 받게되고, 이러한 중복 패킷을 3번 감지하면 문제가 되는 순번의 패킷을 재전송해줄 수 있습니다.
- Fast Recovery : 혼잡한 상태가 되면 윈도우의 크기를 1로 줄이지않고 반으로 줄인 다음 선형적으로 증가시키는 기법입니다. 이 기법을 적용하면 혼잡상황을 겪고난 후에는 AIMD와 같은 방식으로 동작합니다.
실질적인 혼잡제어는 이 중 하나만으로 작동한다기보단, 상황에 따라 정책을 바꿔가며 제어합니다. 예를 들면 처음에는 Slow Start를 사용하다가 혼잡 상태가 감지되면 AMID를 사용하는 방식입니다. 이런 정책에는 Tahoe, Reno, New Reno, Cubic, Ealstic-TCP 등 여러가지가 존재합니다.
참고
'💻 CS > 네트워크' 카테고리의 다른 글
[Network] HTTPS의 동작방식 (0) | 2022.02.15 |
---|---|
[Network] HTTP 헤더 : 캐시와 조건부요청 (0) | 2021.07.10 |
[Network] HTTP 일반헤더 (0) | 2021.07.06 |
[Network] HTTP 상태코드 (0) | 2021.06.26 |
[Network] HTTP API 설계 예시 (1) | 2021.06.12 |